CloudNativePG¶
Every chart that needs PostgreSQL ships its own, each upgraded by whoever
maintains the chart that buried it. CloudNativePG is one operator in
cnpg-system and a Cluster resource per database.
At a glance¶
| Namespace | cnpg-system for the operator; each database in its workload's namespace |
| Stage | 03-controllers; it brings its own CRDs and everything that uses it comes later |
| Depends on | Rook-Ceph for the database volumes |
| If it is down | Running databases keep running; failover, upgrades and new clusters stop |
| Health check | kubectl get clusters.postgresql.cnpg.io -A → Cluster in healthy state |
| Files | payload/platform/cloudnative-pg/ |
Configuration¶
A Cluster is not a StatefulSet with a nicer name:
| It handles | Instead of |
|---|---|
| Primary election and failover between instances | A single pod that takes the database down with it |
-rw and -ro Services that follow the primary |
Hardcoding a pod name and being wrong after a restart |
| Rolling minor-version upgrades, replicas first | A StatefulSet image bump and hope |
Generated credentials in a -app Secret |
A password in Git, or a manual kubectl create secret |
| A PodMonitor and an upstream Grafana dashboard | No visibility until something is already wrong |
Major-version upgrades are declarative too, but offline: ArgoCD reports Degraded while one runs and the workload is down for its duration. Read the upstream guide before merging one.
Databases claim rook-ceph-block, so Ceph's three copies already sit under
every database and a single-instance Cluster is a defensible default: the
data survives a node loss even when the process does not. Where a workload
cannot tolerate the restart, instances: 3 is the change.
Usage¶
The contract¶
Every workload that needs PostgreSQL gets a CloudNativePG Cluster. No
chart-bundled database, ever. A bundled Postgres moves when the
application's chart decides — a major version jump inside someone else's patch
release; a Cluster moves when its imageName changes, a Renovate PR with a
human in front of it. Most bundled subcharts are also Bitnami's, whose
registry terms keep changing. The rule for the
workloads repository:
- Disable the subchart (
postgresql.enabled: falseorinternalDatabase.enabled: false) and point the chart at theCluster. - Never copy the password. CloudNativePG writes
username,password,host,port,dbnameand a ready-madeurito<cluster-name>-app; charts take those through anexistingSecretblock, and applications without one readurias an environment variable. Nothing goes into Git or OpenBao — nothing outside the cluster ever needs this secret. - Put the
Clusterin the workload's namespace, notcnpg-system, so the namespace'sCiliumNetworkPolicygoverns port 5432 and deleting the namespace takes the database with it.
Health check¶
Cluster in healthy state is the phrase; ArgoCD's built-in health check reads
the same field, which lets a sync wave wait for a database before the
application in front of it. The plugin prints the primary, replication lag,
WAL position and last failover.
Pitfalls¶
Backups are Velero's job, for now
CloudNativePG can stream WAL to S3 and the object store exists, but nothing is configured to do it yet. A workload database is protected exactly as far as its PVC is: a crash-consistent CSI snapshot, recovered to a snapshot boundary rather than a point in time. See Backups & Recovery.