BookNest's StatefulSet (StatefulSets and PostgreSQL) has no replica, failover or scheduled backup. CloudNativePG 171,411 (github.com/cloudnative-pg/cloudnative-pg (https://github.com/cloudnative-pg/cloudnative-pg 9,370 ), Apache-2.0, from EDB, CNCF Sandbox since January 2025) adds all three. It creates Pods, PVCs, Services <name>-rw (primary), -ro and -r, and a Secret <name>-app with the keys the chart's db.secret expects:
apiVersion: postgresql.cnpg.io/v1
kind: Cluster
metadata: { name: booknest-db, namespace: booknest-helm }
spec:
instances: 2 # a primary and a streaming replica
storage: { size: 1Gi, storageClass: booknest-data }
bootstrap: { initdb: { database: booknest, owner: booknest } }
smartShutdownTimeout: 10 # the default 180 s waits that long for clients to disconnectR=https://raw.githubusercontent.com/cloudnative-pg/cloudnative-pg/release-1.30/releases
kubectl apply --server-side -f $R/cnpg-1.30.1.yaml >/dev/null
kubectl -n cnpg-system rollout status deployment/cnpg-controller-manager >/dev/null
k() { kubectl -n booknest-helm "$@"; }
k apply -f helm/booknest-db.yaml
k wait --for=condition=Ready cluster/booknest-db --timeout=10m >/dev/null
helm upgrade booknest helm/booknest -n booknest-helm --reuse-values --wait \
--set postgres.enabled=false,db.host=booknest-db-rw,db.secret=booknest-db-app | grep REVISION
k delete pod booknest-db-1 --wait=false
S0=$(date +%s)
until k get cluster booknest-db | grep -q 'healthy.*db-2$'; do sleep 1; done
echo "new primary after $(( $(date +%s) - S0 )) s"; k get cluster booknest-db
helm test booknest -n booknest-helm --logs | grep books
git add k8s/promotion-crd.yaml helm/booknest-db.yaml
git commit -qm "Add a CRD and a CNPG cluster"Output
cluster.postgresql.cnpg.io/booknest-db created REVISION: 6 pod "booknest-db-1" deleted from booknest-helm namespace new primary after 25 s NAME AGE INSTANCES READY STATUS PRIMARY booknest-db 88s 2 2 Cluster in healthy state booknest-db-2 6 books through booknest-web
The API created its schema in the new database, the chart's StatefulSet disappeared, and failover needed no human. Backups and connection pooling are further CRDs of the same operator.