Maintenance

Site is under maintenance — quizzes are still available.

Go to quizzes
Sponsored Reserved space — layout preview until AdSense is connected

Tech

How DNS Works in Kubernetes and Container Platforms

Kubernetes DNS enables service discovery in dynamic container environments where pods are ephemeral. This guide explains CoreDNS, pod DNS resolution, search domains, and debugging common pitfalls across Kubernetes, Docker Compose, and Nomad.

June 2026 · 9 min read · 1 views · 0 hearts

How DNS Works in Kubernetes and Container Platforms

Imagine you’re running 200 microservices in Kubernetes, and each one needs to talk to the others by name, not by IP. A pod dies, gets rescheduled, and its IP changes. Yet your services still find each other. That’s the magic of DNS — but inside Kubernetes, it works a little differently than your average dig google.com.

The Problem Kubernetes Solves

In traditional networking, DNS maps stable hostnames to IPs. In Kubernetes, pods are ephemeral — they come and go, scale up and down, and get new IPs constantly. You can't hardcode IPs, and you can't rely on /etc/hosts files updating themselves across hundreds of nodes.

So Kubernetes built its own DNS resolver. It’s not optional — it’s woven into the fabric of the cluster.

How It Works in Plain Terms

Every pod in a Kubernetes cluster gets a DNS resolver configuration automatically. When a pod tries to reach my-service.default.svc.cluster.local, the request is handled by a cluster-wide DNS service — typically CoreDNS (since Kubernetes 1.13, replacing kube-dns).

Here’s the flow:

  1. A pod runs in my-namespace. It tries to reach backend-service.
  2. The pod’s /etc/resolv.conf points to the cluster DNS service (e.g., 10.96.0.10).
  3. CoreDNS receives the query. It checks its internal records, which are populated dynamically by the Kubernetes API server.
  4. CoreDNS returns the ClusterIP of the backend-service Service object.
  5. The pod connects to that IP, and the Service forwards traffic to a healthy pod.

All of this happens in milliseconds, and the records update automatically when pods or services change.

The Key DNS Objects: Services and Pods

Services get DNS names automatically

When you create a Service named api in namespace production, Kubernetes registers:

api.production.svc.cluster.local

That resolves to the Service’s ClusterIP. If you’re in the same namespace, you can just use api. Across namespaces, use api.production.

Pods can get DNS too (if you want)

By default, pods don’t get DNS entries. But if you set hostname and subdomain fields, or use StatefulSets, each pod gets a stable DNS name like:

web-0.web-service.default.svc.cluster.local

This is critical for stateful workloads (databases, Kafka, Elasticsearch) where each node needs a persistent identity.

CoreDNS: The Engine Under the Hood

CoreDNS is a modular, plugin-based DNS server written in Go. Kubernetes ships it as a Deployment (usually 2 replicas) with a ConfigMap for configuration.

Its job is simple: watch the Kubernetes API for Services and Endpoints, then serve DNS queries based on that data.

You can check the logs:

kubectl logs -n kube-system coredns-<pod-id>

Or inspect its config:

kubectl -n kube-system get configmap coredns -o yaml

That ConfigMap contains the Corefile — CoreDNS’s configuration. A typical entry:

.:53 {
    errors
    health
    kubernetes cluster.local in-addr.arpa ip6.arpa {
        pods insecure
        fallthrough in-addr.arpa ip6.arpa
        ttl 30
    }
    prometheus
    forward . /etc/resolv.conf
    cache 30
    loop
    reload
    loadbalance
}

This tells CoreDNS: listen on port 53, handle queries for cluster.local, forward everything else to the node’s upstream DNS (e.g., 8.8.8.8 or corporate DNS), and cache results for 30 seconds.

The pod’s /etc/resolv.conf

Every pod gets an automatically generated /etc/resolv.conf. It looks like:

nameserver 10.96.0.10
search <namespace>.svc.cluster.local svc.cluster.local cluster.local
ndots: 5

The search directive is the secret sauce. It means when you type curl backend, the resolver tries:

  • backend.<namespace>.svc.cluster.local
  • backend.svc.cluster.local
  • backend.cluster.local

This is why you can use short names within the same namespace.

The ndots gotcha

ndots: 5 means a name with fewer than 5 dots is tried with the search domains first. backend has 0 dots, so the resolver tries backend.<namespace>.svc.cluster.local first. But google.com has 1 dot — it’s tried directly first (as an absolute name), which means it might resolve faster if the upstream DNS handles it.

This sometimes causes surprising behavior if your internal service name has multiple dots. Always test.

Container Platforms Beyond Kubernetes

Docker Compose

Docker Compose creates a default network where services can reach each other by service name. For example, a service named web can reach db:5432. Docker’s embedded DNS resolver handles this, and it’s scoped to the Compose project’s network.

It’s simpler than Kubernetes but has no automatic scaling or API-driven updates.

Nomad / Consul

HashiCorp’s Nomad + Consul integration uses Consul DNS. Services register themselves, and Consul responds to .consul domain queries. It’s more manual than Kubernetes but gives you service mesh capabilities.

It uses a similar pattern:

  • Each task gets a DNS resolver pointing to Consul agent (e.g., 127.0.0.1:8600).
  • Consul DNS returns IPs of healthy service instances.

Mesos / Marathon (legacy)

Mesos used Mesos-DNS, which ran as a separate service and polled the Mesos master for task information. It was slower and less reliable than CoreDNS — one reason Kubernetes gained popularity.

Common Pitfalls and Debugging

DNS doesn’t work in a pod? Start here:

  1. Check kubectl exec <pod> -- cat /etc/resolv.conf
  2. Verify CoreDNS is running: kubectl get pods -n kube-system | grep coredns
  3. Test from inside a pod: kubectl run test --image=busybox --rm -it -- nslookup kubernetes.default
  4. Check CoreDNS logs for errors (often the ConfigMap syntax is wrong)
  5. Confirm your dnsPolicy in the pod spec — if it’s None, you need to define custom DNS settings

Timeouts or slow lookups? Check:

  • Network policies blocking UDP port 53
  • CoreDNS resource limits too low (CPU/memory)
  • Upstream DNS server being slow (use forward . 8.8.8.8 or 1.1.1.1 as fallback)
  • Cache TTL set too high — ttl 30 is good for dynamic environments

Why This Matters for Platform Engineers

Understanding cluster DNS isn’t just about fixing nslookup failures. It affects:

  • Service discovery latency — bad DNS config can add 200ms+ to every request
  • Stateful workload reliability — broken DNS means database clusters fail to find each other
  • Security — DNS can leak internal service names or be used for data exfiltration if misconfigured
  • Multi-cluster communication — you’ll need DNS federation or external DNS for services spanning clusters

The Kubernetes DNS documentation is excellent, but the real learning comes from debugging production. Next time a pod can’t reach redis, check CoreDNS first — it usually solves the mystery.

Comments

Questions, corrections, and tips stay visible for everyone reading this page.

0 in thread

Join the discussion

Shown next to your comment.

Up to 4,000 characters

No comments yet

Be the first to leave a note — it helps the next reader.