StatefulSets¶
StatefulSets are for workloads that need stable identity and persistent storage per replica.
Typical examples include databases, queue brokers, and clustered stateful systems.
Why identity matters¶
Deployments treat pods as cattle: any replica can be replaced by any other, so pods get random names and share nothing. That model breaks for systems where replicas are not interchangeable -- a PostgreSQL primary is not the same as its replica, and Kafka broker 2 owns different partitions than broker 0. These systems need each member to come back with the same name, the same data volume, and a predictable address that peers can be configured with.
A StatefulSet also provides an important safety property: at most one pod per identity. Before replacing app-1, the controller must be certain the old app-1 is gone -- two processes writing the same volume or claiming the same cluster membership would corrupt data. This is why StatefulSet pods on a failed node are not replaced automatically until the node object is deleted or the pod is force-deleted: Kubernetes chooses unavailability over split-brain.
What StatefulSets Guarantee¶
- Stable pod ordinal names:
app-0,app-1,app-2 - Stable DNS names through a headless service
- One PersistentVolumeClaim per pod from
volumeClaimTemplates - Ordered rollout and scale behavior by default
Important: StatefulSets do not guarantee a fixed pod IP across restarts. They guarantee stable identity (name/DNS) and stable volume association.
StatefulSet vs Deployment¶
| Concern | Deployment | StatefulSet |
|---|---|---|
| Pod identity | interchangeable | stable ordinal identity |
| Storage | often shared/ephemeral patterns | dedicated PVC per pod |
| Ordering | parallel by default | ordered semantics |
| Typical use | stateless services | stateful clustered systems |

Required Companion: Headless Service¶
StatefulSets rely on a headless Service for stable DNS records.
apiVersion: v1
kind: Service
metadata:
name: web
spec:
clusterIP: None
selector:
app: web
ports:
- port: 80
name: http
Pods then resolve as:
web-0.web.<namespace>.svc.cluster.localweb-1.web.<namespace>.svc.cluster.local
StatefulSet Example¶
apiVersion: apps/v1
kind: StatefulSet
metadata:
name: web
spec:
serviceName: web
replicas: 2
selector:
matchLabels:
app: web
template:
metadata:
labels:
app: web
spec:
containers:
- name: nginx
image: nginx:1.27
volumeMounts:
- name: data
mountPath: /usr/share/nginx/html
volumeClaimTemplates:
- metadata:
name: data
spec:
accessModes: ["ReadWriteOnce"]
resources:
requests:
storage: 10Gi
Pod Management Policy¶
By default, StatefulSets use OrderedReady semantics: pods are created and deleted one at a time in ordinal order. For workloads that do not need strict ordering during scale-up (like sharded caches), Parallel mode starts and stops all pods simultaneously.
Use OrderedReady (the default) when pod N depends on pod N-1 being ready before it can initialize, which is common for clustered databases and consensus systems.
Rolling Updates and Partitions¶
StatefulSets support rolling updates with identity-aware ordering.
For cautious rollouts, use the partition field. Only pods with ordinal >= partition are updated; lower ordinals remain at the old version until you advance the partition.
With 3 replicas and partition: 2, only pod app-2 updates immediately. Set to 1 to also update app-1, then 0 to complete the rollout.
Storage Lifecycle¶
Each replica receives its own PVC named after the volumeClaimTemplate plus the pod ordinal:
data-web-0data-web-1
PVC and PV retention behavior depends on storage class reclaim policy. By default, PVCs are not deleted when a StatefulSet is scaled down or deleted -- they persist until manually removed. This is intentional to prevent data loss.
Since Kubernetes 1.27 (beta; stable in 1.32), you can configure automatic PVC deletion with persistentVolumeClaimRetentionPolicy:
spec:
persistentVolumeClaimRetentionPolicy:
whenDeleted: Delete # delete PVCs when StatefulSet is deleted
whenScaled: Retain # keep PVCs when scaling down
Use Delete carefully -- it is irreversible for stateful systems.
When Not to Use StatefulSet¶
Do not use StatefulSet just because an app writes logs or temp files.
If the workload is horizontally replaceable and does not require replica identity, use Deployment for simpler operations.
Certification notes¶
- Remember the required pairing:
spec.serviceNamemust reference a headless Service, and exam graders check it exists. - PVCs from
volumeClaimTemplatessurvivekubectl delete statefulsetby default -- a frequent scenario-question detail. - Know the per-pod DNS pattern:
<pod>.<service>.<namespace>.svc.cluster.local.
Related Concepts¶
- Pods and Deployments
- Storage
- Services -- headless Services in detail