I tried running a MySQL database in a standard Deployment, but every time the Pod restarted, it lost its connection to the storage, and its hostname changed, breaking my application's configuration. Is Kubernetes only meant for "stateless" apps? How do StatefulSets provide the persistent identity and stable network IDs needed for clustered databases like MongoDB or PostgreSQL?
3 answers
For databases, you must use StatefulSets. Unlike Deployments, where Pods are interchangeable and get random names (e.g., web-a1b2), StatefulSets provide a stable, ordinal index (e.g., db-0, db-1). Most importantly, each Pod gets its own Persistent Volume Claim (PVC) that stays attached to that specific identity even after a restart. This ensures your data follows the Pod.
StatefulSets also handle Ordered Deployment. They bring Pods up one by one (0, then 1, then 2) and take them down in reverse order. This is critical for distributed systems where a "Master" node needs to be ready before the "Slaves" join the cluster. You can't get this deterministic behavior with a standard Deployment.
You also need a Headless Service (a Service with clusterIP: None) when using StatefulSets. This allows the Pods to talk to each other directly using their stable DNS names (like db-0.mysql.svc.cluster.local), which is necessary for database replication and leader election.
This is exactly how we set up our Kafka cluster on K8s. Without the Headless Service, the brokers couldn't maintain a stable connection with each other because their "Internal IPs" shift during maintenance.
One thing to watch out for: deleting a StatefulSet does not delete the associated storage (Persistent Volumes) by default. This is a safety feature to prevent accidental data loss, but it can lead to unexpected cloud storage costs if you aren't careful.