Skip to content

StatefulSets

StatefulSets are workload API objects used to manage stateful applications. Unlike Deployments, StatefulSets maintain a sticky identity for each pod and provide guarantees about the ordering and uniqueness of these pods.

StatefulSets are valuable for applications that require one or more of the following:

  • Stable, unique network identifiers
  • Stable, persistent storage
  • Ordered, graceful deployment and scaling
  • Ordered, automated rolling updates

How StatefulSets Work

StatefulSets create pods with predictable names following the pattern {statefulset-name}-{ordinal}. For example, a StatefulSet named mysql with 3 replicas creates pods: mysql-0, mysql-1, mysql-2.

Key Characteristics:

  • Pods are created sequentially (0, 1, 2...) and terminated in reverse order
  • Each pod gets a stable DNS hostname: {pod-name}.{service-name}.{namespace}.svc.cluster.local
  • PersistentVolumeClaims are retained when pods are deleted (data persists)
  • Scaling down does not delete associated PVCs

When to Use StatefulSets

Use Case Examples
Databases MySQL, PostgreSQL, MongoDB
Message Queues Kafka, RabbitMQ
Distributed Systems Elasticsearch, Cassandra, Zookeeper
Applications requiring stable network identity Leader election scenarios

Resources

References

Headless Service for StatefulSet (required for stable network identities)

apiVersion: v1
kind: Service
metadata:
  name: mysql
  labels:
    app: mysql
spec:
  ports:
    - port: 3306
      name: mysql
  clusterIP: None  # Headless service
  selector:
    app: mysql

StatefulSet Definition

apiVersion: apps/v1
kind: StatefulSet
metadata:
  name: mysql
spec:
  serviceName: "mysql"
  replicas: 3
  selector:
    matchLabels:
      app: mysql
  template:
    metadata:
      labels:
        app: mysql
    spec:
      containers:
        - name: mysql
          image: mysql:8.0
          ports:
            - containerPort: 3306
              name: mysql
          env:
            - name: MYSQL_ROOT_PASSWORD
              valueFrom:
                secretKeyRef:
                  name: mysql-secret
                  key: password
          volumeMounts:
            - name: data
              mountPath: /var/lib/mysql
  volumeClaimTemplates:
    - metadata:
        name: data
      spec:
        accessModes: ["ReadWriteOnce"]
        storageClassName: "standard"
        resources:
          requests:
            storage: 10Gi
Create StatefulSet
oc apply -f statefulset.yaml
Get StatefulSets
oc get statefulsets
Describe StatefulSet
oc describe statefulset mysql
Scale StatefulSet
oc scale statefulset mysql --replicas=5
Delete StatefulSet (keeps PVCs)
oc delete statefulset mysql
Delete StatefulSet and PVCs
oc delete statefulset mysql --cascade=foreground
oc delete pvc -l app=mysql
Create StatefulSet
kubectl apply -f statefulset.yaml
Get StatefulSets
kubectl get statefulsets
Describe StatefulSet
kubectl describe statefulset mysql
Scale StatefulSet
kubectl scale statefulset mysql --replicas=5
Delete StatefulSet (keeps PVCs)
kubectl delete statefulset mysql
Delete StatefulSet and PVCs
kubectl delete statefulset mysql --cascade=foreground
kubectl delete pvc -l app=mysql

StatefulSet vs Deployment

Feature Deployment StatefulSet
Pod Names Random (e.g., nginx-5d4c6f7b8-x2k9j) Predictable (e.g., mysql-0)
Pod Creation Parallel Sequential
Pod Deletion Any order Reverse order
Network Identity Ephemeral Stable DNS
Storage Shared PVC Per-pod PVC
Use Case Stateless apps Stateful apps