Stage 5 · Platform
Networking, Storage & Service Mesh
CoreDNS & Service Discovery
Cluster DNS, stub domains, and custom DNS policies.
Cluster DNS Overview
CoreDNS is the default DNS server for Kubernetes. It provides name resolution for Services and Pods within the cluster. Every Service gets a DNS record: service-name.namespace.svc.cluster.local. This enables service discovery without hardcoded IPs.
# Service DNS record
<service-name>.<namespace>.svc.cluster.local
# Examples
api-service.production.svc.cluster.local
database.default.svc.cluster.local
# Pod DNS record (if pod policy allows)
<pod-ip-dashed>.<namespace>.pod.cluster.local
# 10-242-0-5.production.pod.cluster.localCoreDNS resolves these records to ClusterIPs or Pod IPs. Pods use the cluster DNS by default. The search path allows short names: pods in the same namespace can use just the service name.
CoreDNS Configuration
CoreDNS is configured via a ConfigMap. The configuration file (Corefile) defines plugins for DNS resolution, caching, forwarding, and health checking. Custom plugins can extend CoreDNS with additional functionality.
apiVersion: v1
kind: ConfigMap
metadata:
name: coredns
namespace: kube-system
data:
Corefile: |
.:53 {
errors
health {
lameduck 5s
}
ready
kubernetes cluster.local in-addr.arpa ip6.arpa {
pods insecure
fallthrough in-addr.arpa ip6.arpa
ttl 30
}
prometheus :9153
forward . /etc/resolv.conf {
max_concurrent 1000
}
cache 30
loop
reload
loadbalance
}
example.com:53 {
errors
cache 30
forward . 10.0.0.53
}The first block handles cluster DNS. kubernetes plugin serves cluster records. forward plugin forwards external DNS to upstream (usually cloud DNS). The second block forwards example.com queries to a custom DNS server.
DNS Record Types
CoreDNS creates different record types for different resources. A records map names to ClusterIPs. SRV records provide port information. PTR records enable reverse lookups. ExternalName records alias external services.
apiVersion: v1
kind: Service
metadata:
name: external-db
namespace: production
spec:
type: ExternalName
externalName: db.example.com
# Returns CNAME record pointing to db.example.com
---
# Headless Service — returns individual pod IPs
apiVersion: v1
kind: Service
metadata:
name: kafka-brokers
spec:
clusterIP: None # Headless
selector:
app: kafka
ports:
- port: 9092ExternalName creates a CNAME record. Clients resolve kafka-brokers.default.svc.cluster.local to individual pod IPs. Headless services are used for StatefulSets where you need direct pod access.
Headless services (clusterIP: None) return individual pod IPs instead of a VIP. StatefulSets use headless services to give each pod a unique DNS record: pod-name.service-name.namespace.svc.cluster.local.
Stub Domains
Stub domains let you forward specific domains to external DNS servers. This is useful for corporate DNS, split-horizon DNS, or private zones. Queries for non-stub domains use the default upstream DNS.
apiVersion: v1
kind: ConfigMap
metadata:
name: coredns
namespace: kube-system
data:
Corefile: |
.:53 {
errors
kubernetes cluster.local in-addr.arpa ip6.arpa {
pods insecure
fallthrough in-addr.arpa ip6.arpa
}
forward . /etc/resolv.conf
cache 30
}
corp.internal:53 {
errors
cache 30
forward . 10.0.0.53 10.0.0.54 # Internal DNS servers
}
azure.internal:53 {
errors
cache 30
forward . 168.63.129.16 # Azure DNS
}Queries for corp.internal go to internal DNS. Queries for azure.internal go to Azure DNS. Everything else goes to the default upstream DNS. This enables split-horizon DNS within the cluster.
DNS Policies
DNS policy controls how pods resolve DNS. ClusterFirst (default) uses cluster DNS with fallback to upstream. Default uses the node's DNS. None lets you specify custom DNS settings entirely.
apiVersion: v1
kind: Pod
metadata:
name: custom-dns-pod
spec:
dnsPolicy: None
dnsConfig:
nameservers:
- 8.8.8.8
- 8.8.4.4
searches:
- example.com
options:
- name: ndots
value: "2"
- name: timeout
value: "3"
containers:
- name: app
image: my-app:1.0dnsPolicy: None uses only the dnsConfig you specify. dnsConfig is merged with the base DNS config. ndots controls how many dots in a name trigger search path resolution. Lower ndots = fewer search path lookups = faster resolution.
DNS Debugging
# Test DNS resolution
kubectl run dns-test --image=busybox:1.36 --rm -it -- nslookup api-service
# Check CoreDNS pods
kubectl get pods -n kube-system -l k8s-app=kube-dns
# Check CoreDNS config
kubectl get configmap coredns -n kube-system -o yaml
# Test from a specific pod
kubectl exec -it my-pod -- cat /etc/resolv.conf
kubectl exec -it my-pod -- nslookup api-service.default.svc.cluster.local
# Check CoreDNS logs for errors
kubectl logs -n kube-system -l k8s-app=kube-dns --tail=50DNS issues are common in Kubernetes. Always check: 1) CoreDNS pods are running, 2) /etc/resolv.conf points to the right DNS server, 3) The service name is correct, 4) Network policies don't block DNS traffic.
Set ndots:5 (default) for general use. For pods that mostly access external services, set ndots:2 to reduce search path iterations. Use dnsConfig to override per-pod. CoreDNS cache TTL of 30s balances freshness and performance.
Mark this lesson complete to store local progress and unlock a cleaner resume path the next time you visit.