CoreDNS and service discovery
How Services and Pods get DNS names, how a Pod looks them up, and how to change the Corefile safely.
Key ideas in this lesson · tap one for a simple explanation
What you will be able to do
- Predict the DNS name of any Service, headless Service or Pod, and look it up from a client Pod.
- Set dnsPolicy and dnsConfig on a Pod, and check the result in its /etc/resolv.conf.
- Read the CoreDNS Corefile and change it safely.
Inside a cluster, apps find each other by name. Your frontend calls http://api, and DNS turns api into the 's IP. is the DNS server that answers. It runs as a in kube-system, behind a Service called kube-dns, and one holds its settings. The exam topic is Understand and use CoreDNS.
Your app
looks up the name inventory
/etc/resolv.conf
in every Pod; says where to ask
nameserver 10.96.0.10
CoreDNS
behind the kube-dns Service, at 10.96.0.10
The answer
the ClusterIP of Service inventory
CoreDNS reads Services and Pods from the API, so a new Service has a name within seconds.
The names CoreDNS answers
Every Service gets a name made of its own name, its and svc.cluster.local. For Service inventory in namespace nw-dns, that is inventory.nw-dns.svc.cluster.local. In the table, an A record is a DNS answer that maps a name to an IP.
What a Pod's resolver does
The writes a file called /etc/resolv.conf into every Pod. It tells the Pod where to send lookups, and how to finish short names.
kubectl -n nw-dns exec client -- cat /etc/resolv.conf
# search nw-dns.svc.cluster.local svc.cluster.local cluster.local
# nameserver 10.96.0.10
# options ndots:5
kubectl -n kube-system get svc kube-dns # 10.96.0.10: the ClusterIP of CoreDNSnameserver 10.96.0.10is the ClusterIP of thekube-dnsService. Every lookup goes there.searchlists the endings tried for a short name. That is whyinventoryworks insidenw-dns, andinventory.nw-dnsworks from any namespace.ndots:5means a name with fewer than five dots gets each search ending tried first. Soapi.example.comcosts three failed cluster lookups before the real one. A dot at the end (api.example.com.) skips the search list.
dnsPolicy and dnsConfig
Two Pod fields change that file. dnsPolicy picks where lookups go. dnsConfig adds your own settings on top.
apiVersion: v1
kind: Pod
metadata:
name: resolver
namespace: nw-dnscfg
spec:
dnsPolicy: ClusterFirst # dnsPolicy and dnsConfig are immutable: change the manifest and
dnsConfig: # recreate the Pod (kubectl replace --force -f), or edit a Deployment template
searches:
- corp.internal # appended after the cluster search domains
options:
- name: ndots
value: "2" # value is a string
- name: timeout
value: "2"
containers:
- name: busybox
image: busybox:1.36
command: ["sleep", "3600"]The Corefile
CoreDNS reads its settings from a file called the Corefile, stored in the coredns ConfigMap in kube-system. Each line inside the block turns on one plugin. Here is the one in this lab:
.: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 {
disable success cluster.local
disable denial cluster.local
}
loop
reload
loadbalance
}You do not need every line. These are the ones exam tasks touch:
kubernetesanswers names incluster.local, from the Services and Pods in the API.forward . /etc/resolv.confsends every other name to the DNS servers of the node CoreDNS runs on.cache 30keeps answers for up to 30 seconds. Here it skipscluster.localnames, so only outside names can lag behind a change.hostsis not there by default. It serves fixed name-to-IP entries. Always addfallthrough, so names it does not list still reach the next plugin.reloadrereads the Corefile when the ConfigMap changes. That can take a minute or two, so restart CoreDNS instead of waiting.
Every Pod in the cluster depends on this file, and one typo breaks DNS everywhere. So change it in four steps: back it up, edit it, restart CoreDNS, and check the logs.
# Keep a copy first. Every Pod in the cluster depends on this file.
kubectl -n kube-system get cm coredns -o jsonpath='{.data.Corefile}' > /tmp/cka/Corefile.bak
kubectl -n kube-system edit cm coredns # e.g. add, inside .:53 { … }:
# hosts {
# 10.10.10.10 legacy-db.corp.internal
# fallthrough
# }
# Apply now instead of waiting for reload, then make sure both replicas come back
kubectl -n kube-system rollout restart deploy coredns
kubectl -n kube-system rollout status deploy coredns --timeout=120s
kubectl -n kube-system logs -l k8s-app=kube-dns --tail=20 # a syntax error shows up here
# Roll back if it went wrong
kubectl -n kube-system create cm coredns --from-file=Corefile=/tmp/cka/Corefile.bak --dry-run=client -o yaml | kubectl replace -f -
kubectl -n kube-system rollout restart deploy corednsRunning a lookup
To test DNS, run nslookup from a client Pod in the namespace you care about. The busybox:1.36 image has it.
kubectl -n nw-dns run client --image=busybox:1.36 --restart=Never -- sleep 3600
kubectl -n nw-dns wait --for=condition=Ready pod/client --timeout=60s
kubectl -n nw-dns exec client -- nslookup inventory.nw-dns.svc.cluster.local # one Service
kubectl -n nw-dns exec client -- nslookup inventory-pods.nw-dns.svc.cluster.local # headless: one line per Pod
kubectl -n nw-dns exec client -- nslookup kubernetes.default.svc.cluster.local # the API: always existsWhen a lookup fails, the error message tells you which part is broken. Service and DNS failures walks through each case.
In the official docs· open on exam day too
- DNS for Services and Podssearch: dns for services and pods
- Debugging DNS Resolutionsearch: debugging dns resolution
- Customizing DNS Servicesearch: customizing dns service corefile
Resolve a Service and a headless Service
nw-dns, start a temporary Pod with image busybox:1.36. From it, resolve the fully qualified DNS name of the Service inventory and write the address the lookup returns to /tmp/cka/dns-inventory-ip.txt. Then resolve the fully qualified name of the headless Service inventory-pods and write every address it returns, one per line, to /tmp/cka/dns-inventory-pods.txt. Delete the temporary Pod when you are done.Cluster:kubectl config use-context kind-cka
- 1
Set up the scenario
curl -fsSL https://codewithmuh.com/labs/cka/t/nw-dns-1/setup | bash - 2
Solve it in your terminal
Use kubectl and the Kubernetes docs, like on exam day. Save any answer files under
/tmp/cka/. - 3
Check your work
curl -fsSL https://codewithmuh.com/labs/cka/t/nw-dns-1/verify | bashGot FAIL? Read which check failed, fix it, run it again. - 4
Clean up (optional)
curl -fsSL https://codewithmuh.com/labs/cka/t/nw-dns-1/cleanup | bash
Give a Pod an extra search domain
resolver in namespace nw-dnscfg using image busybox:1.36 that runs sleep 3600. It must keep using cluster DNS. Add corp.internal as an additional search domain and set the resolver option ndots to 2. The Pod must be Running.Cluster:kubectl config use-context kind-cka
- 1
Set up the scenario
curl -fsSL https://codewithmuh.com/labs/cka/t/nw-dns-2/setup | bash - 2
Solve it in your terminal
Use kubectl and the Kubernetes docs, like on exam day. Save any answer files under
/tmp/cka/. - 3
Check your work
curl -fsSL https://codewithmuh.com/labs/cka/t/nw-dns-2/verify | bashGot FAIL? Read which check failed, fix it, run it again. - 4
Clean up (optional)
curl -fsSL https://codewithmuh.com/labs/cka/t/nw-dns-2/cleanup | bash
Serve a static record from CoreDNS
legacy-db.corp.internal to 10.10.10.10. All existing names, including Services and names outside the cluster, must keep resolving. Confirm from Pod client in namespace nw-dnshosts.Cluster:kubectl config use-context kind-cka
- 1
Set up the scenario
curl -fsSL https://codewithmuh.com/labs/cka/t/nw-dns-3/setup | bash - 2
Solve it in your terminal
Use kubectl and the Kubernetes docs, like on exam day. Save any answer files under
/tmp/cka/. - 3
Check your work
curl -fsSL https://codewithmuh.com/labs/cka/t/nw-dns-3/verify | bashGot FAIL? Read which check failed, fix it, run it again. - 4
Clean up (optional)
curl -fsSL https://codewithmuh.com/labs/cka/t/nw-dns-3/cleanup | bash
Finished this lesson?
0 of 3 tasks passed. Your readiness counts tasks, so run them before you move on.