DEV Community

TheYAMLGuy
TheYAMLGuy

Posted on

Kubernetes: StatefulSet vs. Deployment

When I've started with Kubernetes it took me a long time to understand when to use a StatefulSet instead of a Deployment and whats the difference between them.

The truth is: Deployments are for things that don't care if they die. StatefulSets are for things that do.

Let's break down on when to use which and whats the difference.

The Core Difference (TL;DR)

If you remember only one thing from this article, make it this:

  • Deployments manage Stateless pods. Every pod is identical, anonymous and completely replaceable. Think of them like cattle
  • StatefulSets manage Stateful pods. Every pod has a unique identity, a persistent name and its own dedicated storage. Think of them like pets.
Feature Deployment StatefulSet
Pod Names Random hash (web-89768dx878-asdff) Sticky index (db-0, db-1, ...)
Scaling Order All at once (Random) One by one (0, then 1, then 2)
Storage (PVs) Shared or ephemeral Dedicated per pod via Templates
Best For APIs, Frontends, Microservices Databases, Queues, Cluster apps

When to use a Deployment (Stateless)

Go with a Deployment if your application doesn't save any data locally. If Pod A dies, Pod B spins up on a different node, your users shouldn't notice anything because the actual State lives somewhere else like an external DB or S3 Bucket.

How K8s handles it

When you scale a Deployment, Kubernetes creates a ReplicaSet, which spins up pods using random hashes at the end. It doesn't care about the order. If you delete pod-xyz, K8s replaces it with pod-abc.

apiVersion: apps/v1
kind: Deployment
metadata:
  name: api-deployment
  labels:
    app: api
spec:
  replicas: 3
  selector:
    matchLabels:
      app: api
  template:
    metadata:
      labels:
        app: api
    spec:
      containers:
      - name: api
        image: nginx:1.25
        ports:
        - containerPort: 80
Enter fullscreen mode Exit fullscreen mode

When to use a StatefulSet (Stateful)

You have to use a StatefulSet the moment your pods need to remember who they are or need their own private disk space.

Think about a PostgreSQL cluster. You have a Primary node (writes) and Replicas (reads). The replicas need to know where the primary node is. You can't just use a random pod name that changes every time a node restarts.

The Magic behind StatefulSets

  1. Predictable DNS: Your pods will be named postgres-1, postgres-2. etc. If postgres-0 crashes, it terminates and Kubernetes spins up a new pod with the exact same name.
  2. Orderly Scaling: K8s won't start postgres-1 until postgres-0 is completely up and running.
  3. Dedicated Storage(volumeClaimTemplates): Instead of all pods fighting over the same persistent volume, a StatefulSet automatically provisions a unique Persistent Volume (PV) for each pod. postgres-0 gets data-postgres-0, postgres-1 gets data-postgres-1. Even if a pod dies, when it comes back, K8s attaches the exact same disk to it.
apiVersion: apps/v1
kind: StatefulSet
metadata:
  name: postgres-set
spec:
  serviceName: "postgres-headless" # Requires a Headless Service for network identity
  replicas: 3
  selector:
    matchLabels:
      app: postgres
  template:
    metadata:
      labels:
        app: postgres
    spec:
      containers:
      - name: postgres
        image: postgres:16
        ports:
        - containerPort: 5432
          name: db
        volumeMounts:
        - name: pgdata
          mountPath: /var/lib/postgresql/data
  volumeClaimTemplates: # This automatically creates a unique PVC per pod
  - metadata:
      name: pgdata
    spec:
      accessModes: [ "ReadWriteOnce" ]
      resources:
        requests:
          storage: 10Gi
Enter fullscreen mode Exit fullscreen mode

I hope that is helpful for somebody. If you're a beginner, what topics should I write about next?

Top comments (0)