Skip to main content

StatefulSets:

 

StatefulSets: Managing Stateful Applications in Kubernetes

📅 Published: August 2026
⏱️ Estimated Reading Time: 14 minutes
🏷️ Tags: Kubernetes, StatefulSets, Stateful Applications, Databases, Storage


Introduction: What is a StatefulSet?

A StatefulSet is a Kubernetes workload API object used to manage stateful applications. It is designed for applications that require stable, unique network identifiers, persistent storage, and ordered, graceful deployment and scaling.

Think of a StatefulSet as a Deployment for stateful applications. While Deployments are ideal for stateless apps (where Pods are interchangeable), StatefulSets handle applications where each instance has a unique identity and persistent state, like databases, message queues, and distributed systems.

Key characteristics:

  • Stable, unique network identifiers: Each Pod gets a persistent hostname

  • Ordered, graceful deployment: Pods are created and scaled in order

  • Stable persistent storage: Each Pod can have its own PersistentVolume

  • Ordered, graceful deletion: Pods are terminated in reverse order

  • Ordered, automated rolling updates: Updates are applied in order


Part 1: Why Use StatefulSets?

The Problem with Deployments for Stateful Apps

Deployments are designed for stateless applications where Pods are interchangeable. They work well for web servers, APIs, and microservices. However, they have limitations for stateful applications:

AspectDeploymentStatefulSet
Pod namingRandom suffixesOrdered names (web-0, web-1, web-2)
Stable network IDNo (IP changes on restart)Yes (stable hostname)
Persistent storageShared or ephemeralPer-Pod persistent storage
ScalingAny order, parallelOrdered (0, 1, 2, ...)
Update strategyRolling update (any order)Ordered rolling update
Use caseStateless appsDatabases, message queues, stateful microservices

StatefulSet Use Cases

Databases:

  • PostgreSQL, MySQL, MongoDB, Cassandra

  • Each instance needs its own data volume

  • Stable network identity for replication

Message Queues:

  • Kafka, RabbitMQ, ActiveMQ

  • Each broker needs persistent storage

  • Stable network identity for cluster membership

Distributed Systems:

  • Elasticsearch, Cassandra, ZooKeeper

  • Each node has a specific role

  • Stable identity for quorum and consensus


Part 2: StatefulSet Components

Core Components

yaml
apiVersion: apps/v1
kind: StatefulSet
metadata:
  name: postgres
  namespace: database
spec:
  serviceName: "postgres"           # Headless Service name
  replicas: 3
  selector:
    matchLabels:
      app: postgres
  template:
    metadata:
      labels:
        app: postgres
    spec:
      containers:
      - name: postgres
        image: postgres:15
        env:
        - name: POSTGRES_PASSWORD
          value: "secret"
        ports:
        - containerPort: 5432
        volumeMounts:
        - name: data
          mountPath: /var/lib/postgresql/data
  volumeClaimTemplates:              # Per-Pod PVCs
  - metadata:
      name: data
    spec:
      accessModes: ["ReadWriteOnce"]
      storageClassName: "standard"
      resources:
        requests:
          storage: 10Gi

Key Components Explained

serviceName: A headless Service that manages the network identity of the Pods.

volumeClaimTemplates: A template for PersistentVolumeClaims. Each Pod gets its own PVC.

Pod Identity: Each Pod gets a stable hostname: <statefulset-name>-<ordinal>.


Part 3: Stable Network Identity

Headless Service

A headless Service is required for StatefulSets to provide stable network identities:

yaml
apiVersion: v1
kind: Service
metadata:
  name: postgres
  namespace: database
spec:
  clusterIP: None                    # Headless Service
  selector:
    app: postgres
  ports:
  - port: 5432
    targetPort: 5432

DNS Naming

With a headless Service, each Pod gets a unique DNS name:

text
<pod-name>.<service-name>.<namespace>.svc.cluster.local

Examples:

text
postgres-0.postgres.database.svc.cluster.local
postgres-1.postgres.database.svc.cluster.local
postgres-2.postgres.database.svc.cluster.local

Why Stable Network Identity Matters

  1. Database Replication: Primary and replica nodes need to know each other's addresses

  2. Cluster Membership: Distributed systems require stable addresses for quorum

  3. Service Discovery: Other services need to find specific instances


Part 4: Ordered Deployment and Scaling

Creation Order

When you create a StatefulSet with 3 replicas:

text
1. postgres-0 is created and becomes Running
2. postgres-1 is created and becomes Running
3. postgres-2 is created and becomes Running

Scaling Up

When you scale from 3 to 5 replicas:

text
1. postgres-3 is created
2. postgres-4 is created

Scaling Down

