sigs.k8s.io/external-dns@v0.14.1/docs/tutorials/pihole.md (about)

     1  # Setting up ExternalDNS for Pi-hole
     2  
     3  This tutorial describes how to setup ExternalDNS to sync records with Pi-hole's Custom DNS.
     4  Pi-hole has an internal list it checks last when resolving requests. This list can contain any number of arbitrary A or CNAME records.
     5  There is a pseudo-API exposed that ExternalDNS is able to use to manage these records.
     6  
     7  __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).
     8  
     9  
    10  ## Deploy ExternalDNS
    11  
    12  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.
    13  
    14  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. 
    15  This is optional since you _do_ retain the option to pass it as a flag with `--pihole-password`.
    16  
    17  You can create the secret with:
    18  
    19  ```bash
    20  kubectl create secret generic pihole-password \
    21      --from-literal EXTERNAL_DNS_PIHOLE_PASSWORD=supersecret
    22  ```
    23  
    24  Replacing **"supersecret"** with the actual password to your Pi-hole server.
    25  
    26  ### ExternalDNS Manifest
    27  
    28  Apply the following manifest to deploy ExternalDNS, editing values for your environment accordingly. 
    29  Be sure to change the namespace in the `ClusterRoleBinding` if you are using a namespace other than **default**.
    30  
    31  ```yaml
    32  ---
    33  apiVersion: v1
    34  kind: ServiceAccount
    35  metadata:
    36    name: external-dns
    37  ---
    38  apiVersion: rbac.authorization.k8s.io/v1
    39  kind: ClusterRole
    40  metadata:
    41    name: external-dns
    42  rules:
    43  - apiGroups: [""]
    44    resources: ["services","endpoints","pods"]
    45    verbs: ["get","watch","list"]
    46  - apiGroups: ["extensions","networking.k8s.io"]
    47    resources: ["ingresses"]
    48    verbs: ["get","watch","list"]
    49  - apiGroups: [""]
    50    resources: ["nodes"]
    51    verbs: ["list","watch"]
    52  ---
    53  apiVersion: rbac.authorization.k8s.io/v1
    54  kind: ClusterRoleBinding
    55  metadata:
    56    name: external-dns-viewer
    57  roleRef:
    58    apiGroup: rbac.authorization.k8s.io
    59    kind: ClusterRole
    60    name: external-dns
    61  subjects:
    62  - kind: ServiceAccount
    63    name: external-dns
    64    namespace: default
    65  ---
    66  apiVersion: apps/v1
    67  kind: Deployment
    68  metadata:
    69    name: external-dns
    70  spec:
    71    strategy:
    72      type: Recreate
    73    selector:
    74      matchLabels:
    75        app: external-dns
    76    template:
    77      metadata:
    78        labels:
    79          app: external-dns
    80      spec:
    81        serviceAccountName: external-dns
    82        containers:
    83        - name: external-dns
    84          image: registry.k8s.io/external-dns/external-dns:v0.14.0
    85          # If authentication is disabled and/or you didn't create
    86          # a secret, you can remove this block.
    87          envFrom:
    88          - secretRef:
    89              # Change this if you gave the secret a different name
    90              name: pihole-password
    91          args:
    92          - --source=service
    93          - --source=ingress
    94          # Pihole only supports A/CNAME records so there is no mechanism to track ownership.
    95          # You don't need to set this flag, but if you leave it unset, you will receive warning
    96          # logs when ExternalDNS attempts to create TXT records.
    97          - --registry=noop
    98          # IMPORTANT: If you have records that you manage manually in Pi-hole, set
    99          # the policy to upsert-only so they do not get deleted.
   100          - --policy=upsert-only
   101          - --provider=pihole
   102          # Change this to the actual address of your Pi-hole web server
   103          - --pihole-server=http://pihole-web.pihole.svc.cluster.local
   104        securityContext:
   105          fsGroup: 65534 # For ExternalDNS to be able to read Kubernetes token files
   106  ```
   107  
   108  ### Arguments
   109  
   110   - `--pihole-server (env: EXTERNAL_DNS_PIHOLE_SERVER)` - The address of the Pi-hole web server
   111   - `--pihole-password (env: EXTERNAL_DNS_PIHOLE_PASSWORD)` - The password to the Pi-hole web server (if enabled)
   112   - `--pihole-tls-skip-verify (env: EXTERNAL_DNS_PIHOLE_TLS_SKIP_VERIFY)` - Skip verification of any TLS certificates served by the Pi-hole web server.
   113  
   114  ## Verify ExternalDNS Works
   115  
   116  ### Ingress Example
   117  
   118  Create an Ingress resource. ExternalDNS will use the hostname specified in the Ingress object.
   119  
   120  ```yaml
   121  apiVersion: networking.k8s.io/v1
   122  kind: Ingress
   123  metadata:
   124    name: foo
   125  spec:
   126    ingressClassName: nginx
   127    rules:
   128    - host: foo.bar.com
   129      http:
   130        paths:
   131        - path: /
   132          pathType: Prefix
   133          backend:
   134            service:
   135              name: foo
   136              port:
   137                number: 80
   138  ```
   139  
   140  ### Service Example
   141  
   142  The below sample application can be used to verify Services work.
   143  For services ExternalDNS will look for the annotation `external-dns.alpha.kubernetes.io/hostname` on the service and use the corresponding value.
   144  
   145  ```yaml
   146  ---
   147  apiVersion: v1
   148  kind: Service
   149  metadata:
   150    name: nginx
   151    annotations:
   152      external-dns.alpha.kubernetes.io/hostname: nginx.external-dns-test.homelab.com
   153  spec:
   154    type: LoadBalancer
   155    ports:
   156    - port: 80
   157      name: http
   158      targetPort: 80
   159    selector:
   160      app: nginx
   161  ---
   162  apiVersion: apps/v1
   163  kind: Deployment
   164  metadata:
   165    name: nginx
   166  spec:
   167    selector:
   168      matchLabels:
   169        app: nginx
   170    template:
   171      metadata:
   172        labels:
   173          app: nginx
   174      spec:
   175        containers:
   176        - image: nginx
   177          name: nginx
   178          ports:
   179          - containerPort: 80
   180            name: http
   181  ```
   182  
   183  You can then query your Pi-hole to see if the record was created.
   184  
   185  _Change `@192.168.100.2` to the actual address of your DNS server_
   186  
   187  ```bash
   188  $ dig +short @192.168.100.2  nginx.external-dns-test.homelab.com
   189  
   190  192.168.100.129
   191  ```