Build Daily

Tinley Park · October 29, 2026
toolCloudNativePG community (CNCF Sandbox; originally created by EDB)applied

CloudNativePG

A Kubernetes operator that runs PostgreSQL as a Cluster custom resource: it creates one pod and one volume per instance, manages streaming replication, failover and rolling updates with its own controller, and publishes rw/ro/r Services. Backups go through the Barman Cloud plugin, which archives WAL continuously and stores base backups in S3, GCS or Azure, so a cluster can be restored to any point in its recovery window. Apache 2.0 and free. Fits any team that wants Postgres on Kubernetes declared in Git, with point-in-time recovery, and without a managed database service.

Updated October 17, 2026

CloudNativePG (CNPG) is an open-source Kubernetes operator for PostgreSQL. A single Cluster manifest declares the instances, storage, configuration and backup target, and the operator keeps the running database in that state: it provisions pods and volumes, sets up replication, promotes a replica when the primary fails and points the Services at the new primary. Its companion, the Barman Cloud plugin, ships the write-ahead log and base backups to object storage so that a database can be rebuilt at any moment inside its retention window.

What it is

The operator manages vanilla PostgreSQL on vanilla Kubernetes only. It does not support forks of Postgres or other databases. Licence is Apache 2.0. EDB created the project, and it was accepted into the CNCF as a Sandbox project in January 2025.

The current minor line is 1.30 (1.30.0 on 2026-06-29, 1.30.1 on 2026-09-23, released the same day as 1.29.3). According to the project's support table, 1.30 supports Kubernetes 1.34 to 1.36 and PostgreSQL 14 to 18, and its end of life is about December 2026. A minor release stays supported until three months after the next minor ships. The 1.30.1 default operand image is PostgreSQL 18.6 on Debian 13 (trixie).

The resource family is Cluster, Backup, ScheduledBackup, Pooler (PgBouncer), Database, Publication, Subscription, ImageCatalog / ClusterImageCatalog and, new in 1.30, DatabaseRole for one role per manifest. The operator extends through CNPG-I, a gRPC plugin interface. The Barman Cloud plugin (plugin-barman-cloud, also Apache 2.0) is the first major plugin. Its current release is v0.15.1 (2026-09-30, bundling Barman 3.20.1). It needs CloudNativePG 1.26 or later and cert-manager. It replaces the in-tree .spec.backup.barmanObjectStore support, which has been deprecated since 1.26 and is now scheduled for removal in 1.31.0.

How it works

The operator does not use a StatefulSet. Its own controller creates one pod and one PVC for each instance, so it can tell a primary from a replica, resize volumes and update replicas before it does a switchover of the primary. Each pod runs an instance manager as its entry point. The instance manager starts Postgres, reports health to the operator and serves metrics. The operator creates three ClusterIP Services for each cluster: <cluster>-rw (primary only), <cluster>-ro (replicas only) and <cluster>-r (any instance). Applications that use -rw follow the primary across failovers without a change in configuration.

With the plugin, the operator asks the plugin (over gRPC with TLS) to add a Barman Cloud sidecar to every instance pod. That sidecar runs barman-cloud to archive each WAL segment, to take base backups and to fetch WAL during a restore. An ObjectStore resource holds the bucket path, endpoint, credentials, compression and retention policy. In the bucket, WAL goes under wals/ and base backups go as tarballs under base/.

How CloudNativePG archives, backs up and restores

Step 1 of 5. When it builds an instance pod for a Cluster whose spec.plugins lists barman-cloud.cloudnative-pg.io, the operator calls the plugin. The plugin adds the Barman sidecar to the pod.

Barman Cloud plugin flows: continuous WAL archiving, a scheduled base backup, and a point-in-time restore into a new cluster.

The three paths share the bucket. The archive is continuous, and the base backups set where a restore starts. The retention window therefore sets how far back a point-in-time restore can go. A restore always creates a new Cluster. It never rewinds a running one.

When to use it

Reach for it when:

  • Postgres needs to run inside Kubernetes, declared in Git next to the applications that use it.
  • Point-in-time recovery to object storage is a requirement, not a nice-to-have.
  • Failover, replica scaling and minor-version rolling updates should be automatic.
  • The cluster is self-hosted (homelab, on-prem, edge) and a managed database service is not an option or not wanted.

