A StatefulSet gives Pods stable identities and per-replica claims. This single-replica PostgreSQL lab demonstrates a headless Service, Secret-backed password, volumeClaimTemplates, readiness, backup, and controlled deletion.
1. Prepare and execute
Confirm the active kubeconfig context and namespace before applying changes. Save commands and manifests in version control without credentials.
kubectl create namespace postgres
kubectl -n postgres create secret generic postgres-auth
--from-literal=POSTGRES_PASSWORD="$(openssl rand -base64 32)"
2. Declarative configuration
Save the following example in a clearly named YAML file, review it, then use server-side dry-run when the API is available.
apiVersion: v1
kind: Service
metadata: {name: postgres, namespace: postgres}
spec: {clusterIP: None, selector: {app: postgres}, ports: [{port: 5432}]}
---
apiVersion: apps/v1
kind: StatefulSet
metadata: {name: postgres, namespace: postgres}
spec:
serviceName: postgres
replicas: 1
selector: {matchLabels: {app: postgres}}
template:
metadata: {labels: {app: postgres}}
spec:
containers:
- name: postgres
image: postgres:17.5-alpine
envFrom: [{secretRef: {name: postgres-auth}}]
ports: [{containerPort: 5432}]
readinessProbe:
exec: {command: [sh, -c, 'pg_isready -U postgres']}
volumeMounts: [{name: data, mountPath: /var/lib/postgresql/data}]
volumeClaimTemplates:
- metadata: {name: data}
spec:
accessModes: [ReadWriteOnce]
resources: {requests: {storage: 5Gi}}
3. Verify the result
A successful command is not enough. Inspect resource state, conditions, events, endpoints, logs, and an end-to-end request where applicable.
kubectl apply -f postgres.yaml
kubectl -n postgres rollout status statefulset/postgres --timeout=5m
kubectl -n postgres get pod,pvc
kubectl -n postgres exec postgres-0 -- psql -U postgres -c 'select version();'
kubectl -n postgres exec postgres-0 -- pg_dumpall -U postgres > postgres-backup.sql
4. Troubleshooting
Pending claims indicate a StorageClass or topology issue. CrashLoopBackOff frequently means filesystem permissions, an incompatible existing data directory, or missing configuration. One replica is not high availability.
5. Rollback and cleanup
Review the exact target before deleting resources, especially namespaces, claims, Secrets, and cluster-wide add-ons.
kubectl delete -f postgres.yaml
# PVCs remain intentionally; review before deleting:
kubectl -n postgres get pvc
Production checklist
- The active context, namespace, and target version were verified.
- Manifests passed client or server-side validation.
- Resource conditions and recent events show no unresolved error.
- Access, network exposure, resource limits, persistence, and rollback were reviewed.
- Commands and expected output were recorded for the operating team.
References: topic documentation and Kubernetes documentation.