If you have a domain that you want CoreDNS to forward to a specific upstream DNS, you can add a block to the CoreDNS configmap.
Adding this domain block to the CoreDNS configmap and restarting the CoreDNS pods is sufficient will make the change take affect. You may need to restart client pods if DNS caching is happening at the pod level.
Edit CoreDNS ConfigMap
By default, the CoreDNS deployment is configured by the ‘coredns’ ConfigMap. Open it for editing
kubectl edit cm -n kube-system coredns
Assuming we want to have all DNS queries that end with “my.local” to be forwarded to the upstream DNS server at 192.168.1.1, we need to add the following 4 lines to the ConfigMap.
my.local:53 { log forward . 192.168.1.1:53 }
Which looks like below in the overall context of the ConfigMap.
apiVersion: v1 data: Corefile: | my.local:53 { log forward . 192.168.1.1:53 } .:53 { log 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 } kind: ConfigMap metadata: name: coredns namespace: kube-system
Restart CoreDNS pods
The CoreDNS pod(s) need to be restarted.
# enable CoreDNS logging if not found kubectl get cm -n kube-system coredns -o=json | grep -q log || kubectl get cm -n kube-system coredns -o=json | jq 'del(.metadata.resourceVersion,.metadata.uid,.metadata.selfLink,.metadata.creationTimestamp,.metadata.annotations,.metadata.generation,.metadata.ownerReferences,.status)' | sed 's#\.:53 {#\.:53 {\\n log#' | kubectl replace -f - # restart all CoreDNS pods kubectl get pod -n kube-system -l k8s-app=kube-dns --no-headers | awk '{print $1}' | xargs -I{} kubectl delete pod -n kube-system {} # wait to be available again kubectl wait deployment -n kube-system coredns --for condition=Available=True --timeout=90s # tail CoreDNS logs kubectl logs deployment/coredns -n kube-system -f
Validate DNS upstream
# try alpine based image with musl library which can act differently than libc kubectl run -ti --rm alpine-musl --image=giantswarm/tiny-tools:3.12 --restart=Never --timeout=5s -- nslookup sub.my.local # try libc based library kubectl run -ti --rm busybox-libc --image=busybox:1.35.0-glibc --restart=Never --timeout=5s -- nslookup sub.my.local
The DNS queries will be output in the CoreDNS logs tailed earlier.
REFERENCES
kubernetes.io, CoreDNS for Service Discovery
Digital Ocean, how to customize CoreDNS
coredns.io, corefile configuration explained
kubernetes.io, customizing DNS
kubernetes.io, troubleshooting DNS resolution
pracucci.com, why 5 ndots for kubernetes dns lookup can negatively affect performance