Skip it when:

  • A managed service (RDS, Cloud SQL, Azure Flexible Server) is already available and its cost is acceptable. A managed service does the same job without an operator to upgrade.
  • The cluster has no reliable persistent storage. CNPG expects a StorageClass, and local-path volumes tie each instance to one node.
  • The database must be a Postgres fork or carry features that only exist in a fork.
  • The team does not want to own WAL, backup and restore drills. The operator automates those jobs, but the team still owns the outcome.

At a glance

Core concepts

  • Cluster — the database: instance count, image, storage, postgresql.parameters, bootstrap (initdb, recovery or pg_basebackup) and plugins.
  • Instance manager — PID 1 in every instance pod. It controls Postgres locally, and the operator talks to it.
  • Services — -rw, -ro and -r per cluster. These default names are reserved. Extra Services can be declared under .spec.managed.services.additional.
  • ObjectStore (barmancloud.cnpg.io/v1) — the bucket, endpoint, credentials, WAL and data options, and retentionPolicy. The docs recommend one ObjectStore per cluster.
  • Backup / ScheduledBackup — on-demand and cron-driven base backups, with method: plugin when the plugin is used.
  • Primary Lease (new in 1.30) — a Kubernetes Lease that serializes promotion. The docs call it a promotion gate, not a fence.

Key facts

Aspect Value
Operator release line 1.30 (1.30.1, 2026-09-23); 1.29 reached end of life 2026-09-29
Plugin release v0.15.1 (2026-09-30), Barman 3.20.1
Kubernetes (1.30 support table) 1.34, 1.35, 1.36
PostgreSQL majors 14 to 18
Plugin prerequisites CNPG 1.26 or later (1.27 or later recommended), cert-manager, same namespace as the operator
Object stores Amazon S3 and S3-compatible stores, Google Cloud Storage, Azure Blob Storage
Licence Apache 2.0 (operator and plugin)

Compared with other Postgres operators

Aspect CloudNativePG Zalando postgres-operator Crunchy PGO
HA mechanism Own controller and instance manager Patroni in StatefulSets Patroni
Backup tool Barman Cloud plugin WAL-G / WAL-E pgBackRest
Governance CNCF Sandbox Zalando Crunchy Data
Licence Apache 2.0 MIT Apache 2.0

How to integrate

Install cert-manager first, then install the operator and the plugin from the official chart repository:

helm repo add cnpg https://cloudnative-pg.github.io/charts
helm repo update
helm upgrade --install cnpg --namespace cnpg-system --create-namespace cnpg/cloudnative-pg
helm upgrade --install plugin-barman-cloud --namespace cnpg-system cnpg/plugin-barman-cloud
kubectl -n cnpg-system rollout status deploy/plugin-barman-cloud

Declare the object store and a cluster that archives to it:

apiVersion: barmancloud.cnpg.io/v1
kind: ObjectStore
metadata:
  name: pg-backups
spec:
  retentionPolicy: "14d"
  configuration:
    destinationPath: s3://postgres/
    endpointURL: http://s3.example.svc:8333   # any S3-compatible endpoint
    s3Credentials:
      accessKeyId:     { name: pg-backup-s3, key: ACCESS_KEY_ID }
      secretAccessKey: { name: pg-backup-s3, key: ACCESS_SECRET_KEY }
    wal:
      compression: gzip
---
apiVersion: postgresql.cnpg.io/v1
kind: Cluster
metadata:
  name: pg
spec:
  instances: 1
  imageName: ghcr.io/cloudnative-pg/postgresql:17
  storage:
    size: 20Gi
  plugins:
    - name: barman-cloud.cloudnative-pg.io
      isWALArchiver: true
      parameters:
        barmanObjectName: pg-backups
---
apiVersion: postgresql.cnpg.io/v1
kind: ScheduledBackup
metadata:
  name: pg-nightly
spec:
  schedule: "0 0 3 * * *"        # six fields: seconds first
  backupOwnerReference: self
  cluster:
    name: pg
  method: plugin
  pluginConfiguration:
    name: barman-cloud.cloudnative-pg.io

A point-in-time restore is a new cluster:

apiVersion: postgresql.cnpg.io/v1
kind: Cluster
metadata:
  name: pg-restore
spec:
  instances: 1
  storage:
    size: 20Gi
  bootstrap:
    recovery:
      source: origin
      recoveryTarget:
        targetTime: "2026-10-16 21:30:00+00"
  externalClusters:
    - name: origin
      plugin:
        name: barman-cloud.cloudnative-pg.io
        parameters:
          barmanObjectName: pg-backups
          serverName: pg

