Kubernetes – DNS
February 18, 2019DNS is a critical service in any system. Kubernetes is no different, but Kubernetes will implement its own domain naming system that’s implemented within your Kubernetes cluster. This post explores the details that you need to know to operate a k8s cluster properly.
Kubernetes DNS – The theory
I don’t want to dive into DNS too much since it’s a core service most should be familiar with. But at a really high level, DNS translates an IP address that might be changing, with an easily remember-able name such as “theithollow.com”. Every network has a DNS server, but Kubernetes implements their own DNS within the cluster to make connecting to containers a simple task.
There are two implementations of DNS found within Kubernetes clusters. Kube-dns and CoreDNS. The default used with kubeadm after version 1.13 is to use CoreDNS which is managed by the Cloud Native Computing Foundation. Since I used kubeadm to setup our cluster and it’s the default version, this post will focus on CoreDNS.
This topic can be pretty detailed, but lets distill it into the basics. Each time you deploy a new service or pod, the DNS service sees the calls made to the Kube API and adds DNS entries for the new object. Then other containers within a Kubernetes cluster can use these DNS entries to access the services within it by name.
There are two objects that you could access via DNS within your Kubernetes cluster and those are Services and Pods. Now Pods can get a dns entry, but you’d be wondering why, since we’ve learned that accessing pods should be done through a Service. For this reason, pods don’t get a DNS entry by default with CoreDNS.
Services get a DNS entry of the service name appended to the namespace and then appended to “svc.cluster.local”. Similarly pods get entries of PodIPAddress appended to the namespace and then appended to .pod.cluster.local if Pod DNS is enabled in your cluster.
The diagram below shows a pair of services and a pair of pods that are deployed across two different namespaces. Below this are the DNS entries that you can expect to be available for these objects, again assuming Pod DNS is enabled for your cluster.
Any pods looking for a service within the same namespace can just use the common name of the “Service” instead of the FQDN. Kubernetes will add the proper DNS suffix to the request if one is not given. In fact, when you deploy new pods, Kubernetes specifies your DNS server for you unless you override it within a manifest file.
Kubernetes DNS – In Action
Lets take a quick look at how DNS is working in our own Kubernetes cluster. Feel free to deploy any Kubernetes manifest that has a service and pod in the deployment. If you need one, you can use mine below.
apiVersion: apps/v1
kind: Deployment
metadata:
name: nginx-deployment
labels:
app: nginx
spec:
replicas: 2
selector:
matchLabels:
app: nginx
template:
metadata:
labels:
app: nginx
spec:
containers:
- name: nginx-container
image: nginx
ports:
- containerPort: 80
---
apiVersion: v1
kind: Service
metadata:
name: nginxsvc
spec:
type: NodePort
ports:
- name: http
port: 80
targetPort: 80
nodePort: 30001
protocol: TCP
selector:
app: nginx
You can deploy the file with:
kubectl apply -f [manifest file].yml
Code language: CSS (css)
Now lets look at some information about our service which we’ll check later in this post.
kubectl get svc
Code language: JavaScript (javascript)
Once our example pods and services are deployed, let’s deploy another container where we can run some DNS lookups. To do this we’ll deploy the shell-demo container and get an interactive shell by using the commands below. We’ll also install busybox once we’ve got a shell.
Kubectl create -f https://k8s.io/examples/application/shell-demo.yaml
kubectl exec -it shell-demo -- /bin/bash
Apt-get update
Apt-get install busybox -y
Code language: JavaScript (javascript)
Now that busybox is installed and we’re in an interactive shell session, lets check to see what happens when we run a dns lookup on our example service.
busybox nslookup nginxsvc
The results of our nslookup on the nginxsvc that we deployed early on in this post shows the ClusterIP address of the Service. Also, pay close attention to the FQDN. The FQDN is the [service name] +”.” + [namespace name] + “.” + svc.cluster.local.
Summary
DNS is a basic service that we rely on for almost all systems. Kubernetes is no different and it makes accessing other services very simple and straightforward. You can manipulate your DNS configs by update manifest files if you need, but for the basic operations, you should be good to go without even having to configure much. And remember… it’s ALWAYS DNS.
To clean up your cluster run:
kubectl delete -f [manifest file].yml #manifest used during the deploy of the nginxsvc
kubectl delete pod shell-demo
Code language: CSS (css)
Thank you for sharing,
10.244.2.2.namespace1.pod.cluster.local or 10-244-2-2.namespace1.pod.cluster.local ? (dashed IP address)
I had the same, if you do a nslookup on 10.244.2.2 you’ll probably get 10-244-2-2.namespace1.pod.cluster.local
[…] 10. DNS […]
This was one of the best resumed and ELI5 articles i could find on Kubernetes DNS, thanks!