Kubernetes DNS: Why FQDNs Matter
TL;DR
In Kubernetes, the ndots:5 setting causes DNS queries for names with fewer than 5 dots to iterate through all search domains. This means using service name like api triggers 4 DNS queries instead of 1. Using a trailing dot FQDN api.app.svc.cluster.local. forces absolute resolution, reducing DNS load by 75%.
How Kubernetes DNS Works
DNS Configuration in Pods
Every pod gets a /etc/resolv.conf file with CoreDNS settings:
kubectl exec <pod-name> -- cat /etc/resolv.conf
nameserver 192.168.194.138
search default.svc.cluster.local svc.cluster.local cluster.local
options ndots:5
Three critical components:
- nameserver — CoreDNS service IP
- search — DNS search domains appended to incomplete hostnames
- ndots:5 — Names with fewer than 5 dots are treated as relative
Understanding ndots: The Key to DNS Performance
The ndots:5 setting determines how the resolver treats domain names:
How it works:
- Resolver counts the dots in the hostname
- If dots < 5 → treat as relative name → try appending each search domain
- If dots ≥ 5 → treat as absolute name → query directly
- If trailing dot (
.) present → always absolute → query directly
Why api.app.svc.cluster.local (4 dots) is problematic:
- 4 dots < 5 (ndots threshold)
- Resolver treats it as relative
- Appends search domains:
api.app.svc.cluster.local.default.svc.cluster.local, thenapi.app.svc.cluster.local.svc.cluster.local, etc. - Finally tries absolute:
api.app.svc.cluster.local - Result: 4 queries instead of 1
Solution: Add trailing dot → api.app.svc.cluster.local.
- Trailing dot signals “this is absolute”
- Resolver skips search domain iteration
- Result: 1 query
Performance Impact
| Query Type | Example | DNS Queries |
|---|---|---|
| Short name | api | 1-4 |
| FQDN no dot | api.app.svc.cluster.local | 4 |
| FQDN with dot | api.app.svc.cluster.local. | 1 |
For a service handling 1000 requests/second:
- Without trailing dot: 4000 DNS queries/sec
- With trailing dot: 1000 DNS queries/sec
75% reduction in DNS load, resulting in lower latency, reduced CoreDNS CPU/memory, and better cluster performance.
CoreDNS Architecture: A Centralized Bottleneck
CoreDNS runs as a Deployment, not a DaemonSet.
kubectl get deployment coredns -n kube-system
NAME READY UP-TO-DATE AVAILABLE
coredns 2/2 2 2
Typical default: 2 replicas for the entire cluster.
Consequences:
Cross-node network traffic — Most pods query CoreDNS pods on different nodes, consuming inter-node bandwidth
Suggestions
- Always use trailing dots —
api.app.svc.cluster.local.for 1 query - Deploy NodeLocal DNSCache — Eliminate cross-node DNS traffic
- Scale CoreDNS appropriately — More replicas for larger clusters
- Consider lowering ndots — Set to 2-3 for internal-only services
References
- Kubernetes Authors. (n.d.). DNS for services and pods [Documentation].
- Kubernetes Authors. (n.d.). Using NodeLocal DNSCache in Kubernetes clusters [Documentation].
- Pracucci, M. (n.d.). Kubernetes DNS resolution: ndots options and why it may affect application performances.