In Kubernetes, DNS is the backbone of service discovery. Every time a pod needs to communicate with another service, whether internal or external, it makes a DNS request. But did you know that in high-traffic environments, your CoreDNS service might be silently struggling?
Let’s dive into a common performance bottleneck and how you can fix it with a powerful Kubernetes feature: NodeLocal DNS Cache.
By default, each pod in a Kubernetes cluster sends DNS queries to a centralized CoreDNS service, typically running as a set of pods in the kube-system namespace.
This setup works well in smaller clusters. But as your workload scales, it begins to show cracks:
All pods use the network to resolve DNS queries.
Every DNS lookup creates traffic between the pod and CoreDNS.
If CoreDNS gets overloaded, your entire app stack could slow down or break.
You might face symptoms like:
Slow pod startup
️Intermittent DNS resolution failures
Increased CoreDNS restarts
Drop in cluster-wide performance
In short, your cluster becomes fragile under pressure — just because of DNS.
NodeLocal DNSCache is a clever solution that dramatically reduces DNS latency and increases resilience.
Here’s how it works:
Instead of sending DNS queries from each pod over the network to CoreDNS, a DNS caching agent is deployed on every node. This local DNS proxy caches recent responses and resolves them without leaving the node. Only cache misses are forwarded to CoreDNS.
Reduces DNS latency (responses in microseconds instead of milliseconds)
Decreases network traffic to CoreDNS
Offloads CoreDNS, preventing overloads and crash loops
Enhances cluster resilience during CoreDNS restarts or upgrades
Speeds up pod start times, especially for service-heavy apps
This is particularly useful for:
Large-scale clusters with thousands of pods
CI/CD pipelines where pods spin up/down frequently
Stateful applications sensitive to DNS failures
Multi-tenant environments where traffic spikes are unpredictable
At QAPPA Labs, we recently rolled out NodeLocal DNS Cache in one of our production-grade clusters running hundreds of microservices.
Here’s what we observed post-deployment:
Pod start time reduced by 20–30% on average
CoreDNS CPU usage dropped by 45%
Fewer DNS-related errors during deployment bursts
Better performance for time-sensitive services and batch jobs
It was a clear win with minimal configuration effort.
You can deploy NodeLocal DNSCache manually or via Helm. Here’s a quick guide for Helm users:
Step 1: Add the Helm repo
helm repo add k8s-nodelocaldns-helm https://lnkd.in/gF-Pipmn
Step 2: Install the chart
helm install node-local-dns k8s-nodelocaldns-helm/node-local-dns
Make sure your Helm values match your cluster networking setup. You’ll typically set parameters like:
dnsServer (IP used by NodeLocal DNS)
upstreamNameservers (CoreDNS or external resolvers)
enablePprof for profiling
You can also configure this natively using the Kubernetes official setup.
kubectl get pods -n kube-system -l k8s-app=node-local-dns
Then check logs and metrics using:
kubectl logs -n kube-system <node-local-dns-pod-name>
Make sure your pods are resolving DNS via the local proxy. You can test DNS resolution speed with tools like dig or nslookup.
Monitor CoreDNS and NodeLocal DNS pods to ensure they are healthy.
Use readiness and liveness probes to track DNS failures.
Tune cache size and TTLs based on your workload’s needs.
Review DNS metrics in Prometheus/Grafana to observe improvements over time.
Test DNS failover to validate behavior during CoreDNS downtime.