Kubernetes Internal DNS

kubernetes dns is for service objects. DNS is served as a pod in the cluster.

Set up kubelet to use DNS

Modify kubelet definition file(/etc/kubernetes/kubelet) on all minions. Add the following options.

--cluster-dns=<DNS service ip> (should be one of clusterIP range)
--cluster-domain=<default local domain>
ex)
--cluster-dns=10.24.0.10
--cluster-domain=kubic.local

Restart kubelet service on all minions

$ sudo systemctl daemon-reload
$ sudo systemctl restart kubelet

Run kubedns pod and service

Create manifest files for DNS

  • Service manifest file (conffiles/kube-system/kubedns/svc_kubedns.yml)
  • Deployment manifest file (conffiles/kube-system/kubedns/dep_kubedns.yml)

These manifest files are based on https://github.com/kubernetes/kubernetes/tree/master/cluster/addons/dns

Note) If the cluster is not TLS enabled, you have to specify kubemaster in args of kubedns container. (–kube-master-url=http://:8080) If the cluster is working with TLS, there is no need to modify.

Run each manifest file.

$ kubectl create -f svc_kubedns.yml
$ kubectl create -f dep_kubedns.yml

Check if deployment, pods, and service are up okay.

$ kubectl get deploy -n kube-system
NAME       DESIRED   CURRENT   UP-TO-DATE   AVAILABLE   AGE
kube-dns   1         1         1            1           28m

$ kubectl get po -n kube-system
NAME                        READY     STATUS    RESTARTS   AGE
kube-dns-3246654209-znk45   3/3       Running   0          28m

$ kubectl get svc -n kube-system
NAME       CLUSTER-IP   EXTERNAL-IP   PORT(S)         AGE
kube-dns   10.24.0.10   <none>        53/UDP,53/TCP   4d

There are 3 containers running in a pod(kube-dns-3246654209-znk45)

* kubedns: dns service listening on port 10053(udp/tcp) and 10055(tcp)
* dnsmasq: dns proxy service listening on port 53(udp/tcp)
* sidecar: health check service listening on 10054(tcp)

Test DNS Service

Check if DNS is working inside a container. any service will have dns name with the following order.

<service_name>.<namespace>.svc.<cluster_domain>
ex) kubernetes.default.svc.kubic.local

Kubernetes apiserver service name is ‘kubernetes’ and it runs in ‘default’ namespace. So its fqdn(fully qualified domain name) will be kubernetes.default.svc.kubic.local.

I’ll use busybox(conffiles/myfiles/dep_busybox.yml)

$ kubectl create -f dep_busybox.yml
$ kubectl exec -it busybox sh
/# nslookup kubernetes
Server:    10.24.0.10
Address 1: 10.24.0.10 kube-dns.kube-system.svc.kubic.local

Name:      kubernetes

name with the following order.

<service_name>.<namespace>.svc.<cluster_domain>
ex) kubernetes.default.svc.kubic.local

Kubernetes apiserver service name is ‘kubernetes’ and it runs in ‘default’ namespace. So its fqdn(fully qualified domain name) will be kubernetes.default.svc.kubic.local.

I’ll use busybox(conffiles/myfiles/dep_busybox.yml)

$ kubectl create -f dep_busybox.yml
$ kubectl exec -it busybox sh
/# nslookup kubernetes
Server:    10.24.0.10
Address 1: 10.24.0.10 kube-dns.kube-system.svc.kubic.local

Name:      kubernetes

kubernetes.default.svc.kubic.local.

I’ll use busybox(conffiles/myfiles/dep_busybox.yml)

$ kubectl create -f dep_busybox.yml
$ kubectl exec -it busybox sh
/# nslookup kubernetes
Server:    10.24.0.10
Address 1: 10.24.0.10 kube-dns.kube-system.svc.kubic.local

Name:      kubernetes
Address 1: 10.24.0.1 kubernetes.default.svc.kubic.local

We can see it automatically refer to the internal kubedns and kubedns gives the IP for kubernetes hostname. One curious thing is I put only ‘kubernetes’ but it is expanded to ‘.default.svc.kubic.local’. The magic is in /etc/resolv.conf.

If you see /etc/resolv.conf in the container, it shows:

search default.svc.kubic.local svc.kubic.local kubic.local
nameserver 10.24.0.10
options ndots:5

Look at ‘options ndots:5’. That makes resolver expands kubernetes to kubernetes.default.svc.kubic.local. kubernetes.default and kubernetes.default.svc will also be expaneded.