The Problem with Deployments
A standard Deployment treats Pods as cattle. They are interchangeable. If `pod-abcde` dies, it is replaced by `pod-fghij`. They share no history, no identity, and no persistent storage unique to them.
1. The “Sticky Identity” Requirement
Databases (like MySQL, Cassandra, Kafka) need:
- Stable Network ID: “I am always
db-0.” - Stable Storage: “I always need
disk-0attached to me.” - Ordered Startup: “Primary (
db-0) must start before Replica (db-1).”
Enter the StatefulSet.
2. Interactive: StatefulSet Scaling Simulator
Watch how a StatefulSet scales compared to a Deployment. Notice the Ordering and Persistent Identity.
3. Key Feature: VolumeClaimTemplates
In a Deployment, all Pods share the same PVC definition (usually creating a ReadWriteMany volume, or failing if ReadWriteOnce).
In a StatefulSet, you define a Template. Each Pod gets its own unique PVC stamped out from that template.
web-0getspvc-web-0web-1getspvc-web-1
If web-0 dies and restarts, it reattaches to pvc-web-0. Data Persistence is guaranteed per replica.
4. Headless Service
A StatefulSet requires a Headless Service to control the network domain.
A normal Service has a ClusterIP and load balances traffic.
A Headless Service (ClusterIP: None) returns the IPs of the individual Pods.
This allows web-0 to talk directly to web-1 by DNS name: web-1.service-name.default.svc.cluster.local.
5. Configuration Example
apiVersion: apps/v1
kind: StatefulSet
metadata:
name: web
spec:
serviceName: "nginx" # Must match Headless Service
replicas: 3
selector:
matchLabels:
app: nginx
template:
metadata:
labels:
app: nginx
spec:
containers:
- name: nginx
image: k8s.gcr.io/nginx-slim:0.8
volumeMounts:
- name: www
mountPath: /usr/share/nginx/html
# The Magic: Auto-creates PVCs for each Pod
volumeClaimTemplates:
- metadata:
name: www
spec:
accessModes: [ "ReadWriteOnce" ]
storageClassName: "my-storage-class"
resources:
requests:
storage: 1Gi
apiVersion: v1
kind: Service
metadata:
name: nginx
labels:
app: nginx
spec:
ports:
- port: 80
name: web
clusterIP: None # HEADLESS!
selector:
app: nginx
6. When to use StatefulSets?
- Databases: MySQL, PostgreSQL, MongoDB (Primary/Replica).
- Clustered Apps: Zookeeper, Kafka, Elasticsearch.
- Legacy Apps: Apps that write to local disk and expect it to be there after a restart.