Managing StatefulSets

1. Creating StatefulSet

Example: StatefulSet with PVC template

apiVersion: apps/v1
kind: StatefulSet
metadata: { name: db }
spec:
  serviceName: db          # headless service for stable DNS
  replicas: 3
  selector: { matchLabels: { app: db } }
  template:
    metadata: { labels: { app: db } }
    spec:
      containers:
      - name: postgres
        image: postgres:16
        volumeMounts: [{ name: data, mountPath: /var/lib/postgresql/data }]
  volumeClaimTemplates:
  - metadata: { name: data }
    spec:
      accessModes: [ReadWriteOnce]
      storageClassName: gp3
      resources: { requests: { storage: 50Gi } }

2. Listing StatefulSets

kubectl get sts
kubectl get sts,svc,pvc -l app=db
ColumnMeaning
READYready/desired replicas
AGECreation time

3. Describing StatefulSet Details

FieldMeaning
Pod Management PolicyOrderedReady / Parallel
Update StrategyRollingUpdate / OnDelete
Volume ClaimsTemplates & bound PVCs

4. Scaling StatefulSet

kubectl scale sts db --replicas=5
kubectl patch sts db --type=json -p='[{"op":"replace","path":"/spec/replicas","value":5}]'
DirectionOrder
Scale upLowest ordinal first (db-0, db-1, ...)
Scale downHighest ordinal first (last in, first out)
Warning: PVCs are not deleted on scale-down. Reclaim manually or with persistentVolumeClaimRetentionPolicy.

5. Understanding Ordered Pod Creation

PhaseDetail
Sequentialdb-N waits for db-(N-1) Ready
Ordinal0,1,2,... in pod name
DNSdb-0.db.NS.svc.cluster.local

6. Using Parallel Pod Management

spec:
  podManagementPolicy: Parallel    # create/delete all at once
PolicyWhen
OrderedReady (default)Apps requiring strict startup ordering
ParallelIndependent replicas (faster scale)

7. Configuring Volume Claim Templates

PropertyDetail
Naming<template-name>-<sts-name>-<ordinal>
LifecycleOutlives pod by default
retentionPolicywhenDeleted, whenScaled (Retain/Delete)
persistentVolumeClaimRetentionPolicy:
  whenDeleted: Retain
  whenScaled: Delete

8. Using Headless Services

apiVersion: v1
kind: Service
metadata: { name: db }
spec:
  clusterIP: None
  selector: { app: db }
  ports: [{ port: 5432, name: pg }]
EffectDetail
clusterIP: NoneNo VIP; DNS returns pod IPs
Per-pod DNSPOD-NAME.SVC.NS.svc.cluster.local

9. Understanding Stable Network IDs

IdentityPersistence
Pod nameStable across reschedules (db-0 stays db-0)
DNSStable via headless service
StorageSame PVC re-attaches
Pod IPNOT stable; changes per restart

10. Updating StatefulSets

updateStrategyBehavior
RollingUpdateHighest ordinal first; one at a time
OnDeleteManual: kill pod to update
partition: NOnly update ordinals ≥N (canary)
maxUnavailable NEW≥1.27 — concurrent updates
updateStrategy:
  type: RollingUpdate
  rollingUpdate: { partition: 2, maxUnavailable: 1 }

11. Deleting StatefulSets

kubectl delete sts db
kubectl delete sts db --cascade=orphan   # keep pods
kubectl delete pvc -l app=db             # explicit PVC cleanup
Warning: Default delete does NOT remove PVCs. Data persists until PVCs are deleted.

12. Troubleshooting StatefulSet Issues

SymptomCommon Cause
Pod stuck PendingPVC unbound (no PV / StorageClass issue)
db-1 never startsdb-0 not Ready (ordered policy)
Volume reattach failsRWO volume on wrong AZ (zone-pinned)
DNS resolution failsHeadless service missing/mismatched