De DNS records die aangemaakt dienen te worden in mijn DNS server (Pi-Hole) wil ik automatisch laten doen zodra er een Ingress aangemaakt wordt voor de FQDN van de service. Hiervoor is External DNS die ook A-records kan aanmaken in de Local DNS van Pi-Hole.

Het installeren van External DNS is een kwestie van de kubectl commando’s ingeven, of zorg ervoor dat het automatisch geïnstalleerd met behulp van ArgoCD of Fleet of wat voor CI/CD tool dan ook.
Installatie
Maak eerst een namespace:
kubectl create namespace externaldns
En dan een secret waarin het wachtwoord van de Pi-Hole API staat:
kubectl -n externaldns create secret generic pihole-password --from-literal EXTERNAL_DNS_PIHOLE_PASSWORD=[het wachtwoord]
en dan kan een service-account aangemaakt worden, een clusterrole en clusterrolebinding in de externaldns namespace voor het service-account en uiteindelijk de deployment zelf.
--- apiVersion: v1 kind: ServiceAccount metadata: name: external-dns --- apiVersion: rbac.authorization.k8s.io/v1 kind: ClusterRole metadata: name: external-dns rules: - apiGroups: [""] resources: ["services","endpoints","pods"] 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: externaldns --- 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.13.5 envFrom: - secretRef: name: pihole-password args: - --source=service - --source=ingress - --registry=noop ## omdat pi-hole geen TXT records kan aanmaken - --policy=upsert-only ## om te voorkomen dat andere DNS records verwijderd worden - --provider=pihole - --pihole-server=http://[adres van jouw Pi-Hole server] securityContext: fsGroup: 65534
Kwestie van het manifest apply’en met kubectl en external DNS is geïnstalleerd.
External-DNS naar Pi-Hole local-DNS records kan helaas niet voorzien worden van TXT-records, vandaar de optie ‘noop‘. Hierdoor kan External-DNS niet bepalen welke records in Pi-Hole door External-DNS zijn aangemaakt.
Indien in Pi-Hole ook DNS records worden gebruikt die niet met external-dns zijn aangemaakt, dan is de optie ‘upsert-only‘ van toepassing om te voorkomen dat die records worden verwijderd door External-DNS. Het nadeel is dat records wel aangemaakt met External-DNS in Pi-Hole handmatig verwijderd dienen te worden als de service (of Ingress) in Kubernetes niet meer gebruikt wordt. (omdat er dus geen TXT-record aan hangt)
Services
Om voor services een DNS record aan te laten maken, is het noodzakelijk om in de service een annotation te zetten, bijvoorbeeld:
kubectl annotate service nginx "external-dns.alpha.kubernetes.io/hostname=nginx-speeltuin.digitalinfo.nl."
eventueel voorzien van een TimeToLive waarde:
kubectl annotate service nginx "external-dns.alpha.kubernetes.io/ttl=10"
De DNS records voor een ClusterIP type service is:
kubectl annotate service nginx "external-dns.alpha.kubernetes.io/internal-hostname=nginx-speeltuin.internal.digitalinfo.nl."
Ingress
Voor het aanmaken van een DNS record aan de hand van een Ingress hostname is geen annotation nodig. De DNS records voor een Ingress worden door external-dns aangemaakt zodra de Ingress wordt aangemaakt.