PostgreSQL StatefulSet with Persistent Storage
Deploy PostgreSQL as a Kubernetes StatefulSet with persistent volume claims, exec-based readiness probes, and environment variables for database initialization.
Detailed Explanation
PostgreSQL on Kubernetes
Databases require stable network identities and persistent storage — exactly what StatefulSets provide. Unlike Deployments, StatefulSets give each pod a stable hostname and ensure volumes persist across pod restarts and rescheduling.
Key Configuration
apiVersion: apps/v1
kind: StatefulSet
metadata:
name: postgres
labels:
app: "postgres"
spec:
replicas: 1
template:
spec:
containers:
- name: postgres
image: postgres:16-alpine
ports:
- name: postgres
containerPort: 5432
env:
- name: POSTGRES_DB
value: "mydb"
- name: POSTGRES_USER
value: "admin"
- name: POSTGRES_PASSWORD
value: "changeme"
resources:
requests:
cpu: "250m"
memory: "256Mi"
limits:
cpu: "1000m"
memory: "1Gi"
volumeMounts:
- name: pgdata
mountPath: /var/lib/postgresql/data
livenessProbe:
tcpSocket:
port: 5432
initialDelaySeconds: 30
periodSeconds: 10
readinessProbe:
exec:
command:
- "pg_isready"
- "-U"
- "admin"
initialDelaySeconds: 5
periodSeconds: 10
volumes:
- name: pgdata
persistentVolumeClaim:
claimName: pgdata-pvc
Why StatefulSet?
- Stable network identity: Pod is always
postgres-0, enabling predictable DNS (postgres-0.postgres.default.svc.cluster.local) - Persistent volumes: PVCs survive pod restarts and rescheduling
- Ordered deployment: Pods are created and terminated in order (critical for primary/replica setups)
Readiness Probe
The exec-based readiness probe runs pg_isready inside the container. This is more accurate than a TCP check because it verifies that PostgreSQL is actually accepting connections, not just that the port is open. The -U admin flag checks if the specific user can connect.
Production Considerations
In production, you should:
- Use Kubernetes Secrets instead of plain-text environment variables for passwords
- Set up WAL archiving for point-in-time recovery
- Consider an operator like CloudNativePG for automated failover
- Use a larger PVC with a storage class that supports snapshots
Use Case
Deploying a PostgreSQL database for development or staging environments in Kubernetes, with persistent data that survives pod restarts. For production, consider using a database operator.