StatefulSets
A Deployment gives you interchangeable Pods with random names. That is exactly right for a stateless web server, and exactly wrong for a database, where replica 2 must keep its identity — and its disk — across restarts.
A StatefulSet is the variant that gives each Pod a stable identity. In this course we cover it as a talking point rather than a lab, because if you can run a Deployment you can read a StatefulSet, and the one genuinely new idea is per-replica storage — which is covered by the Persistence lab. You should still recognise one, because you will meet them in every cluster.
Reference
What Is Different
| Deployment | StatefulSet | |
|---|---|---|
| Pod names | web-7d9c4f-abcde — random | db-0, db-1, db-2 — ordinal and permanent |
| Network identity | A Service load-balances across them | Each Pod gets stable DNS: db-0.db.default.svc.cluster.local |
| Start and stop order | All at once, in any order | Sequential: 0, then 1, then 2 — and the reverse for deletion |
| Storage | Shared, or none | volumeClaimTemplates give each replica its own claim |
| When to use | Stateless, interchangeable replicas | Databases, queues, anything with identity or quorum |
The Three Ideas
Identity. The db-1 Pod that comes back after a restart is still db-1, with the same name, the same DNS record and the same volume. Other members of the cluster can be configured to find each other by name — which is how a database forms a quorum without a discovery service.
Order. Pods are created in order and terminated in reverse. podManagementPolicy: Parallel opts out when your application does not care.
Per-replica storage. This is the part worth pausing on:
volumeClaimTemplates:
- metadata:
name: data
spec:
accessModes: ["ReadWriteOnce"]
resources:
requests:
storage: 5GiEach replica gets its own claim — data-db-0, data-db-1 — created from this template. Scale to five and you get five volumes. Scaling down does not delete the claims, deliberately: the data outlives the Pod, and if you scale back up the same volume is reattached. It also means a StatefulSet you scaled to zero still holds storage you are paying for.
Because each replica has its own volume, a StatefulSet needs a StorageClass whose volumes can attach to individual nodes — ReadWriteOnce is the normal choice.
Headless Services
A StatefulSet normally pairs with a headless Service (clusterIP: None). Instead of load-balancing, DNS for that Service returns one record per Pod, which is what makes db-0.db resolvable and lets clients address a specific replica.
apiVersion: v1
kind: Service
metadata:
name: db
spec:
clusterIP: None
selector:
app: db
ports:
- port: 5432Seeing One in Action
Your cluster runs its own StatefulSets, so you can look at the real thing rather than a contrived example:
kubectl get statefulsets -A
kubectl get pvc -A | head
kubectl get pod -l app.kubernetes.io/name=... -o wideThen watch the ordering for yourself:
kubectl get pods -w # then delete db-1 and watch only db-1 come backRollouts, and the Reason for Partitions
StatefulSets update in reverse ordinal order — highest number first — one Pod at a time, waiting for each to become ready. That is slower than a Deployment on purpose: you are usually rolling out something with a schema or a quorum.
updateStrategy.rollingUpdate.partition lets you update only Pods with an ordinal greater than the partition. Set partition: 3 on a five-replica set and only db-4 and db-3 move to the new version — a canary with real teeth, and the standard way to test a risky change on one replica before committing.
What to Take Away
- Reach for a StatefulSet when identity matters: a stable name, a stable volume, or ordered start and stop.
volumeClaimTemplatesgives each replica its own storage, and that storage outlives both the Pod and a scale-down.- A headless Service is what makes per-replica DNS work.
- Rollouts are slower and ordered by design. The
partitionfield is how you stage them.