CoreDNS

CoreDNS is the default DNS server for Kubernetes clusters. It enables Pods and Services to discover each other by name rather than by volatile IP address.

Why Cluster DNS Matters

In Kubernetes:

  • Pod IPs are ephemeral — they change on restart, rescheduling, or scaling.
  • Service IPs are stable within the cluster, but remembering them is impractical.
  • Applications need to reach other services by a predictable name (e.g., database.default.svc.cluster.local).

CoreDNS solves this by maintaining an internal DNS namespace for the cluster.

Relationship to External DNS

This video on external DNS is explicitly framed as a prerequisite for understanding CoreDNS:

“From the next video we’ll be looking into networking stuff related to Kubernetes itself like CoreDNS. I thought it would be a good idea to add a prerequisite because to understand CoreDNS, you need to know how DNS works actually.” — Day 30 CKA Video

The same principles apply:

  • A records → map service names to ClusterIPs
  • CNAME-like behavior → ExternalName Services proxy to external domains
  • Caching → CoreDNS caches responses to reduce API server load
  • Hierarchical resolution.svc.cluster.local is the cluster domain; queries outside it are forwarded upstream

How CoreDNS Works (High-Level)

  1. A Pod makes a DNS query for my-service.default.svc.cluster.local.
  2. The query is sent to the cluster’s DNS Service IP (usually 10.96.0.10 or the 10th IP in the Service CIDR).
  3. CoreDNS receives the query.
  4. CoreDNS checks the Kubernetes plugin — finds the Service’s ClusterIP.
  5. Returns the IP to the Pod.

For external domains (e.g., google.com), CoreDNS forwards the query to an upstream resolver configured in its Corefile.

CoreDNS Configuration (Corefile)

CoreDNS behavior is defined by the Corefile:

.:53 {
    errors
    health
    kubernetes cluster.local in-addr.arpa ip6.arpa {
       pods insecure
       fallthrough in-addr.arpa ip6.arpa
    }
    prometheus :9153
    forward . /etc/resolv.conf
    cache 30
    loop
    reload
    loadbalance
}
PluginPurpose
kubernetesAnswers queries for .svc.cluster.local using the API server
forwardSends unresolved queries to upstream DNS (e.g., /etc/resolv.conf)
cacheCaches responses for 30 seconds
prometheusExposes metrics for monitoring

DNS in Kubernetes Services

Service TypeDNS Behavior
ClusterIPmy-service.my-namespace.svc.cluster.local → ClusterIP
HeadlessReturns individual Pod IPs (A records for each endpoint)
ExternalNameReturns a CNAME to an external domain

Troubleshooting Cluster DNS

CommandPurpose
kubectl run -it --rm debug --image=busybox:1.28 --restart=Never -- nslookup kubernetes.defaultTest if Pod DNS works
kubectl logs -n kube-system -l k8s-app=kube-dnsCheck CoreDNS logs
kubectl get configmap coredns -n kube-system -o yamlInspect Corefile

Practical Practice

Exam-style hands-on tasks for CoreDNS and cluster DNS. Complete each task before reviewing the solution. Time yourself — CKA tasks average 5–7 minutes.

Task 1: Verify Cluster DNS is Working You are asked to confirm that Pods in the cluster can resolve the Kubernetes API service name. Requirements: Use a temporary Pod with busybox:1.28. Run nslookup kubernetes.default. Verification: The command returns the ClusterIP of the kubernetes Service. Solution:

kubectl run -it --rm debug --image=busybox:1.28 --restart=Never -- nslookup kubernetes.default

Task 2: Resolve a Cross-Namespace Service A Pod in namespace frontend cannot reach a Service api in namespace backend. You suspect the Pod is using a short name instead of the full FQDN. Requirements: From a test Pod in frontend, resolve the Service using the correct cross-namespace FQDN. Verification: kubectl run -n frontend -it --rm debug --image=busybox:1.28 --restart=Never -- nslookup api.backend.svc.cluster.local Solution:

kubectl run -n frontend -it --rm debug --image=busybox:1.28 --restart=Never -- nslookup api.backend.svc.cluster.local

Task 3: Inspect the CoreDNS ConfigMap You are asked to view the active CoreDNS Corefile to understand how cluster DNS is configured. Requirements: Read the ConfigMap coredns in kube-system namespace. Verification: kubectl get configmap coredns -n kube-system -o yaml | head -20 Solution:

kubectl get configmap coredns -n kube-system -o yaml
# Look for the Corefile section under data:

Task 4: Fix DNS Resolution After NetworkPolicy A default-deny NetworkPolicy in namespace app is blocking all egress. Pods can no longer resolve Service names. Requirements: Add an egress rule allowing UDP 53 to the kube-system namespace. Verification: kubectl run -n app -it --rm debug --image=busybox:1.28 --restart=Never -- nslookup kubernetes.default Solution:

cat <<EOF | kubectl apply -f -

apiVersion: networking.k8s.io/v1 kind: NetworkPolicy metadata: name: allow-dns namespace: app spec: podSelector: {} policyTypes:

  • Egress egress:
  • to:
    • namespaceSelector: matchLabels: kubernetes.io/metadata.name: kube-system ports:
    • protocol: UDP port: 53 EOF

Source