DNS in Kubernetes
Instead of IP addresses, Kubernetes DNS uses DNS-based service discovery to connect Pods and Services by name. In a dynamic Kubernetes cluster, pods change IP addresses when added, removed, or moved. Kubernetes DNS centralizes a service registry to automatically transform stable Service names to Cluster IPs.
You can also read What is Ingress in Kubernetes for Beginners?
Core Architecture and Implementation
Since 1.13, Go-based authoritative DNS server CoreDNS has replaced Kube-DNS as Kubernetes’ primary DNS provider. High-availability replication occurs under the kube-system namespace.
Services that front CoreDNS Pods use 10.96.0.10 as their static internal IP address. Kubernetes fills /etc/resolv.conf with this IP to configure each cluster container for name resolution.
The Corefile Configuration
The Corefile, a configuration file kept in a Kubernetes ConfigMap, defines the behavior of CoreDNS. Administrators can enable different plugins for faults, health checks, and specific Kubernetes service discovery with this modular configuration.
Example Corefile ConfigMap:
apiVersion: v1
kind: ConfigMap
metadata:
name: coredns
namespace: kube-system
data:
Corefile: |
.:53 {
errors # Logs any errors
health { # Health check endpoint
lameduck 5s
}
ready # Signals readiness on port 8181
kubernetes cluster.local in-addr.arpa ip6.arpa { # Main K8s plugin
pods insecure
fallthrough in-addr.arpa ip6.arpa
ttl 30
}
prometheus :9153 # Exposes metrics for Prometheus
forward . /etc/resolv.conf # Forwards non-cluster queries to upstream
cache 30 # Enables a frontend cache
loop # Detects and prevents DNS loops
reload # Automatically reloads ConfigMap changes
loadbalance # Round-robin DNS loadbalancer
}
DNS Naming Conventions
A unique DNS record is assigned to each Service and Pod in Kubernetes. The default domain of the cluster, usually cluster.local, is a subdomain of all Kubernetes DNS names.
Service Records
The standard format for a Service’s Fully Qualified Domain Name (FQDN) is: <service-name>.<namespace>.svc.cluster.local.
- Service Name: The name assigned to the Service object (e.g.,
my-database). - Namespace: The logical partition where the service resides (e.g.,
prod). - svc: A constant string identifying the resource as a Service.
- cluster.local: The default base domain for the cluster.
For example, a service named alpaca-prod in the default namespace resolves to alpaca-prod.default.svc.cluster.local.
Pod Records
Pods are also assigned DNS names, typically in the format: <pod-ip-address>.<namespace>.pod.cluster.local.
For a Pod with IP 172.17.0.3 in the default namespace, the name would be 172-17-0-3.default.pod.cluster.local.
You can also read What is Kube-Proxy in Kubernetes and it’s Lifecycle
DNS Records for Different Service Types
- Standard Services (ClusterIP): The stable Cluster IP of the Service is where they resolve.
- Headless Services: Specified in the Service specification by setting
clusterIP: None. A DNS query for a headless service delivers the distinct IP addresses of each Pod that the service has chosen, rather than a single load-balancing IP. - ExternalName Services: A DNS alias is what they do. The cluster DNS returns a CNAME record that points to an external domain (such as
my-db.external.com) when a Pod searches for an ExternalName Service.
Example: Headless Service for Stateful Pods For stateful applications like databases, Pods often need stable network identities.
apiVersion: v1
kind: Service
metadata:
name: mongo
spec:
clusterIP: None # Defines a headless service
selector:
app: mongodb
ports:
- port: 27017
---
apiVersion: v1
kind: Pod
metadata:
name: mongo-0
spec:
hostname: mongo-0 # Explicit hostname
subdomain: mongo # Matches headless service name
containers:
- name: mongo
image: mongo
In this scenario, the Pod will have a stable FQDN of mongo-0.mongo.default.svc.cluster.local.
Customizing Pod DNS Settings
The dnsPolicy and dnsConfig fields in Kubernetes let you alter DNS behavior per-Pod.
dnsPolicy Options
- ClusterFirst (Default): Upstream nameservers receive any DNS queries that do not match the cluster domain. (Note: Despite not being named “Default,” this is the default.
- Default: By default, the name resolution setting is inherited by the Pod from the Node on which it operates.
- None: The Pod requires dnsConfig; it completely disregards Kubernetes DNS settings.
- ClusterFirstWithHostNet: Used to make sure Pods running with hostNetwork: true can still resolve cluster names.
dnsConfig for Granular Control
Nameservers, search domains, and merge-with-default parameters can all be manually specified.
Example: Pod with Custom DNS Config
apiVersion: v1
kind: Pod
metadata:
name: custom-dns-pod
spec:
containers:
- name: test
image: busybox
dnsPolicy: "None" # Ignores cluster defaults
dnsConfig:
nameservers:
- 1.1.1.1 # External DNS
searches:
- my-custom-domain.com # Custom search path
options:
- name: ndots
value: "2" # Custom resolver option
You can also read Kubernetes Controller Manager vs Cloud Controller Manager
Scope Resolution and Namespaces
Namespaces provide a way to partition the DNS address space. This allows teams to run parallel environments (like dev and prod) on the same cluster using the same service names without conflict.
- A Pod in the
devnamespace looking for a service namedentwill resolve toent.dev.svc.cluster.local. - To reach the same service in the
prodnamespace, the Pod must use the FQDN:ent.prod.svc.cluster.local
Troubleshooting Kubernetes DNS
The following steps are used to diagnose name resolving issues:
- Check CoreDNS Status: Ensure the CoreDNS Pods are running and healthy in the
kube-systemnamespace.- Command:
kubectl get pods -n kube-system -l k8s-app=kube-dns.
- Command:
- Verify the kube-dns Service: Ensure the Service exists and has a Cluster IP.
- Inspect resolv.conf: Check the configuration inside a running Pod to ensure it points to the correct nameserver IP.
- Command:
kubectl exec <pod-name> -- cat /etc/resolv.conf.
- Command:
- Use nslookup for Testing: Run a test query from within a Pod to see if resolution works.
- Example:
nslookup kubernetes.defaultshould resolve to the API server IP.
- Example:
- Check CoreDNS Logs: Look for error messages that might indicate permission issues or upstream forwarding failures.
- Command:
kubectl logs -n kube-system -l k8s-app=kube-dns.
- Command:
Kubernetes DNS automates complex networking protocols, allowing programmers to build scalable, reliable applications with uniform naming conventions.
You can also read What is Kubernetes Cloud Controller Manager?
