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
from
domain will be forwarded to theto
DNS server. In the current configuration the vlaue offrom
is set to.
which indicates any domain. - to: Destination to forward the DNS requests, currently set to the DNS server configured in
/etc/resolve.conf
in 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.