CoreDNS provides Kubernetes service discovery via predictable DNS names. The default ndots:5 search path causes 5 DNS lookups per service call. At scale, this multiplies DNS traffic dramatically and introduces latency in surprising places.
Know the Kubernetes DNS naming convention (service.namespace.svc.cluster.local) and how pods resolve service names using CoreDNS.
Understand ndots and the search path. Tune CoreDNS replicas and resource limits. Use autopath plugin to reduce DNS amplification. Monitor CoreDNS latency and error rates.
Design DNS strategy for high-throughput clusters: NodeLocal DNSCache to move DNS resolution off the network, FQDN usage in service code, CoreDNS custom zones for split-horizon DNS.
CoreDNS provides Kubernetes service discovery via predictable DNS names. The default ndots:5 search path causes 5 DNS lookups per service call. At scale, this multiplies DNS traffic dramatically and introduces latency in surprising places.
Traffic scales to 50k req/s; CoreDNS hits 100% CPU on all 3 pods
DNS query latency spikes to 500ms; service-to-service latency follows
Analysis reveals 250k DNS queries/s = 5x the actual request rate
ndots:5 identified as root cause; 5 search domains tried per bare hostname
Services updated to use FQDNs; DNS traffic drops to 50k/s; CoreDNS CPU normalizes
The question this raises
What does ndots:5 actually do to DNS queries, and when does it become a performance bottleneck for high-throughput services?
A pod in namespace "payments" tries to reach a service named "auth" in namespace "identity" by calling http://auth. What happens?
Lesson outline
Predictable Names for Ephemeral IPs
Pod IPs change constantly. Service ClusterIPs are stable but numeric. CoreDNS provides human-readable, predictable DNS names for Services and Pods. It watches the Kubernetes API for Service and Endpoint changes and updates its DNS records in real-time -- no static configuration required.
Service DNS
Use for: api-service.default.svc.cluster.local resolves to the Service ClusterIP. Pods in same namespace can use short name api-service. Cross-namespace calls need the full name or namespace qualifier: api-service.other-ns.
Headless Service DNS
Use for: For StatefulSets with clusterIP: None, DNS returns individual pod IPs. kafka-0.kafka-headless.default.svc.cluster.local resolves directly to kafka-0's pod IP. Used for direct pod addressing by distributed systems.
NodeLocal DNSCache
Use for: DaemonSet running a DNS cache on every node. Pods hit 169.254.20.10 (link-local) for DNS instead of CoreDNS pods over the network. Eliminates network latency for DNS. Reduces CoreDNS load by 90% on busy clusters.
Pod /etc/resolv.conf: nameserver 10.96.0.10 <- CoreDNS ClusterIP search default.svc.cluster.local svc.cluster.local cluster.local options ndots:5 Call: http://api-service (has 0 dots < ndots:5) Query 1: api-service.default.svc.cluster.local -> HIT (ClusterIP returned) [Queries 2-5 skipped because query 1 hit] Call: http://api.external.com (has 2 dots < ndots:5) Query 1: api.external.com.default.svc.cluster.local -> MISS Query 2: api.external.com.svc.cluster.local -> MISS Query 3: api.external.com.cluster.local -> MISS Query 4: api.external.com.ec2.internal -> MISS Query 5: api.external.com. -> HIT (external DNS) 5 queries for every external hostname! Fix: use FQDN with trailing dot http://api-service.default.svc.cluster.local. <- 1 query, no search OR: reduce ndots: 2 in pod dnsConfig
ndots:5 causes up to 5 sequential DNS queries per lookup for short names; FQDNs with trailing dot skip the search path entirely
DNS Optimization Strategies
50k req/s cluster with default ndots:5 and short service names
“250k DNS queries/s; CoreDNS at 100% CPU; 500ms DNS latency; all service calls delayed”
“Services use FQDNs; NodeLocal DNSCache deployed; DNS traffic drops 5x to 50k/s; latency sub-millisecond”
Cross-namespace service call using short name
“http://auth fails or hits wrong service -- search path adds caller's namespace, not target namespace”
“http://auth.identity.svc.cluster.local -- explicit namespace in DNS name; always resolves correctly”
DNS resolution chain for a service call
01
1. App calls http://api-service; OS queries /etc/resolv.conf nameserver (CoreDNS or NodeLocal cache)
02
2. CoreDNS receives query; checks kubernetes plugin (watches Service/Endpoint objects)
03
3. Match found for api-service.default.svc.cluster.local; returns ClusterIP (e.g., 10.96.100.1)
04
4. OS returns ClusterIP to application; HTTP client connects to 10.96.100.1
05
5. kube-proxy iptables DNATs 10.96.100.1 to a ready pod IP
06
6. Request reaches pod; response returns along the same path
1. App calls http://api-service; OS queries /etc/resolv.conf nameserver (CoreDNS or NodeLocal cache)
2. CoreDNS receives query; checks kubernetes plugin (watches Service/Endpoint objects)
3. Match found for api-service.default.svc.cluster.local; returns ClusterIP (e.g., 10.96.100.1)
4. OS returns ClusterIP to application; HTTP client connects to 10.96.100.1
5. kube-proxy iptables DNATs 10.96.100.1 to a ready pod IP
6. Request reaches pod; response returns along the same path
1spec:2dnsConfig:3options:4- name: ndotsndots: 2 -- only try search domains if hostname has fewer than 2 dots; reduces amplification5value: "2" # reduce from 5 to 2 -- fewer search domain attempts6- name: single-request-reopen7value: "" # avoid parallel A/AAAA query race condition8containers:9- name: app10env:11- name: API_URL12# Use FQDN with namespace for cross-namespace callsAlways use FQDN for cross-namespace service URLs -- prevents namespace resolution ambiguity13value: "http://auth-service.identity.svc.cluster.local"
DNS failure modes
Cross-namespace call using short service name resolves to wrong namespace
# Pod in namespace: payments
# Trying to call auth service in namespace: identity
env:
- name: AUTH_SERVICE_URL
value: "http://auth-service:8080"
# Resolves: auth-service.payments.svc.cluster.local
# If no auth-service in 'payments': NXDOMAIN -> connection error
# If there IS an auth-service in 'payments': hits WRONG service!# Always use FQDN for cross-namespace service calls
env:
- name: AUTH_SERVICE_URL
value: "http://auth-service.identity.svc.cluster.local:8080"
# Explicit namespace: always resolves to the right service
# Works from any namespace regardless of caller's DNS search pathDNS search domains are scoped to the pod's namespace. Cross-namespace service calls must use the full DNS name including the target namespace. Short names only work reliably within the same namespace.
| Configuration | DNS queries per request | CoreDNS load | Latency | Complexity |
|---|---|---|---|---|
| Default (ndots:5, short names) | 1-5 per lookup | High at scale | 5-50ms (network round-trip) | None |
| FQDNs + ndots:2 | 1 per lookup | Low | 5-10ms (network round-trip) | Low (URL naming discipline) |
| NodeLocal DNSCache | 1 per lookup (cached) | Very low | <1ms (node-local) | Medium (DaemonSet deploy) |
| NodeLocal + FQDNs + ndots:2 | 1 per lookup (cached) | Minimal | <1ms | Medium |
Kubernetes DNS naming scheme
📖 What the exam expects
Services: <service>.<namespace>.svc.cluster.local. Pods: <pod-ip-dashed>.<namespace>.pod.cluster.local. Short names (service) only resolve within the same namespace using search domains.
Toggle between what certifications teach and what production actually requires
Performance debugging questions about DNS latency and architecture questions about service discovery at scale.
Common questions:
Strong answer: Mentions NodeLocal DNSCache for high-throughput clusters, reducing ndots in pod dnsConfig, and monitoring CoreDNS with coredns_dns_request_duration_seconds histogram.
Red flags: Not knowing that cross-namespace service calls require the full DNS name, or not being aware of the ndots amplification effect.
Related concepts
Explore topics that connect to this one.
Ready to see how this works in the cloud?
Switch to Career Paths for structured paths (e.g. Developer, DevOps) and provider-specific lessons.
View role-based pathsSign in to track your progress and mark lessons complete.
Questions? Discuss in the community or start a thread below.
Join DiscordSign in to start or join a thread.