On-demand backups and status come from the kubectl cnpg plugin: kubectl cnpg backup pg --method=plugin --plugin-name=barman-cloud.cloudnative-pg.io and kubectl cnpg status pg.

In the GL stack

CloudNativePG 1.30.1 with the Barman Cloud plugin v0.15.1 runs the shared Postgres on both the beta and the prod cluster. It holds one database for each product, paiddaily.io and sagedaily.io among them.

  • Image. The cluster runs a Postgres 17.11 image with the pgTAP extension added. Product business logic lives in stored procedures.
  • Backups. WAL is archived continuously, and a base backup is taken every night. Both go to the S3 backup store, which is SeaweedFS on the management cluster, in its postgres bucket. Retention is 14 days. A point-in-time restore has been drilled, not only configured. A nightly pg_dump of each database runs as a second, logical copy.
  • Split with Velero. Velero's volume policy skips the CNPG volumes. Barman Cloud is the backup of record for Postgres data, and Velero covers the rest of each namespace.
  • Migration without app changes. The Services keep the names of the Postgres deployment that came before, so every connection string kept working when the database moved under the operator.
  • Beta data. Beta databases are snapshots refreshed from prod.
  • Restarts. Restart an instance by deleting its pod. The operator recreates the pod on the same volume. kubectl rollout restart does nothing useful here because no Deployment or StatefulSet owns the pod.

Gotchas

  • The in-tree backup goes away in 1.31. .spec.backup.barmanObjectStore has been deprecated since 1.26, and the 1.30.0 notes move its removal to 1.31.0. Migrate before that upgrade: translate the stanza into an ObjectStore, then switch the Cluster, the ScheduledBackups and the externalClusters in one change.
  • The plugin lives with the operator. It must be installed in the operator's namespace (normally cnpg-system), and cert-manager must be ready first, or the plugin's certificates are not issued and the install fails.
  • Deployment names differ by install method. The Helm chart creates deploy/plugin-barman-cloud. The kubectl manifest creates deploy/barman-cloud. Runbooks and alerts must use the right name.
  • Leave serverName empty on the ObjectStore. It exists for API compatibility only. Set serverName as a plugin parameter on the Cluster or in externalClusters.
  • Six-field cron. ScheduledBackup.schedule starts with seconds. 0 0 * * * is not the Kubernetes CronJob meaning. Write 0 0 0 * * * for midnight.
  • A restored cluster does not archive by default. Add .spec.plugins to the recovery cluster, and give it its own serverName or path. Barman checks that the WAL archive is empty before the first archive, so a restored cluster that points at the source's archive fails that check.
  • cluster references are immutable since 1.30. A ScheduledBackup, Database, Pooler, Publication or Subscription cannot be pointed at another cluster. The API server rejects the change, so delete and recreate the object.
  • Backup metric names changed. The plugin exports barman_cloud_cloudnative_pg_io_last_available_backup_timestamp, ..._last_failed_backup_timestamp and ..._first_recoverability_point. These replace the older cnpg_collector backup metrics, so update alert rules that use the old names.
  • Plugin upgrades are not zero-downtime. The plugin Deployment uses the Recreate strategy. Extra replicas protect against node loss, not against the short gap during an upgrade.

Risks

  • Fast support window. About one minor release every three months, and each minor is supported only until three months after the next one. 1.30 is due for end of life around December 2026. Plan regular operator upgrades.
  • Backup path in transition. The plugin is at v0.x, and the in-tree path is about to be removed. Expect API and parameter changes, and read the release notes on every bump.
  • Vendor weight. CNCF governance and Apache 2.0 reduce lock-in, but EDB created the project and its engineers remain central to it. Kubernetes distributions other than vanilla, such as OpenShift, are not officially supported or tested.
  • Backups are only as good as the last restore. WAL archiving can fail without notice when a bucket fills or a credential rotates. Alert on the age of the last backup and on archive failures, and drill restores on a schedule.
  • Credentials in the bucket path. The S3 keys can read every base backup and every WAL segment. Scope them to the one bucket, and treat the bucket as production data.

Alternatives

  • Managed Postgres (RDS, Cloud SQL, Azure Flexible Server) — choose it when the database can live outside the cluster and paying for operations is better than running an operator.
  • Zalando postgres-operator — choose it for a Patroni-based HA model and an existing WAL-G backup setup.
  • Crunchy PGO — choose it when the team wants pgBackRest as the backup tool.
  • Plain StatefulSet with scheduled pg_dump — choose it for a single small database where a restore to last night's dump is acceptable and point-in-time recovery is not needed.

Related