Skip to main content

CoreDNS

The default DNS server in Kubernetes that runs as a Deployment inside the cluster, resolving service names to ClusterIP addresses and enabling pods to discover and communicate with each other using human-readable DNS names instead of raw IP addresses.

CoreDNS - The Phone Book of Your Kubernetes Cluster

What is CoreDNS in Simple Terms?

Without CoreDNS, your pods would need to hardcode IP addresses to talk to each other — and pod IPs change every time a pod restarts. CoreDNS is the phone book of your cluster: you call orders-service and CoreDNS looks up its current IP and routes you there automatically.

How DNS Resolution Works Step by Step

◈ DIAGRAM
+--------------------------------------------------+
| Pod calls: orders-service.production.svc.cluster.local | <- Step 1: DNS query
+--------------------------------------------------+
|
v
+--------------------------------------------------+
| Pod's /etc/resolv.conf points to CoreDNS | <- Step 2: Resolver config
| nameserver 10.96.0.10 (CoreDNS ClusterIP) |
+--------------------------------------------------+
|
v
+--------------------------------------------------+
| CoreDNS receives query, looks up Service in etcd | <- Step 3: Lookup
+--------------------------------------------------+
|
v
+--------------------------------------------------+
| CoreDNS returns ClusterIP: 10.96.45.200 | <- Step 4: Response
+--------------------------------------------------+
|
v
+--------------------------------------------------+
| kube-proxy routes traffic to a healthy pod | <- Step 5: Delivery
+--------------------------------------------------+

Kubernetes DNS Name Format

Bash
# Full DNS name format for any Service
<service-name>.<namespace>.svc.cluster.local
# Production examples
payments-service.production.svc.cluster.local
redis.cache.svc.cluster.local
postgres-0.postgres.production.svc.cluster.local # StatefulSet pod DNS
# Short names also work within the same namespace
# From inside the production namespace:
curl http://payments-service:4000/health # works
curl http://payments-service.production:4000/health # works
curl http://payments-service.production.svc.cluster.local:4000/health # always works

CoreDNS Architecture Inside the Cluster

◈ DIAGRAM
+-------------------------------+ +-------------------------------+
| kube-system ns | | production ns |
| | | |
| coredns pod 1 (10.244.0.5) | | payments-api pod |
| coredns pod 2 (10.244.0.6) | <------> | /etc/resolv.conf: |
| | | nameserver 10.96.0.10 |
| CoreDNS Service | | search production.svc... |
| ClusterIP: 10.96.0.10 | | |
+-------------------------------+ +-------------------------------+

CoreDNS runs as 2 replicas by default for HA. All pods in the cluster are configured at creation time to point to the CoreDNS ClusterIP for DNS resolution.

CoreDNS Configuration (Corefile)

Bash
# View the active CoreDNS config
kubectl get configmap coredns -n kube-system -o yaml
YAML
# Default Corefile inside the ConfigMap
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 # Metrics endpoint for Grafana/Prometheus
forward . /etc/resolv.conf # Forwards external DNS queries upstream
cache 30
loop
reload
loadbalance
}

Debugging CoreDNS Issues

Bash
# Check CoreDNS pods are running and healthy
kubectl get pods -n kube-system -l k8s-app=kube-dns
# Check CoreDNS logs for query failures or errors
kubectl logs -n kube-system -l k8s-app=kube-dns --tail=50
# Run a debug pod with full DNS tools
kubectl run dns-debug --image=busybox:1.35 -it --rm -n production -- sh
# Inside the debug pod — test resolution
nslookup payments-service.production.svc.cluster.local
nslookup kubernetes.default.svc.cluster.local
# Test cross-namespace resolution
nslookup redis.cache.svc.cluster.local
# Check what DNS config a pod received
kubectl exec -it <pod-name> -n production -- cat /etc/resolv.conf

Troubleshooting CoreDNS Issues

Symptom Likely Cause Fix
nslookup times out inside pod CoreDNS pods not running kubectl get pods -n kube-system — check coredns pods
Short name works, FQDN fails Search domain misconfigured Check /etc/resolv.conf inside the pod
Cross-namespace call fails Using short name instead of FQDN Use service.namespace.svc.cluster.local
DNS works for some pods, not others CoreDNS overloaded Scale CoreDNS replicas up
External DNS not resolving Upstream forwarder misconfigured Check forward directive in Corefile
Bash
# Scale CoreDNS for high-traffic clusters (Hotstar/Swiggy scale)
kubectl scale deployment coredns --replicas=4 -n kube-system
# Restart CoreDNS if config was updated
kubectl rollout restart deployment/coredns -n kube-system
# Watch CoreDNS pod status during restart
kubectl rollout status deployment/coredns -n kube-system
Common Mistake

Using short service names for cross-namespace calls. orders-service resolves correctly only from within the same namespace. From a different namespace, it silently fails or hits the wrong service. Always use the full FQDN orders-service.production.svc.cluster.local for cross-namespace communication — especially critical in Swiggy or Razorpay-scale microservice environments with 50+ namespaces.

Tip

If pods cannot resolve DNS, check CoreDNS logs first with kubectl logs -n kube-system -l k8s-app=kube-dns. DNS failures are one of the most common root causes of mysterious service connectivity issues in Kubernetes — they look like network errors but are actually name resolution failures.

Remember

CoreDNS is itself a Kubernetes Service with a ClusterIP (default 10.96.0.10). Every pod's /etc/resolv.conf is automatically configured by kubelet to point to this address at creation time. If CoreDNS goes down, the entire cluster's service discovery breaks — treat it as a critical infrastructure component, not just another deployment.

Security

CoreDNS can be configured to block internal DNS queries to prevent pods from discovering services they shouldn't. In multi-tenant clusters at PhonePe or CRED, use CoreDNS policy plugins combined with NetworkPolicy to restrict which namespaces can resolve which service names.

Frequently Asked Questions

What actually breaks if CoreDNS goes down in a cluster?

Every pod-to-pod communication that relies on a Kubernetes service DNS name (like `my-service.namespace.svc.cluster.local`) stops resolving — applications hardcoded to use IPs are unaffected, but that's rare in practice. Since CoreDNS itself runs as a Deployment inside the cluster it serves, a misconfigured resource limit or a bad rollout of CoreDNS can cause a cascading cluster-wide outage, which is why it typically runs with multiple replicas and its own PodDisruptionBudget.

What's a common CoreDNS performance issue teams hit at scale?

DNS query latency or timeouts under high request volume, often traced back to the default `ndots:5` setting in pod resolv.conf, which causes many unnecessary search-domain lookup attempts before resolving an external domain — a single external DNS lookup can multiply into 5 queries. Mitigations include tuning ndots per-pod, using fully-qualified domain names with a trailing dot to skip the search list, or scaling CoreDNS replicas and enabling its caching plugin more aggressively.