How to Deploy a StatefulSet in Kubernetes
StatefulSets are the Kubernetes workload controller designed for applications that require stable network identities, persistent storage, and ordered deployment. Databases, message queues, and distributed caches are prime candidates. This guide shows you how to deploy and manage StatefulSets on your Breeze cluster.
How StatefulSets Differ from Deployments
- Stable pod names — pods are named
<statefulset>-0,<statefulset>-1, etc., rather than random suffixes - Ordered startup and shutdown — pods are created sequentially and terminated in reverse order
- Persistent volume claims — each pod gets its own PVC that survives rescheduling
- Stable DNS — each pod gets a predictable hostname via a headless Service
Creating a Headless Service
StatefulSets require a headless Service (with clusterIP: None) for DNS resolution:
apiVersion: v1
kind: Service
metadata:
name: postgres-headless
labels:
app: postgres
spec:
ports:
- port: 5432
name: postgres
clusterIP: None
selector:
app: postgres
Defining the StatefulSet
apiVersion: apps/v1
kind: StatefulSet
metadata:
name: postgres
spec:
serviceName: postgres-headless
replicas: 3
selector:
matchLabels:
app: postgres
template:
metadata:
labels:
app: postgres
spec:
containers:
- name: postgres
image: postgres:16
ports:
- containerPort: 5432
env:
- name: POSTGRES_PASSWORD
valueFrom:
secretKeyRef:
name: pg-secret
key: password
- name: PGDATA
value: /var/lib/postgresql/data/pgdata
volumeMounts:
- name: pg-data
mountPath: /var/lib/postgresql/data
volumeClaimTemplates:
- metadata:
name: pg-data
spec:
accessModes: ["ReadWriteOnce"]
storageClassName: standard
resources:
requests:
storage: 10Gi
Verifying the StatefulSet
After applying the manifest, watch the pods come up in order:
kubectl get pods -l app=postgres -w
You should see postgres-0 reach Running before postgres-1 starts, and so on. Each pod also gets a dedicated PVC:
kubectl get pvc -l app=postgres
DNS Resolution
Each pod is reachable at <pod-name>.<headless-service>.<namespace>.svc.cluster.local. For example, postgres-0.postgres-headless.default.svc.cluster.local. This stable DNS is critical for clustering protocols in databases and distributed systems running on your Breeze infrastructure.
Scaling and Updates
Scale a StatefulSet carefully — new replicas are added in order and removed in reverse:
kubectl scale statefulset postgres --replicas=5
For updates, StatefulSets support RollingUpdate and OnDelete strategies. The rolling update proceeds from the highest ordinal to the lowest, ensuring the primary replica is updated last.