Skip to content

external-dns setup

Install the required packages

apt install bind9 bind9utils bind9-doc dnsutils

Configuration files are in /etc/bind and /var/cache/bind. Following are the config files in /etc/bind

  • named.conf.local
  • named.conf.options

named.conf.options adds configuration to the bind daemon. The configuration allows us to query from the local network, allow recursive lookup. Internal network acl is setup to allow access from 192.168.2.0/24 and 172.16.21.0/24 subnets. logging has been setup for DNS query logs. /var/log/named is the preferred logging location for DNS related logs. The TSIG key externaldns-key has been added to allow external-dns to update the DNS entries. The TSIG has been generated with the command tsig-keygen -a hmac-sha256 externaldns-key

key "externaldns-key" {
    algorithm hmac-sha256;
    secret "96Ah/a2g0/nLeFGK+d/0tzQcccf9hCEIy34PoXX2Qg8=";
};
acl internal-network {
  192.168.2.0/24;
  172.16.21.0/24;

};
options {
    directory "/var/cache/bind";
    allow-query {localhost; internal-network; };
    // allow-transfer {localhost; };
    recursion yes;
    forwarders {
      8.8.8.8;
    };
    dnssec-validation no;
    querylog yes;
    listen-on-v6 { none; };
};
logging{
  channel queries_log {
    file "/var/log/named/querylog" versions 600 size 20m;
    print-time yes;
    print-category yes;
    print-severity yes;
    severity info;
    };
  category queries { queries_log; };
};
key "externaldns-key" {
    algorithm hmac-sha256;
    secret "Zi7VGquB/1XL52ZGt5YAfe46uQpvqPO8riiEFrNBZwo=";
};

named.conf.local is the config file used to create a local zone. Configuration allows us to update DNS entries from the external-dns pod

zone "logpoint.com.np" {
  type master;
  file "db.logpoint.com.np";
  allow-transfer {
    key "externaldns-key";
  };
  update-policy {
    grant externaldns-key zonesub ANY; 
 };
};

Zone file on /var/cache/bind

The zone file db.logpoint.com.np is created on the location /var/cache/bind location

;
; BIND data file for logpoint.com.np
;
$TTL    604800
@   IN  SOA logpoint.com.np. root.logpoint.com.np. (
                  2     ; Serial
             604800     ; Refresh
              86400     ; Retry
            2419200     ; Expire
             604800 )   ; Negative Cache TTL
;
@   IN  NS  logpoint.com.np.
@   IN  A   127.0.0.1
@   IN  AAAA    ::1

external-dns installation

external-dns synchronizes exposed Kubernetes Services and Ingresses with DNS providers.Inspired by Kubernetes DNS, Kubernetes' cluster-internal DNS server, external-dns makes Kubernetes resources discoverable via public DNS servers. Like KubeDNS, it retrieves a list of resources (Services, Ingresses, etc.) from the Kubernetes API to determine a desired list of DNS records. Unlike KubeDNS, however, it's not a DNS server itself, but merely configures other DNS providers accordingly—e.g. AWS Route 53 or Google Cloud DNS.

In order to use external-dns with your cluster you need to add a deployment with access to your ingress and service resources. The following is example manifests with RBAC respectively.

apiVersion: v1
kind: Namespace
metadata:
  name: external-dns
  labels:
    name: external-dns
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
  name: external-dns
  namespace: external-dns
rules:
- apiGroups:
  - ""
  resources:
  - services
  - endpoints
  - pods
  - nodes
  verbs:
  - get
  - watch
  - list
- apiGroups:
  - extensions
  - networking.k8s.io
  resources:
  - ingresses
  verbs:
  - get
  - list
  - watch
---
apiVersion: v1
kind: ServiceAccount
metadata:
  name: external-dns
  namespace: external-dns
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
  name: external-dns-viewer
  namespace: external-dns
roleRef:
  apiGroup: rbac.authorization.k8s.io
  kind: ClusterRole
  name: external-dns
subjects:
- kind: ServiceAccount
  name: external-dns
  namespace: external-dns
---
apiVersion: apps/v1
kind: Deployment
metadata:
  name: external-dns
  namespace: external-dns
spec:
  selector:
    matchLabels:
      app: external-dns
  template:
    metadata:
      labels:
        app: external-dns
    spec:
      serviceAccountName: external-dns
      containers:
      - name: external-dns
        image: k8s.gcr.io/external-dns/external-dns:v0.7.6
        args:
        - --registry=txt
        - --txt-prefix=external-dns-
        - --txt-owner-id=k8s
        - --provider=rfc2136
        - --rfc2136-host=192.168.0.1 
        - --rfc2136-port=53
        - --rfc2136-zone=k8s.example.org
        - --rfc2136-tsig-secret=96Ah/a2g0/nLeFGK+d/0tzQcccf9hCEIy34PoXX2Qg8=
        - --rfc2136-tsig-secret-alg=hmac-sha256
        - --rfc2136-tsig-keyname=externaldns-key
        - --rfc2136-tsig-axfr
        - --source=ingress
        - --domain-filter=k8s.example.org

Using external-dns

To use external-dns add an ingress or a LoadBalancer service with a host that is part of the domain-filter. For example both of the following would produce A records.

apiVersion: v1
kind: Service
metadata:
  name: nginx
  annotations:
    external-dns.alpha.kubernetes.io/hostname: nginx.external-dns-test.my-org.com
    external-dns.alpha.kubernetes.io/ttl: 60
spec:
    ...

external-dns.alpha.kubernetes.io/hostname updates the hostname to the DNS Server. external-dns.alpha.kubernetes.io/ttl modifies the ttl value to add into the DNS server.

Creating a forwarder on core DNS

It might be necessary to access the DNS records from pods in the kubernetes cluster. CoreDNS can forward requests related to a particular domain to a specific DNS Server which can be configured

apiVersion: v1
data:
  Corefile: |
    .:53 {
        errors
        health {
           lameduck 5s
        }
        ready
        kubernetes cluster.local in-addr.arpa ip6.arpa {
           pods insecure
           fallthrough in-addr.arpa ip6.arpa
           ttl 30
        }
        prometheus :9153
        forward . /etc/resolv.conf {
           max_concurrent 1000
        }
        cache 30
        loop
        reload
        loadbalance
    }
    logpoint.com.np:53 {
      errors
      cache 30
      forward . 192.168.2.223
      reload
    }
kind: ConfigMap
metadata:
  creationTimestamp: "2020-09-09T09:40:38Z"
  name: coredns
  namespace: kube-system
  resourceVersion: "1089226813"
  uid: d889be4e-4c36-47a2-ab50-9a1f87c1f6cb

The stanza logpoint.com.np forwards all requests realted to logpoint.com.np to 192.168.2.223. It can be added to the coredns configmap in kube-system namespace via the kubectl edit cm coredns command.