When you scale from 5 to 3 replicas:

text
1. postgres-4 is terminated
2. postgres-3 is terminated

This ordered scaling ensures that you don't lose quorum or disrupt replication.

Scaling Commands

bash
# Scale a StatefulSet
kubectl scale statefulset postgres --replicas=5

# Edit the StatefulSet
kubectl edit statefulset postgres

# Apply changes from YAML
kubectl apply -f statefulset.yaml

Part 5: Persistent Storage

PersistentVolumeClaims

Each Pod in a StatefulSet gets its own PersistentVolumeClaim (PVC) based on the volumeClaimTemplates:

yaml
volumeClaimTemplates:
- metadata:
    name: data
  spec:
    accessModes: ["ReadWriteOnce"]
    storageClassName: "standard"
    resources:
      requests:
        storage: 10Gi

PVC Naming

PVCs are named according to the template:

text
data-postgres-0
data-postgres-1
data-postgres-2

Why Per-Pod Storage Matters

  1. Data Isolation: Each database instance has its own data

  2. Data Persistence: Data survives Pod restarts and rescheduling

  3. Independent Scaling: Each Pod can have its own storage size

StatefulSet with Storage

yaml
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
        env:
        - name: MYSQL_ROOT_PASSWORD
          value: "root"
        ports:
        - containerPort: 3306
        volumeMounts:
        - name: data
          mountPath: /var/lib/mysql
  volumeClaimTemplates:
  - metadata:
      name: data
    spec:
      accessModes: ["ReadWriteOnce"]
      storageClassName: standard
      resources:
        requests:
          storage: 20Gi

Part 6: Update Strategies

RollingUpdate (Default)

StatefulSets support rolling updates, updating Pods in reverse ordinal order:

text
1. postgres-2 is updated
2. postgres-1 is updated
3. postgres-0 is updated

Partitioned RollingUpdate

You can specify a partition to control which Pods are updated:

yaml
spec:
  updateStrategy:
    type: RollingUpdate
    rollingUpdate:
      partition: 2

With partition 2, only Pods with ordinal >= 2 are updated:

text
1. postgres-2 is updated (if it exists)
2. postgres-3 is updated (if it exists)
...

Pods below the partition (0, 1) are not updated.

OnDelete

The OnDelete strategy only updates Pods when they are manually deleted:

yaml
spec:
  updateStrategy:
    type: OnDelete

When a Pod is deleted, it is recreated with the new template.


Part 7: StatefulSet vs Deployment

AspectStatefulSetDeployment
Pod namingOrdered (web-0, web-1)Random (web-abc123)
Stable network IDYes (stable hostname)No (IP changes)
Persistent storagePer-Pod PVCShared or ephemeral
ScalingOrdered, sequentialParallel, any order
DeletionOrdered, reverseAny order
UpdatesOrdered (reverse)Any order
Use caseStateful appsStateless apps

Part 8: Real-World StatefulSet Examples

Example 1: PostgreSQL with Primary-Replica

yaml
apiVersion: apps/v1
kind: StatefulSet
metadata:
  name: postgres
spec:
  serviceName: postgres
  replicas: 3
  selector:
    matchLabels:
      app: postgres
  template:
    metadata:
      labels:
        app: postgres
    spec:
      containers:
      - name: postgres
        image: postgres:15
        env:
        - name: POSTGRES_PASSWORD
          valueFrom:
            secretKeyRef:
              name: postgres-secret
              key: password
        - name: POSTGRES_PRIMARY
          value: "postgres-0.postgres.database.svc.cluster.local"
        ports:
        - containerPort: 5432
        volumeMounts:
        - name: data
          mountPath: /var/lib/postgresql/data
  volumeClaimTemplates:
  - metadata:
      name: data
    spec:
      accessModes: ["ReadWriteOnce"]
      storageClassName: standard
      resources:
        requests:
          storage: 100Gi

Example 2: Elasticsearch Cluster

yaml
apiVersion: apps/v1
kind: StatefulSet
metadata:
  name: elasticsearch
spec:
  serviceName: elasticsearch
  replicas: 3
  selector:
    matchLabels:
      app: elasticsearch
  template:
    metadata:
      labels:
        app: elasticsearch
    spec:
      containers:
      - name: elasticsearch
        image: docker.elastic.co/elasticsearch/elasticsearch:8.10.0
        env:
        - name: discovery.type
          value: "zen"
        - name: cluster.name
          value: "es-cluster"
        - name: node.name
          valueFrom:
            fieldRef:
              fieldPath: metadata.name
        - name: discovery.seed_hosts
          value: "elasticsearch-0.elasticsearch,elasticsearch-1.elasticsearch,elasticsearch-2.elasticsearch"
        ports:
        - containerPort: 9200
        - containerPort: 9300
        volumeMounts:
        - name: data
          mountPath: /usr/share/elasticsearch/data
  volumeClaimTemplates:
  - metadata:
      name: data
    spec:
      accessModes: ["ReadWriteOnce"]
      storageClassName: standard
      resources:
        requests:
          storage: 200Gi

