How Kubernetes Implements DNS?

How Kubernetes Implements DNS? We need the entries into a central DNS Server like CoreDNS.

In web-app-podIn nginx-pod
way 1cat >> /etc/host
cat >> /etc/host
way 2cat >> /etc/resolv.conf
cat >> /etc/resolv.conf
Cluster DNS

The way 2 should use in Kubernetes Cluster.

Every time a new pod is created, we should add a record in the DNS Server for the pod so that other pods can access the new pod, and configure the /etc/resolv.conf file in the pod to the Cluster DNS Server so that the pod can resolve other pods in the cluster. This is kind of how Kubernetes does it. Except that it does not create similar entries for Pods to map pod name to its IP Address. It does that for services. For pods, it forms Hostnames by replacing . with - in the IP Address of the pod. Kubernetes implements DNS in the same way. It deploys a DNS Server within the cluster.

HostnameNamespaceTypeRootIP Address
DNS rule

Prior to version 1.12 : The DNS implemented by Kubernetes was Kube-DNS. Kubernetes version 1.12: the recommended DNS server is CoreDNS.

How does the core DNS setup in the cluster?

$ kubectl get pods -n kube-system -o wide
NAME                                        READY   STATUS      RESTARTS   AGE     IP             NODE       NOMINATED NODE   READINESS GATES
coredns-74ff55c5b-vjvpb                     1/1     Running     5          4d22h     minikube   <none>           <none>
  • The CoreDNS server is deployed as a pod in the Kube-system namespace.
  • This Pod runs the CoreDNS executable, the same executable that we ran when we deployed CoreDNS ourself.

CoreDNS requires a configuration file. as below configuration file in Kubernetes ConfigMap

$ kubectl get ConfigMap coredns -n kube-system -o yaml
apiVersion: v1
  Corefile: |
    .:53 {
        health {
           lameduck 5s
        kubernetes cluster.local {
           pods insecure
           ttl 30
        prometheus :9153
        forward . /etc/resolv.conf {
           max_concurrent 1000
        cache 30
kind: ConfigMap
  creationTimestamp: "2021-01-19T11:21:40Z"
  - apiVersion: v1
    fieldsType: FieldsV1
        .: {}
        f:Corefile: {}
    manager: kubeadm
    operation: Update
    time: "2021-01-19T11:21:40Z"
  name: coredns
  namespace: kube-system
  resourceVersion: "256"
  uid: 65e2cda2-d57a-4f39-a3f5-6bcf4620fb06

In this file, you have a number of plugins configured. Plugins are configured for handling errors, reporting health, monitoring metrics, cache etc. The plugin that make CoreDNS with Kubernetes, is the Kubernetes plugin. And this is where the top level domain name for the cluster is set. kubernetes cluster.local So every recod in the coredns DNS server falls under this domain.

Also, there is pod option, pods insecure, is what is responsible for creating a record for pods in the cluster.

A recode being created for each pod by converting their IPs into a dashed format. This is disabled by default. However, it can be enabled with the entry here. Any record that the DNS server can not resolve, the pod tries to reach it is forwarded to the nameserver specified in the core dns pods /etc/reolv.conf file. etc/resolv.conf file is set to use the nameserver from the Kubernetes Node. That is core file is passed into the pods has a ConfigMap object. If you need to modify the configuration you should edit the ConfigMap object.

HostnameNamespaceTypeRootIP Address
pods record.

If the Kubernetes Cluster has coredns pod, It watches the kubernetes cluster for new pods or services, and every time a pod or a service is created it adds a record for it in its database.

$ kubectl get pods -n kube-system
NAME                                        READY   STATUS      RESTARTS   AGE
coredns-74ff55c5b-vjvpb                     1/1     Running     6          5d

$ kubectl get service -n kube-system
kube-dns                             ClusterIP     <none>        53/UDP,53/TCP,9153/TCP   5d

$ kubectl get pod -n default -o wide
NAME                               READY   STATUS    RESTARTS   AGE   IP            NODE       NOMINATED NODE   READINESS GATES
nginx-pod                          1/1     Running   2          10h    minikube   <none>           <none>
web-app-pod                        1/1     Running   2          10h    minikube   <none>           <none>

$ kubectl get service -n default
NAME                      TYPE        CLUSTER-IP       EXTERNAL-IP   PORT(S)        AGE
nginx-clusterip-service   ClusterIP    <none>        80/TCP         10h

CoreDNS connection Test

$ kubectl exec -it web-app-pod -- sh
[ root@web-app-pod:/ ]$ cat /etc/resolv.conf
search default.svc.cluster.local svc.cluster.local cluster.local
options ndots:5

$ kubectl exec -it nginx-pod -- sh
# cat /etc/resolv.conf
search default.svc.cluster.local svc.cluster.local cluster.local
options ndots:5

If you curl curl nginx-clusterip-service, it return with no error. which should happen nginx-clusterip-service.default.svc.cluster.local Because in /etc/resolv.conf has search command default.svc.cluster.local svc.cluster.local cluster.local.

[ root@web-app-pod:/ ]$ curl nginx-clusterip-service.default.svc.cluster.local
Welcome to nginx!

[ root@web-app-pod:/ ]$ curl nginx-clusterip-service
Welcome to nginx!

This is only for service so, you won’t be able to reach a pod the same way. You need to specify the full FQDN of the pod.

[ root@web-app-pod:/ ]$ curl 172-17-0-9
curl: (6) Couldn't resolve host '172-17-0-9'

[ root@web-app-pod:/ ]$ curl 172-17-0-9.default.pod.cluster.local
Welcome to nginx!

Leave a Reply

Your email address will not be published.