mirror of
https://github.com/kubernetes-sigs/external-dns.git
synced 2025-08-05 17:16:59 +02:00
* chore(release): updates kustomize & docs with v0.18.0 Signed-off-by: Michel Loiseleur <michel.loiseleur@traefik.io> * add endpointslices rbac * fix version updater script --------- Signed-off-by: Michel Loiseleur <michel.loiseleur@traefik.io>
201 lines
5.7 KiB
Markdown
201 lines
5.7 KiB
Markdown
# Pi-hole
|
|
|
|
This tutorial describes how to setup ExternalDNS to sync records with Pi-hole's Custom DNS.
|
|
Pi-hole has an internal list it checks last when resolving requests. This list can contain any number of arbitrary A, AAAA or CNAME records.
|
|
There is a pseudo-API exposed that ExternalDNS is able to use to manage these records.
|
|
|
|
__NOTE:__ Your Pi-hole must be running [version 5.9 or newer](https://pi-hole.net/blog/2022/02/12/pi-hole-ftl-v5-14-web-v5-11-and-core-v5-9-released).
|
|
|
|
__NOTE:__ Provider for Pi-hole version prior to 6.0 is now deprecated and will be removed in future release.
|
|
|
|
__NOTE:__ Since Pi-hole version 6, you should use the flag *--pihole-api-version=6*
|
|
|
|
## Deploy ExternalDNS
|
|
|
|
You can skip to the [manifest](#externaldns-manifest) if authentication is disabled on your Pi-hole instance or you don't want to use secrets.
|
|
|
|
If your Pi-hole server's admin dashboard is protected by a password, you'll likely want to create a secret first containing its value.
|
|
This is optional since you *do* retain the option to pass it as a flag with `--pihole-password`.
|
|
|
|
You can create the secret with:
|
|
|
|
```bash
|
|
kubectl create secret generic pihole-password \
|
|
--from-literal EXTERNAL_DNS_PIHOLE_PASSWORD=supersecret
|
|
```
|
|
|
|
Replacing __"supersecret"__ with the actual password to your Pi-hole server.
|
|
|
|
### ExternalDNS Manifest
|
|
|
|
Apply the following manifest to deploy ExternalDNS, editing values for your environment accordingly.
|
|
Be sure to change the namespace in the `ClusterRoleBinding` if you are using a namespace other than __default__.
|
|
|
|
```yaml
|
|
---
|
|
apiVersion: v1
|
|
kind: ServiceAccount
|
|
metadata:
|
|
name: external-dns
|
|
---
|
|
apiVersion: rbac.authorization.k8s.io/v1
|
|
kind: ClusterRole
|
|
metadata:
|
|
name: external-dns
|
|
rules:
|
|
- apiGroups: [""]
|
|
resources: ["services","pods"]
|
|
verbs: ["get","watch","list"]
|
|
- apiGroups: ["discovery.k8s.io"]
|
|
resources: ["endpointslices"]
|
|
verbs: ["get","watch","list"]
|
|
- apiGroups: ["extensions","networking.k8s.io"]
|
|
resources: ["ingresses"]
|
|
verbs: ["get","watch","list"]
|
|
- apiGroups: [""]
|
|
resources: ["nodes"]
|
|
verbs: ["list","watch"]
|
|
---
|
|
apiVersion: rbac.authorization.k8s.io/v1
|
|
kind: ClusterRoleBinding
|
|
metadata:
|
|
name: external-dns-viewer
|
|
roleRef:
|
|
apiGroup: rbac.authorization.k8s.io
|
|
kind: ClusterRole
|
|
name: external-dns
|
|
subjects:
|
|
- kind: ServiceAccount
|
|
name: external-dns
|
|
namespace: default
|
|
---
|
|
apiVersion: apps/v1
|
|
kind: Deployment
|
|
metadata:
|
|
name: external-dns
|
|
spec:
|
|
strategy:
|
|
type: Recreate
|
|
selector:
|
|
matchLabels:
|
|
app: external-dns
|
|
template:
|
|
metadata:
|
|
labels:
|
|
app: external-dns
|
|
spec:
|
|
serviceAccountName: external-dns
|
|
containers:
|
|
- name: external-dns
|
|
image: registry.k8s.io/external-dns/external-dns:v0.18.0
|
|
# If authentication is disabled and/or you didn't create
|
|
# a secret, you can remove this block.
|
|
envFrom:
|
|
- secretRef:
|
|
# Change this if you gave the secret a different name
|
|
name: pihole-password
|
|
args:
|
|
- --source=service
|
|
- --source=ingress
|
|
# Pihole only supports A/AAAA/CNAME records so there is no mechanism to track ownership.
|
|
# You don't need to set this flag, but if you leave it unset, you will receive warning
|
|
# logs when ExternalDNS attempts to create TXT records.
|
|
- --registry=noop
|
|
# IMPORTANT: If you have records that you manage manually in Pi-hole, set
|
|
# the policy to upsert-only so they do not get deleted.
|
|
- --policy=upsert-only
|
|
- --provider=pihole
|
|
# Switch to pihole V6 API
|
|
- --pihole-api-version=6
|
|
# Change this to the actual address of your Pi-hole web server
|
|
- --pihole-server=http://pihole-web.pihole.svc.cluster.local
|
|
securityContext:
|
|
fsGroup: 65534 # For ExternalDNS to be able to read Kubernetes token files
|
|
```
|
|
|
|
### Arguments
|
|
|
|
- `--pihole-server (env: EXTERNAL_DNS_PIHOLE_SERVER)` - The address of the Pi-hole web server
|
|
- `--pihole-password (env: EXTERNAL_DNS_PIHOLE_PASSWORD)` - The password to the Pi-hole web server (if enabled)
|
|
- `--pihole-tls-skip-verify (env: EXTERNAL_DNS_PIHOLE_TLS_SKIP_VERIFY)` - Skip verification of any TLS certificates served by the Pi-hole web server.
|
|
- `--pihole-api-version (env: EXTERNAL_DNS_PIHOLE_API_VERSION)` - Specify the pihole API version (default is 5. Eligible values are 5 or 6).
|
|
|
|
## Verify ExternalDNS Works
|
|
|
|
### Ingress Example
|
|
|
|
Create an Ingress resource. ExternalDNS will use the hostname specified in the Ingress object.
|
|
|
|
```yaml
|
|
apiVersion: networking.k8s.io/v1
|
|
kind: Ingress
|
|
metadata:
|
|
name: foo
|
|
spec:
|
|
ingressClassName: nginx
|
|
rules:
|
|
- host: foo.bar.com
|
|
http:
|
|
paths:
|
|
- path: /
|
|
pathType: Prefix
|
|
backend:
|
|
service:
|
|
name: foo
|
|
port:
|
|
number: 80
|
|
```
|
|
|
|
### Service Example
|
|
|
|
The below sample application can be used to verify Services work.
|
|
For services ExternalDNS will look for the annotation `external-dns.alpha.kubernetes.io/hostname` on the service and use the corresponding value.
|
|
|
|
```yaml
|
|
---
|
|
apiVersion: v1
|
|
kind: Service
|
|
metadata:
|
|
name: nginx
|
|
annotations:
|
|
external-dns.alpha.kubernetes.io/hostname: nginx.external-dns-test.homelab.com
|
|
spec:
|
|
type: LoadBalancer
|
|
ports:
|
|
- port: 80
|
|
name: http
|
|
targetPort: 80
|
|
selector:
|
|
app: nginx
|
|
---
|
|
apiVersion: apps/v1
|
|
kind: Deployment
|
|
metadata:
|
|
name: nginx
|
|
spec:
|
|
selector:
|
|
matchLabels:
|
|
app: nginx
|
|
template:
|
|
metadata:
|
|
labels:
|
|
app: nginx
|
|
spec:
|
|
containers:
|
|
- image: nginx
|
|
name: nginx
|
|
ports:
|
|
- containerPort: 80
|
|
name: http
|
|
```
|
|
|
|
You can then query your Pi-hole to see if the record was created.
|
|
|
|
Change *@192.168.100.2* to the actual address of your DNS server
|
|
|
|
```bash
|
|
$ dig +short @192.168.100.2 nginx.external-dns-test.homelab.com
|
|
|
|
192.168.100.129
|
|
```
|