Lesson 7 · Workloads, config & networking
StatefulSets vs Deployments
When interchangeable clones aren't enough — and why conversationmgmt, your own service, is one of only two.
Your win: explain what a StatefulSet guarantees that a Deployment doesn't — stable identity, ordered lifecycle, per-Pod storage — and articulate why exactly two backend services here use one.
Deployments assume clones; some workloads can't be clones
A Deployment (Lesson 4) treats its Pods as interchangeable: any replica is as good as any other, they start in any order, and they share no per-Pod identity. That's perfect for a stateless request handler. But some workloads need each Pod to be distinct and durable. That's a StatefulSet.1
| Deployment | StatefulSet | |
|---|---|---|
| Pod identity | random names, interchangeable | stable, ordinal: pod-0, pod-1… |
| Startup / scaling | any order, in parallel | ordered, one at a time (0, then 1, …) |
| Storage | usually shared or none | its own PersistentVolume per Pod, kept across restarts |
| Network name | reached via the Service | stable per-Pod DNS (usually via a headless Service) |
| Rollout | rolling update (new RS) | ordered, reverse-ordinal update |
In this repo: exactly two, and one is yours
tom and conversationmgmt
Of ~24 backend services, only two are StatefulSets (grep-confirmed):
conversationmgmt— your team's service. Its entrypoint backend/conversationmgmt/templates/app.yaml:1 callsutil.appStatefulSetWithToggle→ the shared libs/util/templates/_statefulset.tpl:4.tom— student management/chat. A bespoke split: backend/tom/templates/statefulset.yaml:2 (util.statefulSet) for the workload, plus a separateapp.yamlfor everything else.
spike, notificationmgmt, usermgmt,
…) is a Deployment. The _statefulset.tpl file appears in every chart's
templates/util/, but that's just the library macro being copied in
by update_deps.sh (Course 3) — only these two invoke it.
serviceName in _statefulset.tpl:13
points at it. (2) tom even disables its PodDisruptionBudget
(backend/tom/values.yaml:48-49). So this is a StatefulSet used
mainly for stable identity/ordering, not the full textbook per-Pod-PV-plus-headless
setup. Good to say out loud: "we use it for stable pod identity; it's chat-session/websocket
affinity, not a database." (Confirm the precise reason with the tom/conversationmgmt
owners — that's the wisdom step.)
Kubernetes docs — StatefulSets
The guarantees (stable identity, ordered ops, per-Pod storage), the headless-Service pairing, and when to prefer a Deployment.
Check yourself (from memory)
Q1. The core thing a StatefulSet guarantees over a Deployment is…
pod-0…), ordered
lifecycle, and per-Pod persistent storage. Deployments treat Pods as clones.
Q2. How many backend business services here are StatefulSets?
Q3. You'd default to a Deployment (not StatefulSet) when Pods are…
pod-0,1,2),
ORDERED lifecycle (one at a time), OWN PersistentVolume per pod, stable per-pod DNS (usually
a headless Service). RULE: default to Deployment; use StatefulSet only when a pod needs a
durable identity that survives restarts (DBs, brokers, partition owners). REPO: only TWO
backend services — conversationmgmt (your team, app.yaml →
util.appStatefulSetWithToggle) and tom (bespoke
statefulset.yaml). Caveats: they reuse the normal ClusterIP service (not
headless), and tom disables its PDB — used for stable identity, not a textbook DB setup.