🧪
🎯 Goal
By the end, you will clearly see:
- Why ClusterIP hides pod identity
- Why Headless Service exposes pod identity
- How StatefulSet + Headless Service gives stable DNS per pod
- Why databases need this
🧠 Mental model (keep this in mind)
| Setup | DNS result |
|---|---|
| Deployment + ClusterIP | One virtual IP |
| Deployment + Headless | Multiple pod IPs |
| StatefulSet + Headless | Stable pod DNS names (this is the magic) |
🧩 Project structure
headless-demo/
├── mysql-headless.yaml
├── mysql-statefulset.yaml
└── dns-test.yaml
1️⃣ Headless Service (NO Cluster IP)
📄 mysql-headless.yaml
apiVersion: v1
kind: Service
metadata:
name: mysql-headless
spec:
clusterIP: None # 👈 THIS MAKES IT HEADLESS
selector:
app: mysql
ports:
- port: 3306
📌 Important:
- No virtual IP
- DNS will return pod IPs
2️⃣ StatefulSet (stable pod identity)
📄 mysql-statefulset.yaml
apiVersion: apps/v1
kind: StatefulSet
metadata:
name: mysql
spec:
serviceName: mysql-headless # 👈 REQUIRED
replicas: 3
selector:
matchLabels:
app: mysql
template:
metadata:
labels:
app: mysql
spec:
containers:
- name: mysql
image: mysql:8.0
env:
- name: MYSQL_ROOT_PASSWORD
value: root
ports:
- containerPort: 3306
📌 What StatefulSet guarantees:
- Pods named:
mysql-0
mysql-1
mysql-2
- Names NEVER change
- Identity is stable
3️⃣ DNS test pod (to observe behavior)
📄 dns-test.yaml
apiVersion: v1
kind: Pod
metadata:
name: dns-test
spec:
containers:
- name: dns
image: busybox:1.28
command: ["sleep", "3600"]
4️⃣ Apply everything (ORDER MATTERS)
kubectl apply -f mysql-headless.yaml
kubectl apply -f mysql-statefulset.yaml
kubectl apply -f dns-test.yaml
Wait:
kubectl get pods
You should see:
mysql-0 Running
mysql-1 Running
mysql-2 Running
dns-test Running
5️⃣ 🔥 THE MOST IMPORTANT PART — DNS BEHAVIOR
Enter the test pod
kubectl exec -it dns-test -- sh
🔍 DNS lookup of the HEADLESS service
nslookup mysql-headless
✅ You will see MULTIPLE IPs (one per pod):
Address: 10.244.0.12
Address: 10.244.0.13
Address: 10.244.0.14
👉 This is DNS round-robin.
🔥 DNS lookup of INDIVIDUAL PODS (THIS IS THE KEY)
nslookup mysql-0.mysql-headless
nslookup mysql-1.mysql-headless
nslookup mysql-2.mysql-headless
✅ Each one resolves to a specific pod IP.
This is what ClusterIP can NEVER do.
6️⃣ Why databases NEED this
Imagine:
| Role | DNS |
|---|---|
| Primary DB | mysql-0.mysql-headless |
| Replica 1 | mysql-1.mysql-headless |
| Replica 2 | mysql-2.mysql-headless |
Now:
- Writes →
mysql-0.mysql-headless - Reads → replicas
- Replication → stable target
💡 This is impossible with Deployment + ClusterIP.
7️⃣ Visual intuition (what’s happening)
8️⃣ One-line interview answer (remember this)
“A headless service removes the virtual IP and exposes pod identities via DNS. Combined with StatefulSets, it enables stable per-pod DNS, which is required for databases and leader-follower architectures.”


SOCIAL SHARE CARD GENERATOR