Creating StatefulSets: Setting Up Ordered Rooms
Creating StatefulSets is like setting up ordered hotel rooms. Define room requirements. Create ordered rooms. Stable identity. That's creating StatefulSets.
🎯 The Big Picture​
Think of creating StatefulSets like setting up ordered hotel rooms. Define room requirements (YAML). Create ordered rooms (StatefulSet). Stable room numbers (stable identity). That's creating StatefulSets.
Creating StatefulSets defines stateful application specifications. YAML or kubectl. Headless service required. Volume claim templates. Essential for stateful apps.
The Ordered Room Setup Analogy​
Think of creating StatefulSets like setting up ordered rooms:
YAML definition: Room requirements
- Define room specifications
- Ordered room management
- Stable identity
Headless Service: Room directory
- Required for StatefulSet
- DNS entries
- Stable names
Volume Claim Templates: Storage per room
- Each room gets storage
- Individual PVCs
- Persistent
Once you see it this way, creating StatefulSets makes perfect sense.
Prerequisites: Headless Service​
Create headless service first:
apiVersion: v1
kind: Service
metadata:
name: db
spec:
clusterIP: None # Headless
selector:
app: database
ports:
- port: 5432
name: postgres
Why required:
- DNS entries
- Stable identity
- Pod discovery
Think of it as: Room directory. Required. Creates DNS.
Creating StatefulSet​
Basic StatefulSet:
apiVersion: apps/v1
kind: StatefulSet
metadata:
name: database
spec:
serviceName: db # Must match headless service
replicas: 3
selector:
matchLabels:
app: database
template:
metadata:
labels:
app: database
spec:
containers:
- name: db
image: postgres:16-alpine
ports:
- containerPort: 5432
volumeMounts:
- name: db-storage
mountPath: /var/lib/postgresql/data
volumeClaimTemplates:
- metadata:
name: db-storage
spec:
accessModes:
- ReadWriteOnce
resources:
requests:
storage: 20Gi
storageClassName: standard
What this does:
- Creates 3 database pods
- Ordered deployment
- Individual storage per pod
- Stable identity
Think of it as: Ordered room management. 3 rooms. Ordered. Individual storage.
Complete Production StatefulSet​
Production-ready StatefulSet:
apiVersion: apps/v1
kind: StatefulSet
metadata:
name: production-db
namespace: production
labels:
app: database
env: production
spec:
serviceName: db
replicas: 3
podManagementPolicy: OrderedReady
updateStrategy:
type: RollingUpdate
rollingUpdate:
partition: 0
selector:
matchLabels:
app: database
env: production
template:
metadata:
labels:
app: database
env: production
spec:
containers:
- name: postgres
image: postgres:16-alpine
ports:
- containerPort: 5432
name: postgres
env:
- name: POSTGRES_PASSWORD
valueFrom:
secretKeyRef:
name: db-secret
key: password
- name: PGDATA
value: /var/lib/postgresql/data/pgdata
volumeMounts:
- name: db-storage
mountPath: /var/lib/postgresql/data
resources:
requests:
memory: "512Mi"
cpu: "500m"
limits:
memory: "2Gi"
cpu: "2000m"
livenessProbe:
exec:
command:
- pg_isready
- -U
- postgres
initialDelaySeconds: 30
periodSeconds: 10
readinessProbe:
exec:
command:
- pg_isready
- -U
- postgres
initialDelaySeconds: 5
periodSeconds: 5
volumeClaimTemplates:
- metadata:
name: db-storage
spec:
accessModes:
- ReadWriteOnce
resources:
requests:
storage: 50Gi
storageClassName: fast-ssd
That's a complete StatefulSet. Production-ready. Comprehensive.
Real-World Example: Complete Creation​
Step 1: Create headless service:
apiVersion: v1
kind: Service
metadata:
name: db
spec:
clusterIP: None
selector:
app: database
ports:
- port: 5432
Step 2: Create StatefulSet:
apiVersion: apps/v1
kind: StatefulSet
metadata:
name: database
spec:
serviceName: db
replicas: 3
selector:
matchLabels:
app: database
template:
metadata:
labels:
app: database
spec:
containers:
- name: db
image: postgres:16-alpine
volumeMounts:
- name: db-storage
mountPath: /var/lib/postgresql/data
volumeClaimTemplates:
- metadata:
name: db-storage
spec:
accessModes:
- ReadWriteOnce
resources:
requests:
storage: 20Gi
Step 3: Verify:
kubectl get statefulset database
kubectl get pods -l app=database
Output:
NAME READY STATUS RESTARTS AGE
database-0 1/1 Running 0 1m
database-1 1/1 Running 0 2m
database-2 1/1 Running 0 3m
Step 4: Check storage:
kubectl get pvc
Output:
NAME STATUS VOLUME CAPACITY ACCESS MODES STORAGECLASS AGE
db-storage-db-0 Bound pv-xxx 20Gi RWO standard 1m
db-storage-db-1 Bound pv-yyy 20Gi RWO standard 2m
db-storage-db-2 Bound pv-zzz 20Gi RWO standard 3m
That's complete creation. StatefulSet working. Individual storage.
My Take: StatefulSet Creation Strategy​
Here's what I do:
Always:
- Create headless service first
- Use volume claim templates
- Set appropriate replicas
- Use health checks
Production:
- Complete definitions
- Resource limits
- Health checks
- Backup strategy
The key: Headless service first. Volume claim templates. Health checks. Production-ready.
Memory Tip: The Ordered Room Setup Analogy​
Creating StatefulSets = Setting up ordered rooms
Headless Service: Room directory StatefulSet: Ordered rooms Volume templates: Storage per room
Once you see it this way, creating StatefulSets makes perfect sense.
Common Mistakes​
- No headless service: DNS won't work
- Wrong serviceName: Doesn't match
- No volume claim templates: No persistent storage
- Not understanding ordering: Confusion
- Using for stateless: Wrong tool
Key Takeaways​
- Create headless service first - Required for StatefulSet
- Use volume claim templates - Individual storage per pod
- serviceName must match - Critical requirement
- Ordered deployment - Sequential creation
- Use for stateful apps - Databases, queues
What's Next?​
Now that you understand creating StatefulSets, let's learn about StatefulSet scaling. Next: StatefulSet Scaling.
Remember: Creating StatefulSets is like setting up ordered rooms. Headless service first. Volume claim templates. Stable identity. Use for stateful apps. Essential.