Chapter 6.4 - StatefulSets and Persistent Storage
Learning Objectives
By the end of this chapter, you will be able to:
- Understand StatefulSets and their characteristics
- Deploy stateful applications with persistent storage
- Understand stable Pod identities
- Use volumeClaimTemplates
- Understand the differences with Deployments
- Manage ordered scaling
Introduction
Deployments are perfect for stateless applications. For stateful applications like databases, you need StatefulSets.
What Is a StatefulSet?
A StatefulSet manages deployments and scaling of a set of Pods with:
- Stable identities: Predictable Pod names (web-0, web-1, web-2)
- Persistent storage: Each Pod has its own volume
- Guaranteed ordering: Ordered deployment and scaling
- Headless service: Service without ClusterIP for DNS discovery
Key Characteristics
1. Stable Identities
Pod Names:
web-0web-1web-2
Advantages:
- Stable identity even after restart
- Stable DNS for service discovery
- Storage tied to identity
2. Individual Persistent Storage
Each Pod has its own persistent volume created via volumeClaimTemplates.
3. Guaranteed Ordering
Deployment: Ascending order (0, 1, 2)
Deletion: Descending order (2, 1, 0)
Scaling: Ordered
4. Headless Service
A headless service (without ClusterIP) enables stable DNS discovery.
apiVersion: v1
kind: Service
metadata:
name: web-service
spec:
clusterIP: None # Headless service
selector:
app: web
ports:
- port: 80
DNS:
web-0.web-service.default.svc.cluster.localweb-1.web-service.default.svc.cluster.localweb-2.web-service.default.svc.cluster.local
Complete Example
Step 1: Create the Headless Service
apiVersion: v1
kind: Service
metadata:
name: web-service
spec:
clusterIP: None
selector:
app: web
ports:
- port: 80
name: http
Step 2: Create the StatefulSet
apiVersion: apps/v1
kind: StatefulSet
metadata:
name: web-statefulset
spec:
serviceName: "web-service" # Must match the headless service
replicas: 3
selector:
matchLabels:
app: web
template:
metadata:
labels:
app: web
spec:
containers:
- name: nginx
image: nginx:1.20
ports:
- containerPort: 80
name: http
volumeMounts:
- name: www
mountPath: /usr/share/nginx/html
volumeClaimTemplates:
- metadata:
name: www
spec:
accessModes: [ "ReadWriteOnce" ]
storageClassName: "fast-ssd"
resources:
requests:
storage: 10Gi
Result:
- 3 Pods:
web-0,web-1,web-2 - 3 PVCs:
www-web-0,www-web-1,www-web-2 - Each Pod has its own volume
VolumeClaimTemplates
volumeClaimTemplates automatically create a PVC for each Pod.
Characteristics:
- Automatic PVC creation
- Name:
{template-name}-{pod-name} - Each Pod has its own PVC
- PVCs are deleted only if the Pod is deleted
Differences: Deployment vs StatefulSet
| Characteristic | Deployment | StatefulSet |
|---|---|---|
| Identity | Random (random-abc123) | Stable (web-0, web-1) |
| Storage | Shared or ephemeral | Individual persistent |
| Scaling | Random | Guaranteed order |
| Service | Normal ClusterIP | Headless (DNS) |
| Use Case | Stateless apps | Stateful apps (DB, etc.) |
| Restart | New name | Same name |
Use Cases
1. Databases
apiVersion: apps/v1
kind: StatefulSet
metadata:
name: postgres
spec:
serviceName: postgres
replicas: 3
template:
spec:
containers:
- name: postgres
image: postgres:14
env:
- name: PGDATA
value: /var/lib/postgresql/data/pgdata
volumeMounts:
- name: postgres-data
mountPath: /var/lib/postgresql/data
volumeClaimTemplates:
- metadata:
name: postgres-data
spec:
accessModes: [ "ReadWriteOnce" ]
storageClassName: "fast-ssd"
resources:
requests:
storage: 50Gi
2. Stateful Applications
- Distributed file systems
- Caches with persistent data
- Applications with stable identities
3. Services Requiring Ordering
- Master-slave replication
- Applications with quorum
- Services with leader election
Scaling
Scaling Up
kubectl scale statefulset web-statefulset --replicas=5
Result: Creates web-3 then web-4 in order.
Scaling Down
kubectl scale statefulset web-statefulset --replicas=2
Result: Deletes web-2 then web-1 in descending order.
Important: PVCs are not automatically deleted. Delete them manually if needed.
Updates
Rolling Update
spec:
updateStrategy:
type: RollingUpdate
template:
spec:
containers:
- name: nginx
image: nginx:1.21 # New version
Process:
- Update
web-2(last) - Update
web-1 - Update
web-0(first)
OnDelete
spec:
updateStrategy:
type: OnDelete
Process: Updates only when a Pod is manually deleted.
Useful Commands
Create and Manage
# Create a StatefulSet
kubectl apply -f statefulset.yaml
# View StatefulSets
kubectl get statefulset
kubectl get sts
# View Pods
kubectl get pods -l app=web
# Details
kubectl describe statefulset web-statefulset
Scaling
# Increase replicas
kubectl scale statefulset web-statefulset --replicas=5
# Decrease replicas
kubectl scale statefulset web-statefulset --replicas=2
View Volumes
# View created PVCs
kubectl get pvc
# View details
kubectl describe pvc www-web-0
Best Practices
1. Use for Stateful Applications
StatefulSets only for stateful applications. Use Deployments for stateless.
2. Headless Service Required
Always create a headless service for DNS discovery.
3. Appropriate Storage
Choose the right access mode (RWO for databases).
4. Backups
Set up regular volume backups.
5. Monitoring
Monitor the state and performance of each Pod.
Summary
In this chapter, you learned:
StatefulSet: Manages stateful applications with stable identities
Characteristics: Predictable names, individual volumes, guaranteed ordering, headless service
volumeClaimTemplates: Automatic PVC creation per Pod
Use cases: Databases, stateful applications, ordered services
Differences: Stable vs random identity, individual vs shared storage
Scaling: Guaranteed ordering (ascending for up, descending for down)
Updates: RollingUpdate (reverse) or OnDelete
Next Steps
Module 7: Advanced Workloads (in-depth StatefulSets, DaemonSets, Jobs)
Lab 6.4: StatefulSet with Persistent Storage
Chapter created: December 2024