bookmark_borderHow Kubernetes Implements DNS?

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

DNS
In web-app-podIn nginx-pod
way 1cat >> /etc/host
nginx-pod 172.17.0.2
cat >> /etc/host
web-app-pod 172.17.0.3
way 2cat >> /etc/resolv.conf
nameserver 172.17.0.8
cat >> /etc/resolv.conf
nameserver 172.17.0.8
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
nginx-clusterip-servicedefaultsvccluster.local10.98.112.241
172-1172-17-0-2defaultpodcluster.local172.17.0.2
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   172.17.0.8     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
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
    }
kind: ConfigMap
metadata:
  creationTimestamp: "2021-01-19T11:21:40Z"
  managedFields:
  - apiVersion: v1
    fieldsType: FieldsV1
    fieldsV1:
      f:data:
        .: {}
        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 www.google.com 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
172-1172-17-0-2defaultpodcluster.local172.17.0.2
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   10.96.0.10     <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   172.17.0.9    minikube   <none>           <none>
web-app-pod                        1/1     Running   2          10h   172.17.0.4    minikube   <none>           <none>

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

CoreDNS connection Test

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

$ kubectl exec -it nginx-pod -- sh
# cat /etc/resolv.conf
nameserver 10.96.0.10
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!
ANOTE.DEV