Docs / Kubernetes & Orchestration / How to Deploy a StatefulSet in Kubernetes

How to Deploy a StatefulSet in Kubernetes

By Admin · Mar 2, 2026 · Updated Apr 23, 2026 · 31 views · 2 min read

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.

Was this article helpful?