StatefulSet vs Deployment

DeploymentStatefulSet
Pod namesRandom hashOrdinal: mysql-0, mysql-1
StartupParallelSequential (default)
ShutdownAny orderReverse ordinal
Stable DNSNoYes (via headless Service)
Per-replica storageShared/nonevolumeClaimTemplates
Required-serviceName → headless Service

StatefulSet skeleton

apiVersion: apps/v1
kind: StatefulSet
metadata:
  name: mysql
spec:
  replicas: 3
  serviceName: mysql-h      # must match headless Service name
  selector:
    matchLabels:
      app: mysql
  podManagementPolicy: OrderedReady   # or Parallel
  updateStrategy:
    type: RollingUpdate
    rollingUpdate:
      partition: 0    # only Pods with ordinal >= partition are updated
  template:
    spec:
      containers:
      - name: mysql
        image: mysql
  volumeClaimTemplates:
  - metadata:
      name: data-volume
    spec:
      accessModes: [ReadWriteOnce]
      resources:
        requests:
          storage: 500Mi

updateStrategy

TypeBehaviour
RollingUpdate (default)Updates Pods in reverse ordinal order
OnDeleteNo automatic update; updated only when manually deleted
  • partition: 2 with 3 replicas: only mysql-2 updated; mysql-0, mysql-1 stay on old version

Headless Service

apiVersion: v1
kind: Service
metadata:
  name: mysql-h
spec:
  clusterIP: None
  selector:
    app: mysql
  ports:
  - port: 3306

DNS: mysql-0.mysql-h.default.svc.cluster.local (not load-balanced)

Create headless Service imperatively

kubectl expose statefulset db-sts --name=db-headless \
  --port=5432 --target-port=5432 --cluster-ip=None -n q72

kubectl

kubectl create -f statefulset.yaml
kubectl scale statefulset mysql --replicas=5
kubectl get statefulsets

Exam gotchas

  • Delete StatefulSet → PVCs remain: delete PVCs manually if needed
  • Parallel policy: faster scale, no guaranteed startup order
  • Regular Service load-balances: wrong for targeting specific DB replica
  • OnDelete: change image via kubectl set image then delete Pods one by one
  • partition: canary a StatefulSet update

Practice scenario: StatefulSet + headless + PVC + RBAC

Tasks

  • StatefulSet mysql-cluster (3 replicas, volumeClaimTemplates 5Gi RWO)
  • Headless Service clusterIP: None, serviceName matches
  • SA db-admin: full STS + PVC access; SA db-read: get/list/watch only
Solution
# Service clusterIP: None + StatefulSet serviceName: mysql-cluster + volumeClaimTemplates
kubectl create sa db-admin
kubectl create role db-admin-sts --verb=get,list,watch,create,update,patch,delete --resource=statefulsets
# PVC role needs apiGroups: [""] resources: [persistentvolumeclaims]
kubectl auth can-i delete statefulsets --as=system:serviceaccount:default:db-admin

Concepts: mysql-0.mysql-cluster.default.svc.cluster.local; PVCs survive STS delete.