What DNS Records Does a Headless Service Create?
A Headless Service (clusterIP: None) creates DNS A records that return individual Pod IPs instead of a single ClusterIP. For StatefulSets, it also creates per-Pod A records in the format <pod-name>.<service-name>.<namespace>.svc.cluster.local, enabling direct Pod addressing.
Detailed Answer
A Headless Service is a Service with clusterIP: None. Instead of routing through a virtual IP, it exposes individual Pod IPs directly through DNS. This is essential for stateful workloads and peer discovery.
Regular Service vs Headless Service DNS
Regular Service (ClusterIP)
apiVersion: v1
kind: Service
metadata:
name: web
namespace: default
spec:
selector:
app: web
ports:
- port: 80
DNS lookup returns one IP (the ClusterIP):
nslookup web.default.svc.cluster.local
# Name: web.default.svc.cluster.local
# Address: 10.96.45.12 ← Single ClusterIP
Headless Service
apiVersion: v1
kind: Service
metadata:
name: web-headless
namespace: default
spec:
clusterIP: None
selector:
app: web
ports:
- port: 80
DNS lookup returns all Pod IPs:
nslookup web-headless.default.svc.cluster.local
# Name: web-headless.default.svc.cluster.local
# Address: 10.244.1.5 ← Pod 1 IP
# Address: 10.244.2.8 ← Pod 2 IP
# Address: 10.244.3.3 ← Pod 3 IP
StatefulSet Per-Pod DNS Records
When a Headless Service is used with a StatefulSet, each Pod gets its own addressable DNS record:
apiVersion: v1
kind: Service
metadata:
name: redis-headless
namespace: cache
spec:
clusterIP: None
selector:
app: redis
ports:
- port: 6379
---
apiVersion: apps/v1
kind: StatefulSet
metadata:
name: redis
namespace: cache
spec:
serviceName: "redis-headless" # Links to the Headless Service
replicas: 3
selector:
matchLabels:
app: redis
template:
metadata:
labels:
app: redis
spec:
containers:
- name: redis
image: redis:7.2
ports:
- containerPort: 6379
resources:
requests:
cpu: "250m"
memory: "256Mi"
DNS records created:
# Aggregate record (all Pods)
redis-headless.cache.svc.cluster.local → 10.244.1.5, 10.244.2.8, 10.244.3.3
# Per-Pod records (StatefulSet only)
redis-0.redis-headless.cache.svc.cluster.local → 10.244.1.5
redis-1.redis-headless.cache.svc.cluster.local → 10.244.2.8
redis-2.redis-headless.cache.svc.cluster.local → 10.244.3.3
SRV Records
Headless Services also create SRV records for service discovery:
dig SRV redis-headless.cache.svc.cluster.local
# _tcp.redis-headless.cache.svc.cluster.local. SRV 0 33 6379 redis-0.redis-headless.cache.svc.cluster.local.
# _tcp.redis-headless.cache.svc.cluster.local. SRV 0 33 6379 redis-1.redis-headless.cache.svc.cluster.local.
# _tcp.redis-headless.cache.svc.cluster.local. SRV 0 33 6379 redis-2.redis-headless.cache.svc.cluster.local.
SRV records include the port number, useful for services that use dynamic ports.
publishNotReadyAddresses
By default, only Pods with a Ready status are included in DNS. For some use cases (like peer discovery during initialization), you need unready Pods included:
apiVersion: v1
kind: Service
metadata:
name: redis-headless
spec:
clusterIP: None
publishNotReadyAddresses: true # Include not-ready Pods in DNS
selector:
app: redis
ports:
- port: 6379
This is important for StatefulSets where Pod-1 needs to find Pod-0's address even before Pod-0 passes its readiness probe (e.g., during cluster bootstrapping).
Use Cases for Headless Service DNS
| Use Case | Why Headless DNS | |---|---| | Database replication | Replicas need to find the primary by name | | Kafka brokers | Consumers need to connect to specific brokers | | etcd cluster | Members need to discover peers during bootstrap | | Elasticsearch | Nodes use DNS for cluster formation | | Client-side load balancing | gRPC clients want all endpoints to load balance themselves |
Headless Service with Deployments
Headless Services work with Deployments, but you only get the aggregate DNS record:
# Deployment Pods get random names — no per-Pod records
nslookup web-headless.default.svc.cluster.local
# Address: 10.244.1.5
# Address: 10.244.2.8
# Address: 10.244.3.3
# No per-Pod records like web-abc12.web-headless...
# Per-Pod DNS only works with StatefulSets
This is still useful for gRPC clients that need to discover all endpoints for client-side load balancing, since gRPC's long-lived connections bypass ClusterIP round-robin.
Verifying DNS Records
# From a debug Pod
kubectl run dns-test --rm -it --image=busybox -- sh
# Look up the Headless Service
nslookup redis-headless.cache.svc.cluster.local
# Look up a specific Pod
nslookup redis-0.redis-headless.cache.svc.cluster.local
# Check SRV records
nslookup -type=SRV redis-headless.cache.svc.cluster.local
Why Interviewers Ask This
Interviewers ask this to test your understanding of how DNS-based service discovery works for stateful workloads and peer-to-peer communication patterns.
Common Follow-Up Questions
Key Takeaways
- Headless Services return Pod IPs directly in DNS, enabling client-side load balancing.
- StatefulSets with Headless Services get per-Pod DNS records for individual addressing.
- publishNotReadyAddresses controls whether unready Pods are included in DNS.