AI Hints
Home›Kubernetes Tutorial›Special Workloads
Kubernetes · Lesson 31 of 86

StatefulSets

Pods with a name and a memory.

⏱ 2 min read▶ Video at 1:15:53🎓 Free
Watch this lesson in the Kubernetes courseWatch on YouTube ↗Full Kubernetes course

Deployments treat pods like identical, disposable workers. That is perfect for web servers. But a database cluster is different. Each member has its own role, its own name, and its own data. For these apps, Kubernetes offers the stateful set. In this lesson, you will see how it keeps identity and storage together.

StatefulSets
From the video: StatefulSets
  • Deployment pods are interchangeable
  • Some apps need a stable identity
  • StatefulSets provide it

Deployment versus StatefulSet

Let's compare the two. A deployment gives pods random names, like web, dash, a random suffix. They start together, and share one volume, or none. A stateful set gives pods predictable names, with an index, db zero, db one, and db two. They start in order, one after another, and stop in reverse. And each pod gets its own personal volume, which follows it, even if the pod is rebuilt. Identity, order, and private storage are the three gifts.

Deployment

  • Random pod names
  • All start at once
  • Shared or no storage
  • Interchangeable pods

StatefulSet

  • Stable names: db-0, db-1, db-2
  • Ordered start and stop
  • A private volume per pod
  • Each pod keeps its identity

A StatefulSet in YAML

Here is a stateful set. It looks like a deployment, with a few new ideas. Service name points to a headless service, which gives each pod its own D N S name. We ask for three replicas. And at the bottom, volume claim templates, is a blueprint for claims. For every pod, Kubernetes stamps out a new claim from it, named after the pod, so db zero gets its own disk, db one gets another, and so on.

statefulset.yamlyaml
apiVersion: apps/v1
kind: StatefulSet
metadata:
  name: db
spec:
  serviceName: db
  replicas: 3
  selector:
    matchLabels:
      app: db
  template:
    metadata:
      labels:
        app: db
    spec:
      containers:
      - name: db
        image: nginx:1.27
        volumeMounts:
        - name: data
          mountPath: /usr/share/nginx/html
  volumeClaimTemplates:
  - metadata:
      name: data
    spec:
      accessModes: ["ReadWriteOnce"]
      resources:
        requests:
          storage: 1Gi

Names that stick

Let's create it, together with its headless service. After a little while, the pods are running, and see their names. Zero, one, and two, and the claims, one for each pod. Now watch. We delete pod db one. The stateful set creates a replacement, with exactly the same name, db one, and it reconnects to the same claim, so its data is still there. Even the D N S name of the pod stays the same. Identity survives replacement.

kubectl
kubectl apply -f sts.yaml
service/db created
statefulset.apps/db created
Warning: spec.SessionAffinity is ignored for headless services
kubectl get pods -l app=db
NAME   READY   STATUS    RESTARTS   AGE
db-0   1/1     Running   0          46s
db-1   1/1     Running   0          44s
db-2   1/1     Running   0          43s
kubectl get pvc -o custom-columns=NAME:.metadata.name,STATUS:.status.phase,SIZE:.status.capacity.storage
NAME        STATUS   SIZE
data-db-0   Bound    1Gi
data-db-1   Bound    1Gi
data-db-2   Bound    1Gi
kubectl delete pod db-1 --now
pod "db-1" deleted from default namespace
kubectl get pods -l app=db
NAME   READY   STATUS    RESTARTS   AGE
db-0   1/1     Running   0          55s
db-1   1/1     Running   0          8s
db-2   1/1     Running   0          52s
File used: sts.yaml
apiVersion: v1
kind: Service
metadata:
  name: db
spec:
  clusterIP: None
  selector:
    app: db
  ports:
  - port: 80
---
apiVersion: apps/v1
kind: StatefulSet
metadata:
  name: db
spec:
  serviceName: db
  replicas: 3
  selector:
    matchLabels:
      app: db
  template:
    metadata:
      labels:
        app: db
    spec:
      containers:
      - name: db
        image: nginx:1.27
        volumeMounts:
        - name: data
          mountPath: /usr/share/nginx/html
  volumeClaimTemplates:
  - metadata:
      name: data
    spec:
      accessModes: ["ReadWriteOnce"]
      resources:
        requests:
          storage: 1Gi

Summary

Good. A stateful set gives pods stable names, ordered startup, and a private volume each. It is the right choice for databases and clustered systems. Next, a workload that puts one pod on every node, the daemon set.

Key takeaways
  • Stable names: db-0, db-1, db-2
  • Ordered start, private volumes
  • Replacement keeps the identity
Next up: DaemonSets — one pod on every node