A Deployment treats pods as interchangeable. A StatefulSet gives each pod a stable name (db-0, db-1), ordered startup, and its own volume.
apiVersion: v1
kind: Service
metadata: { name: db }
spec:
clusterIP: None # headless service gives each pod a DNS name
selector: { app: db }
ports: [{ port: 5432 }]
---
apiVersion: apps/v1
kind: StatefulSet
metadata: { name: db }
spec:
serviceName: db
replicas: 3
selector: { matchLabels: { app: db } }
template:
metadata: { labels: { app: db } }
spec:
containers:
- name: postgres
image: postgres:14
volumeMounts: [{ name: data, mountPath: /var/lib/postgresql/data }]
volumeClaimTemplates:
- metadata: { name: data }
spec:
accessModes: [ReadWriteOnce]
resources: { requests: { storage: 20Gi } }
Pods get names like db-0.db.default.svc. Deleting the StatefulSet does not delete the volumes. Running databases on Kubernetes needs replication, backups and tested failover; for many teams a managed database such as RDS is the safer choice.