How to configure an external DNS server address in CoreDNS

In this tutorial, we will configure Kubernetes Service, CoreDNS, to resolve external domain names via an external DNS server.
CoreDNS can resolve Kubernetes cluster-internal domain names like the domain names assigned to Pods and Services.
What if a Pod in your cluster wants to communicate with an external domain like app.yourdomain.com. CoreDNS cannot resolve app.yourdomain.com because it’s not cluster-internal. So it proxies such DNS requests to another resolver. By default, CoreDNS proxies these requests to the DNS server configured in the /etc/resolve.conf in the CoreDNS Pod.
We are going to change CoreDNS configuration so CoreDNS will proxy DNS requests for external domain names to Google DNS server 8.8.8.8 (or any preferred DNS server of yours).
Prerequisites
- A Kubernetes cluster with CoreDNS installed.
kubectl(Kubernetes CLI) installed and configured to access the Kubernetes cluster.
If you do not have a Kubernetes cluster, check out this tutorial to quickly deploy a Kubernetes cluster on your laptop.
Outline of steps
- Step-1: Verify current CoreDNS configuration
- Step-2: Update CoreDNS configuration
- Step-3: Test the CoreDNS new configuration
Step-1: Verify current CoreDNS configuration
CoreDNS configuration is stored in ConfigMap coredns in the kube-system namespace. Let’s check out what the current configuration is.
Open a terminal in the workstation where kubectl is installed and configured to access the Kubernetes cluster and print the CoreDNS configuration:
$ kubectl describe configmap coredns -n kube-system
Name: coredns
Namespace: kube-system
Labels: <none>
Annotations: <none>
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
}
BinaryData
====
Events: <none>
The domain of the Kubernetes cluster is set to cluster.local by default. CoreDNS resolves any DNS request that belongs to this domain.
For any DNS request that does not belong to cluster.local, CoreDNS will proxy the request as specified by the forward directive in the ConfigMap.
Current configuration of forward:
forward . /etc/resolv.conf {
max_concurrent 1000
}
The syntax of forward:
forward <from> <to> {
<other_params>
}
- from: DNS requests that have a matching
fromdomain will be forwarded to thetoDNS server. In the current configuration the vlaue offromis set to.which indicates any domain. - to: Destination to forward the DNS requests, currently set to the DNS server configured in
/etc/resolve.confin the CoreDNS Pod.
Step-2: Update CoreDNS configuration
Let’s update forward directive as below so CoreDNS will proxy the DNS requests to 8.8.8.8
forward . 8.8.8.8 {
max_concurrent 1000
}
I have used Google DNS server 8.8.8.8. You can use your preferred DNS server.
Edit the ConfigMap:
$ kubectl edit configmap coredns -n kube-system
This will open coredns ConfigMap in a text editor in your terminal. Update the forward directive as required and save.
Step-3: Test the CoreDNS new configuration
Let’s test our new CoreDNS configuration.
Launch busybox pod:
$ kubectl run busybox --image=busybox --command -- "/bin/sh" "-c" 'while true; do sleep 10; done'
Connect to busybox pod:
$ kubectl exec -it busybox -- sh
This opens a terminal session to the busybox pod.
Lookup any DNS record from busybox Pod terminal (you can replace cloudqubes.com with any domain name.):
# nslookup cloudqubes.com
Server: 10.96.0.10
Address: 10.96.0.10:53
Non-authoritative answer:
Non-authoritative answer:
Name: cloudqubes.com
Address: 20.99.157.72
The domain name is successfully resolved. We cannot verify with nslookp that our domain name is actually resolved from 8.8.8.8.
In an upcoming post, let’s check out how to use CoreDNS metrics to analyze requests proxied to external DNS servers.