StatefulSets Basics
This page introduces the StatefulSet controller through small, runnable examples: stable pod names, per-pod storage, ordered rollout, and safe scaling.
Search across all documentation pages
This page introduces the StatefulSet controller through small, runnable examples: stable pod names, per-pod storage, ordered rollout, and safe scaling.
Work through the basic examples first, then the intermediate ones for update and retention control.
kubectl matching your server minor.volumeClaimTemplates.kubectl version
kubectl get storageclassThe smallest StatefulSet needs a serviceName, a selector, and a pod template.
apiVersion: apps/v1
kind: StatefulSet
metadata:
name: web
spec:
serviceName: web
replicas: 3
selector:
matchLabels:
app: web
template:
metadata:
labels:
app: web
spec:
containers:
- name: nginx
image: nginx:1.27
ports:
- containerPort: 80serviceName points at the headless Service that backs stable DNS.web-0, web-1, web-2 in order.A StatefulSet relies on a Service with clusterIP: None to publish per-pod DNS.
apiVersion: v1
kind: Service
metadata:
name: web
spec:
clusterIP: None
selector:
app: web
ports:
- port: 80clusterIP: None makes the Service headless.web-0.web, web-1.web, and so on.serviceName.Apply both manifests and watch pods come up one at a time.
kubectl apply -f service.yaml -f statefulset.yaml
kubectl get pods -l app=web -wweb-1 will not start until web-0 is Ready.-w flag streams changes as they happen.OrderedReady policy.Add a volumeClaimTemplates block to give each pod its own volume.
volumeClaimTemplates:
- metadata:
name: data
spec:
accessModes: ["ReadWriteOnce"]
storageClassName: standard
resources:
requests:
storage: 1Gidata-web-0, data-web-1, and so on.volumeMounts with name: data.storageClassName explicitly rather than relying on the default.Mount the claim inside the pod template so the data is actually used.
containers:
- name: nginx
image: nginx:1.27
volumeMounts:
- name: data
mountPath: /usr/share/nginx/htmlname must match the volumeClaimTemplates entry.volumes entry is needed; the template provides it.Each pod is individually addressable through the headless Service.
kubectl run tmp --rm -it --image=busybox:1.36 -- \
nslookup web-0.web.default.svc.cluster.local<pod>.<service>.<namespace>.svc.cluster.local.Scale a StatefulSet with the same command you use for a Deployment.
kubectl scale statefulset/web --replicas=5web-3 then web-4 in order.web-4, then web-3.Standard kubectl verbs work for status and troubleshooting.
kubectl get statefulset web
kubectl describe statefulset web
kubectl get pvc -l app=webget shows desired versus ready replicas.describe surfaces events like failed scheduling or volume binding.The default update strategy is RollingUpdate, and a partition lets you canary high ordinals first.
updateStrategy:
type: RollingUpdate
rollingUpdate:
partition: 22 are updated.0 to update every pod.When your app tolerates simultaneous starts, skip the ordered wait.
spec:
podManagementPolicy: ParallelOrderedReady for quorum databases.Decide what happens to per-pod volumes on scale-down or deletion.
spec:
persistentVolumeClaimRetentionPolicy:
whenScaled: Delete
whenDeleted: RetainwhenScaled: Delete reclaims PVCs when you scale in.whenDeleted: Retain keeps data if the StatefulSet itself is removed.Retain for both, which preserves data but can leak storage.StatefulSet pods terminate in reverse ordinal order, and you can give each one time to leave cleanly.
spec:
template:
spec:
terminationGracePeriodSeconds: 60web-2, then web-1, then web-0.Stack versions: This page was written for Kubernetes 1.36.2, Docker Engine 29.6.1 (BuildKit default), containerd (CRI runtime on nodes), Helm 3, Compose v2, Argo CD (latest - verify at build), and Gateway API (GA - verify controller support at build).
Reviewed by Chris St. John·Last updated Jul 19, 2026