How Does CoreDNS Work in Kubernetes?

intermediate|networkingdevopssreCKA
TL;DR

CoreDNS is the default DNS server in Kubernetes. It runs as a Deployment in the kube-system namespace and resolves Service names, Pod names, and external domains. Every Pod's /etc/resolv.conf points to the CoreDNS ClusterIP.

Detailed Answer

CoreDNS Architecture

CoreDNS runs as a Deployment (typically two replicas for high availability) in the kube-system namespace. A ClusterIP Service named kube-dns exposes it, usually on IP 10.96.0.10. The kubelet configures every Pod's /etc/resolv.conf to point to this address.

# View CoreDNS components
kubectl get deployment coredns -n kube-system
kubectl get svc kube-dns -n kube-system

When a Pod performs a DNS lookup, the query goes to CoreDNS, which resolves it using information from the Kubernetes API.

DNS Record Types

CoreDNS creates several types of DNS records:

Service Records (A/AAAA)

<service-name>.<namespace>.svc.cluster.local
# Example: nginx-svc.default.svc.cluster.local -> 10.96.45.12

Headless Service Records

For headless Services (ClusterIP: None), CoreDNS returns the individual Pod IPs:

<service-name>.<namespace>.svc.cluster.local -> 10.244.1.5, 10.244.2.8, 10.244.3.12

SRV Records

_<port-name>._<protocol>.<service>.<namespace>.svc.cluster.local
# Example: _http._tcp.nginx-svc.default.svc.cluster.local

Pod Records

<pod-ip-dashed>.<namespace>.pod.cluster.local
# Example: 10-244-1-5.default.pod.cluster.local

The Corefile ConfigMap

CoreDNS is configured through a ConfigMap named coredns in kube-system:

apiVersion: v1
kind: ConfigMap
metadata:
  name: coredns
  namespace: kube-system
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
    }

Key plugins:

  • kubernetes: Resolves cluster Service and Pod names
  • forward: Forwards external queries to upstream DNS
  • cache: Caches responses for the specified TTL
  • loop: Detects and breaks DNS forwarding loops
  • health/ready: Provides liveness and readiness endpoints

How Pod DNS Resolution Works

Every Pod gets a /etc/resolv.conf like this:

nameserver 10.96.0.10
search default.svc.cluster.local svc.cluster.local cluster.local
options ndots:5

The ndots:5 setting means any name with fewer than 5 dots is treated as a relative name. Kubernetes appends each search domain and tries them in order. For example, resolving nginx-svc triggers:

  1. nginx-svc.default.svc.cluster.local (match found, returns ClusterIP)
  2. If not found: nginx-svc.svc.cluster.local
  3. If not found: nginx-svc.cluster.local
  4. If not found: absolute lookup for nginx-svc

This can cause extra DNS queries for external names. You can tune this per Pod:

apiVersion: v1
kind: Pod
metadata:
  name: optimized-dns
spec:
  dnsConfig:
    options:
      - name: ndots
        value: "2"
  containers:
    - name: app
      image: myapp:latest

Troubleshooting DNS

# 1. Verify CoreDNS is running
kubectl get pods -n kube-system -l k8s-app=kube-dns

# 2. Run a debug Pod
kubectl run dnstest --image=busybox:1.36 --rm -it --restart=Never -- sh

# Inside the debug Pod:
nslookup kubernetes.default.svc.cluster.local
nslookup google.com

# 3. Check CoreDNS logs
kubectl logs -n kube-system -l k8s-app=kube-dns

# 4. Verify resolv.conf in a Pod
kubectl exec <pod-name> -- cat /etc/resolv.conf

Custom DNS Entries

You can add custom DNS entries using the hosts plugin in the Corefile:

data:
  Corefile: |
    .:53 {
        hosts {
          10.0.0.50 legacy-db.internal
          fallthrough
        }
        kubernetes cluster.local in-addr.arpa ip6.arpa {
          pods insecure
          fallthrough in-addr.arpa ip6.arpa
        }
        forward . /etc/resolv.conf
        cache 30
    }

Scaling CoreDNS

For large clusters, CoreDNS can become a bottleneck. Use the NodeLocal DNSCache addon, which runs a DNS caching agent on each node to reduce cross-node DNS traffic and improve latency:

kubectl apply -f https://raw.githubusercontent.com/kubernetes/kubernetes/master/cluster/addons/dns/nodelocaldns/nodelocaldns.yaml

This places a local DNS cache at 169.254.20.10 on each node, reducing load on the central CoreDNS Pods and improving DNS resolution times from ~2ms to ~0.1ms.

Why Interviewers Ask This

Interviewers want to confirm you understand how in-cluster service discovery works and can troubleshoot DNS resolution failures, one of the most common Kubernetes issues.

Common Follow-Up Questions

What is the full DNS name for a Service?
<service>.<namespace>.svc.cluster.local. Pods can use the short name within the same namespace.
How do you troubleshoot DNS issues in a cluster?
Run a debug Pod with nslookup/dig, check CoreDNS logs, verify the CoreDNS Pods are running, and inspect the Corefile ConfigMap.
Can CoreDNS resolve external domain names?
Yes. CoreDNS forwards queries it cannot resolve locally to upstream DNS servers specified in the forward plugin configuration.

Key Takeaways

  • CoreDNS resolves Service and Pod names within the cluster
  • It is configured via a ConfigMap called 'coredns' in kube-system
  • DNS failures are among the most common causes of connectivity issues