How to Customize CoreDNS for Kubernetes Clusters

DigitalOcean Kubernetes (DOKS) is a managed Kubernetes service that lets you deploy Kubernetes clusters without the complexities of handling the control plane and containerized infrastructure. Clusters are compatible with standard Kubernetes toolchains and integrate natively with DigitalOcean Load Balancers and block storage volumes.

DigitalOcean Kubernetes (DOKS) uses CoreDNS for cluster DNS management. You can view the CoreDNS settings used by DOKS in the CoreDNS’s configuration file using the following command:

kubectl get configmap -n kube-system coredns -o yaml

The output looks similar to the following:

    
        
apiVersion: v1
data:
  Corefile: |
    .:53 {
        errors
        health
        ready
        kubernetes cluster.local in-addr.arpa ip6.arpa {
          pods insecure
          fallthrough in-addr.arpa ip6.arpa
        }
        prometheus :9153
        forward . /etc/resolv.conf
        cache 30
        loop
        reload
        loadbalance
        import custom/*.override
    }
    import custom/*.server
kind: ConfigMap
[...]

    

The default CoreDNS configuration is in the Corefile key of the ConfigMap and includes plugins such as errors, health, ready, reload, and loadbalance.

The import plugin lets you include customizations, such as specifying a forwarding server for your network traffic, enabling logging for debugging DNS queries, or configuring your environment’s custom domains, stub domains, or upstream nameservers.

The DigitalOcean Kubernetes backend can overwrite any changes you make to the CoreDNS ConfigMap. Instead of modifying the CoreDNS ConfigMap, we recommend using a Kubernetes ConfigMap to customize the CoreDNS settings of a cluster:

  1. Create a custom ConfigMap that has keys named with .override and .server extensions and save it as coredns-custom.yaml.

    • .override lets you change the default Server Block of CoreDNS.
    • .server lets you specify additional server blocks for CoreDNS.

    You can specify a name of your choice for the .server or .override extensions.

    For example, the following custom ConfigMap:

    • Adds the log plugin. Specifying log in the .override option to start logging at the system level. Using the plugin in the .server option starts logging for a specific domain.
    • Overrides the forward plugin to forward requests to the specified nameserver. You can redirect requests to a specific DNS server that can resolve the rewritten domain name.
    
        
apiVersion: v1
kind: ConfigMap
metadata:
  name: coredns-custom
  namespace: kube-system
data:
  log.override: |
    log
  custom.server: |
    example.io:8053 {
      forward . 8.8.8.8
    }

    
  1. Apply the custom configuration to the kube-system namespace:
kubectl apply -f coredns-custom.yaml
  1. Check the logs to make sure that the customization have been applied:
kubectl logs -n kube-system -l k8s-app=kube-dns

For the ConfigMap shown previously, the output looks similar to the following after the changes reconcile:

[INFO] Reloading
[INFO] plugin/reload: Running configuration MD5 = 2abff3bcc90cc5e9925581a55c02a47c
[INFO] Reloading complete
[INFO] 127.0.0.1:56186 - 38484 "HINFO IN 300556296135298597.3851195213192789444. udp 56 false 512" NXDOMAIN qr,rd,ra,ad 131 0.003940763s
[INFO] 10.244.1.134:40618 - 34833 "A IN mirror.vacares.com.svc.cluster.local. udp 54 false
[INFO] 10.244.1.134:52328 - 3722 "AAAA IN mirror.atlanticmetro.net.cluster.local. udp 56 false 512" NXDOMAIN qr,aa,rd 149 0.000093086s
[INFO] 10.244.1.134:40521 - 28128 "A IN example.io. udp 51 false 4096" NOERROR qr,rd,ra 115 0.000944973s

Because the example ConfigMap uses the log plugin, the log output here shows DNS queries, including a query to example.io that occurred on the cluster’s pod.