Kubernetes DNS Policy ClusterFirstWithHostNet
Configure Kubernetes DNS policies: ClusterFirst, ClusterFirstWithHostNet, Default, and None. Fix DNS resolution for hostNetwork pods and custom nameservers.
π‘ Quick Answer: Use
dnsPolicy: ClusterFirstWithHostNetwhen your pod useshostNetwork: truebut still needs to resolve cluster services (e.g.,myservice.namespace.svc.cluster.local). Without it, hostNetwork pods use the nodeβs/etc/resolv.confand canβt find cluster DNS.
The Problem
When a pod uses hostNetwork: true:
- It gets the nodeβs
/etc/resolv.confinstead of the cluster DNS - Service names like
postgres.default.svc.cluster.localfail to resolve - The pod can reach external DNS but not internal Kubernetes services
This breaks DaemonSets (monitoring agents, log collectors) that need both host networking and cluster service access.
The Solution
DNS Policy Options
apiVersion: v1
kind: Pod
metadata:
name: example
spec:
# Choose one:
dnsPolicy: ClusterFirst # Default β uses cluster DNS (CoreDNS)
dnsPolicy: ClusterFirstWithHostNet # For hostNetwork pods needing cluster DNS
dnsPolicy: Default # Uses node's /etc/resolv.conf
dnsPolicy: None # Custom β must provide dnsConfigClusterFirstWithHostNet (The Fix)
apiVersion: apps/v1
kind: DaemonSet
metadata:
name: monitoring-agent
spec:
template:
spec:
hostNetwork: true
dnsPolicy: ClusterFirstWithHostNet # β This is the fix
containers:
- name: agent
image: monitoring-agent:1.0.0
# Can now resolve both:
# - external: google.com β
# - cluster: prometheus.monitoring.svc.cluster.local βHow Each Policy Resolves DNS
graph TD
A[Pod DNS Query] --> B{dnsPolicy}
B -->|ClusterFirst| C[CoreDNS 10.43.0.10]
C --> D{Cluster domain?}
D -->|Yes .svc.cluster.local| E[Resolve internally]
D -->|No| F[Forward to upstream]
B -->|ClusterFirstWithHostNet| G[CoreDNS 10.43.0.10]
G --> D
B -->|Default| H[Node /etc/resolv.conf]
H --> I[Node's configured DNS]
B -->|None| J[Pod dnsConfig only]
J --> K[Custom nameservers]Check Current DNS Configuration
# See what resolv.conf the pod actually uses
kubectl exec myapp-pod -- cat /etc/resolv.conf
# For ClusterFirst:
# nameserver 10.43.0.10
# search default.svc.cluster.local svc.cluster.local cluster.local
# options ndots:5
# For Default (hostNetwork without fix):
# nameserver 8.8.8.8
# search hetzner.cloud
# (no cluster.local β can't resolve services!)Custom DNS with dnsPolicy: None
apiVersion: v1
kind: Pod
metadata:
name: custom-dns
spec:
dnsPolicy: None
dnsConfig:
nameservers:
- 10.43.0.10 # Cluster DNS
- 1.1.1.1 # Cloudflare fallback
searches:
- default.svc.cluster.local
- svc.cluster.local
- cluster.local
- example.com # Custom search domain
options:
- name: ndots
value: "3" # Reduce DNS queries (default 5 is often too high)
- name: timeout
value: "2"
- name: attempts
value: "3"ndots Optimization
# Default ndots:5 means any name with < 5 dots gets search domains appended
# "postgres" β tries postgres.default.svc.cluster.local, postgres.svc.cluster.local, etc.
# Reducing ndots:2 means FQDNs (external.api.com) resolve faster
spec:
dnsConfig:
options:
- name: ndots
value: "2"Common Issues
| Issue | Cause | Fix |
|---|---|---|
| hostNetwork pod canβt resolve services | Using dnsPolicy: Default implicitly | Set dnsPolicy: ClusterFirstWithHostNet |
| Slow DNS resolution | ndots:5 causes extra lookups | Lower to ndots:2 or use FQDN with trailing dot |
| DNS timeout | CoreDNS pod not running | Check kubectl get pods -n kube-system -l k8s-app=kube-dns |
| Wrong search domain | Incorrect namespace in resolv.conf | Verify pod namespace matches expected searches |
| External DNS fails | CoreDNS upstream not configured | Check CoreDNS Corefile upstream block |
Best Practices
- Always set
ClusterFirstWithHostNetfor hostNetwork pods β donβt rely on default - Lower ndots to 2-3 for external-heavy workloads β reduces DNS query volume by 3-4Γ
- Use FQDN with trailing dot for external names β
api.example.com.skips search domains - Monitor CoreDNS metrics β
coredns_dns_requests_totalandcoredns_dns_responses_total - Use
dnsPolicy: Nonesparingly β only for split-horizon or multi-cluster DNS
Key Takeaways
ClusterFirstis the default β resolves cluster services via CoreDNSClusterFirstWithHostNet= ClusterFirst forhostNetwork: truepods (must be explicit)Defaultuses node DNS β no cluster service resolutionNone+dnsConfiggives full control β useful for custom DNS architecturesndots:5is the default and causes 4 extra DNS queries per external lookup β optimize for latency-sensitive apps

Recommended
Kubernetes Recipes β The Complete Book100+ production-ready patterns with detailed explanations, best practices, and copy-paste YAML. Everything in one place.
Get the Book βLearn by Doing
CopyPasteLearn β Hands-on Cloud & DevOps CoursesMaster Kubernetes, Ansible, Terraform, and MLOps with interactive, copy-paste-run lessons. Start free.
Browse Courses βπ Deepen Your Skills β Hands-on Courses
Courses by CopyPasteLearn.com β Learn IT by Doing