Part 9: Common Commands

bash
# Create a StatefulSet
kubectl apply -f statefulset.yaml

# List StatefulSets
kubectl get statefulsets
kubectl get sts

# Describe a StatefulSet
kubectl describe statefulset postgres

# Scale a StatefulSet
kubectl scale statefulset postgres --replicas=5

# Delete a StatefulSet (PVCs remain)
kubectl delete statefulset postgres

# Delete a StatefulSet and PVCs
kubectl delete statefulset postgres --cascade=foreground

# View Pods in a StatefulSet
kubectl get pods -l app=postgres

# View PVCs
kubectl get pvc -l app=postgres

Summary

AspectStatefulSet
PurposeManage stateful applications
Pod namingOrdered (web-0, web-1, web-2)
Network identityStable hostnames
StoragePer-Pod PersistentVolumeClaims
ScalingOrdered, sequential
UpdatesOrdered rolling updates
Use casesDatabases, message queues, distributed systems

StatefulSets are the foundation for running stateful applications in Kubernetes. They provide stable network identities, persistent storage, and ordered operations essential for databases and distributed systems.


Learn More

Practice StatefulSets with hands-on exercises in our interactive labs:
https://devops.trainwithsky.com

Comments

Popular posts from this blog

🌐 Holographic Communications & 6G: The Future of Immersive Connectivity

  🌐 Holographic Communications & 6G: The Future of Immersive Connectivity 🚀 Introduction As the world moves towards 6G , a revolutionary technology is set to redefine digital interactions: Holographic Communications . Imagine real-time, 3D holographic video calls, immersive remote collaboration, and lifelike virtual experiences —all powered by ultra-fast, ultra-low-latency 6G networks . This topic explores Holographic Communications , its impact on various industries, key enabling technologies, and how 6G will bring this futuristic concept to reality . Shape Your Future with AI & Infinite Knowledge...!! Want to Generate Text-to-Voice, Images & Videos? http://www.ai.skyinfinitetech.com Read In-Depth Tech & Self-Improvement Blogs http://www.skyinfinitetech.com Watch Life-Changing Videos on YouTube https://www.youtube.com/@SkyInfinite-Learning Transform Your Skills, Business & Productivity – Join Us Today! 🔍 1. What is Holographic Communication? Hologr...

How to Use SKY TTS: The Complete, Step-by-Step Guide for 2025

 What is SKY TTS? SKY TTS  is a free, next-generation  AI audio creation platform  that brings together high-quality  Text-to-Speech ,  Speech-to-Text , and a full suite of professional  audio editing tools  in one seamless experience. Our vision is simple — to make advanced audio technology  free, accessible, and effortless  for everyone. From creators and educators to podcasters, developers, and businesses, SKY TTS helps users produce  studio-grade voice content  without expensive software or technical skills. With support for  70+ languages, natural voices, audio enhancement, waveform generation, and batch automation , SKY TTS has become a trusted all-in-one toolkit for modern digital audio workflows. Why Choose SKY TTS? Instant Conversion:  Enjoy rapid text-to-speech generation, even with large documents. Advanced Voice Settings:   Adjust speed, pitch, and style for a personalized listening experience. Multi-...

📊 Monitoring & Logging in Kubernetes – Tools like Prometheus, Grafana, and Fluentd

  Monitoring & Logging in Kubernetes – Tools like Prometheus, Grafana, and Fluentd Monitoring and logging are essential for maintaining a healthy and well-performing Kubernetes cluster. In this guide, we’ll cover why monitoring is important, key monitoring tools like Prometheus and Grafana, and logging tools like Fluentd to help you gain visibility into your cluster’s performance and logs. Shape Your Future with AI & Infinite Knowledge...!! Want to Generate Text-to-Voice, Images & Videos? http://www.ai.skyinfinitetech.com Read In-Depth Tech & Self-Improvement Blogs http://www.skyinfinitetech.com Watch Life-Changing Videos on YouTube https://www.youtube.com/@SkyInfinite-Learning Transform Your Skills, Business & Productivity – Join Us Today! 🚀 Introduction In today’s fast-paced cloud-native environment, Kubernetes has emerged as the de-facto container orchestration platform. But deploying and managing applications in Kubernetes is just half the ba...