StatefulSet vs Deployment
| Deployment | StatefulSet | |
|---|---|---|
| Pod names | Random hash | Ordinal: mysql-0, mysql-1 |
| Startup | Parallel | Sequential (default) |
| Shutdown | Any order | Reverse ordinal |
| Stable DNS | No | Yes (via headless Service) |
| Per-replica storage | Shared/none | volumeClaimTemplates |
| 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
| Type | Behaviour |
|---|---|
RollingUpdate (default) | Updates Pods in reverse ordinal order |
OnDelete | No automatic update; updated only when manually deleted |
partition: 2with 3 replicas: onlymysql-2updated;mysql-0,mysql-1stay 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
Parallelpolicy: faster scale, no guaranteed startup order- Regular Service load-balances: wrong for targeting specific DB replica
OnDelete: change image viakubectl set imagethen delete Pods one by onepartition: canary a StatefulSet update
Practice scenario: StatefulSet + headless + PVC + RBAC
Tasks
- StatefulSet
mysql-cluster(3 replicas,volumeClaimTemplates5Gi RWO) - Headless Service
clusterIP: None,serviceNamematches - SA
db-admin: full STS + PVC access; SAdb-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.