When should you choose a StatefulSet over a Deployment, and how do stable network identity and storage work?
Quick Answer
StatefulSets provide stable Pod names (pod-0, pod-1), persistent identity via headless Service DNS, and ordered rollout/scale. Use them for databases, distributed systems needing stable storage, or quorum-based apps—not for stateless APIs like payments-api.
Detailed Answer
Deployments treat Pods as interchangeable cattle—any replica can serve any request. StatefulSets treat Pods as pets with unique identities that persist across rescheduling. Pod names are deterministic: user-auth-service-0, user-auth-service-1, user-auth-service-2. A headless Service (clusterIP: None) creates DNS A records for each Pod: user-auth-service-0.user-auth-service.auth.svc.cluster.local.
StatefulSets guarantee ordered operations. Rolling updates proceed from highest ordinal downward (or configurable). Scaling up creates pod-2 only after pod-1 is Ready. Scaling down removes highest ordinals first. This ordering matters for systems like ZooKeeper, Kafka brokers, or etcd where bootstrap sequence affects cluster formation.
Storage is delivered via volumeClaimTemplates—each Pod receives its own PersistentVolumeClaim named data-user-auth-service-0, bound for the lifetime of that ordinal. If user-auth-service-1 dies and reschedules, it reattaches the same PVC, preserving local session store or replicated database data tied to that identity.
Do not use StatefulSets for horizontally scaled stateless APIs. payments-api behind a Deployment with 3 replicas and shared nothing architecture scales faster and simplifies rolling updates. Misapplied StatefulSets add unnecessary DNS complexity and serial scaling latency.
Analogy: a StatefulSet is like numbered parking spots in an apartment complex. Resident #2 always gets spot #2, even if they temporarily leave and return. A Deployment is a public lot—take any open space.
Combine StatefulSets with PodDisruptionBudgets, proper probes, and anti-affinity to spread ordinals across zones. For multi-writer databases, application-level replication (Patroni, MongoDB replica sets) still required—Kubernetes identity does not replace database consensus.
The spec.updateStrategy.rollingUpdate.partition field enables canary-style rollouts: set partition to 2 and only user-auth-service-2 receives the new image while ordinals 0 and 1 stay on the old version. podManagementPolicy: Parallel speeds bootstrap when ordinals have no ordering dependency—common for Kafka brokers after initial cluster formation.
On delete, retain PVCs by default unless cascade and deletion policies are configured—operations teams rely on this for data safety but must garbage-collect orphaned volumes. startupProbe protects slow-initializing containers without livenessProbe killing them prematurely during long migrations.
For 3 replicas each requesting 250m CPU and 512Mi memory, total StatefulSet reservation is 750m CPU and 1536Mi before overhead—capacity planning must account for per-Pod PVC latency during node failure recovery.