# CloudNativePG: a Kubernetes operator that runs PostgreSQL without Patroni

> CloudNativePG replaces external failover tooling with the Kubernetes API itself. Here is how its reconciliation loop works, how to install it, and where it stops being the right choice.

**cloudnative-pg/cloudnative-pg** — The most popular Kubernetes Operator for PostgreSQL.

- Repository: https://github.com/cloudnative-pg/cloudnative-pg
- Website: https://cloudnative-pg.io
- Stars: 9,382 · Forks: 777
- Language: Go
- License: Apache-2.0
- Published: 2026-09-21 · Updated: 2026-09-21 · Language: en
- Canonical page: https://hysenlabs.com/projects/cloudnative-pg-cloudnative-pg

## The problem CloudNativePG solves for Kubernetes teams

Running PostgreSQL on Kubernetes is not hard. Keeping a primary and its standbys consistent while pods are rescheduled is. The usual answer is to bolt on Patroni, repmgr or Stolon and let a separate agent decide who is primary. CloudNativePG takes the opposite position: the Kubernetes API is the control plane, and the operator is the only thing making decisions.

The README frames this as a Kubernetes-native approach to primary/standby management, aimed at what it calls "PostgreSQL experts for Kubernetes administrators." The target user is a platform team that already treats Kubernetes as the source of truth and does not want a second, parallel state machine that can disagree with it. If your organization still runs PostgreSQL on virtual machines and manages failover with a DBA on call, the pitch is weaker, because the operator assumes the cluster resource is authoritative.

## How the operator reconciles a Cluster resource

The core object is the Cluster custom resource. Its status is exposed directly through the Kubernetes API, so a failover is not a hidden event inside an agent process; it is a field change you can read with kubectl. The README lists the automated actions the operator performs: electing a new primary when the current one fails, provisioning or removing persistent volumes, secrets and config maps when the replica count changes, keeping service endpoints current, and running rolling updates.

That last one is the clearest illustration of the design. On an image update the operator follows a rolling strategy: replicas are updated first, then the primary is moved with a controlled switchover rather than a hard failover. The distinction matters, because a switchover drains the primary before promotion while a failover does not.

The operator also manages secondary resources beyond Cluster: Backup, ScheduledBackup, ClusterImageCatalog, ImageCatalog, Database, Pooler, Publication and Subscription. Extensibility goes through the CNPG-I plugin interface rather than through patched images, which follows from the immutable application container model the README cites. The distributed image is built on distroless and runs as UID 65532, so there is no shell inside the operator container to debug with.

## Installing CloudNativePG and creating a first cluster

The README points to the Quickstart Guide at cloudnative-pg.io/docs/devel/quickstart/ as the recommended entry point, and the repository also ships Helm charts referenced from the project site. The exact chart name and values file are not reproduced in the README, so check the Quickstart before running anything.

The operator itself is a controller-runtime based Go binary. The build target in the Makefile defaults to `ghcr.io/cloudnative-pg/cloudnative-pg-testing`, which is the testing image, not a production tag; install from the released manifests or the published chart instead of building that default.

Once the operator is running, a cluster is a single namespaced object. The README does not print a manifest, but it does describe the shape: instances, storage, and the image reference all live in the spec, and the status reports the current primary. After applying it, `kubectl get cluster` shows the instances column, and `kubectl describe cluster` shows the primary pod name in the status.

The repository also builds a kubectl plugin, listed under the project topics. It is distributed separately from the operator image, so installing the operator does not install the plugin.

## Where CloudNativePG is the wrong tool

The scope section is unusually blunt, and it is the best guide to when to walk away. CloudNativePG is Kubernetes only, PostgreSQL only, and does not support forks. Features from PostgreSQL forks are considered only if they can be integrated as extensions or pluggable frameworks. If you run a managed fork with its own storage engine, the operator will not manage it, and the CNPG-I interface is the only sanctioned path to extend behavior.

It is also explicitly not a general-purpose database operator. Teams standardizing on one operator for PostgreSQL and MariaDB will not get that here.

There is a second constraint that the README implies rather than states. Because the operator owns persistent volumes, secrets, config maps and service endpoints, anything you create by hand inside the managed namespace can be reconciled away. The README does not document an escape hatch for hand-managed resources, and it does not document rollback behavior for the operator itself. If you need to pin a specific operator version and reverse an upgrade, verify that procedure against the release notes before you need it.

## CloudNativePG versus Patroni-based operators

The comparison that matters is architectural, not feature-level. Patroni-based deployments keep a distributed configuration store and a per-node agent; the agent holds the failover logic and Kubernetes is mostly a scheduler. CloudNativePG removes the agent and puts the decision in the operator, which reads and writes the Cluster resource. The README states this directly: instead of relying on external high-availability tools like Patroni, repmgr or Stolon, it integrates with the Kubernetes API.

The practical difference shows up during an incident. With an agent-based setup you inspect the agent's view of the cluster, which may lag the API server. With CloudNativePG the status field is the view, and kubectl is the interface. The trade-off runs the other way too: an operator that owns the lifecycle is harder to partially adopt. You cannot easily keep Patroni in charge of failover while letting CloudNativePG handle backups, because the operator expects to own the whole path. Teams migrating from an existing Patroni cluster should treat it as a cutover, not a gradual merge.

## Maintenance, releases and the Apache-2.0 licence

The last push to the default branch was on 2026-09-21 and the repository is not archived, so the project is being worked on. Three releases landed on 2026-06-29: v1.30.0, v1.29.2 and v1.28.4. That pattern, a feature release alongside patches on the two previous minor lines, tells you the supported upgrade window is roughly three minor versions. Plan to move at least once a year.

Upgrade cost is not just the operator image. The CRDs, the operator deployment and the running PostgreSQL pods move together, and the README describes rolling updates that end in a controlled switchover of the primary. That switchover is a brief write interruption, so schedule it. Because updates follow an immutable container model, there is no in-place patching of the PostgreSQL image; you change the image reference and let the operator roll it.

The licence is Apache-2.0, which permits commercial use and modification with the usual notice and patent terms. The repository also carries an OpenSSF Best Practices badge and a CLOMonitor badge, and there is a commercial support page linked from the README. None of this is legal advice; if you redistribute a modified operator, read the LICENSE file at the repository root rather than a summary.

## Conclusion

Adopt CloudNativePG if you already run vanilla Kubernetes, want PostgreSQL state visible through kubectl, and accept that backups, upgrades and failover all move through the operator. Do not adopt it if you need MySQL or MariaDB, run a PostgreSQL fork, or want a database outside Kubernetes; the README states the project is dedicated to vanilla Kubernetes and vanilla PostgreSQL and does not support forks. Before rolling it into production, verify the version skew between the operator and your Kubernetes API server, confirm which object storage your Backup resources target, and check that your persistent volume provisioner supports the snapshot API the operator expects.

## FAQ

### What is a CloudNativePG operator?

It is the core component of CloudNativePG, a Kubernetes operator that manages the full operational lifecycle of PostgreSQL clusters, from deployment to ongoing maintenance. It reconciles a Cluster custom resource and performs actions such as failover, replica scaling and rolling updates.

### How can I deploy Postgres to Kubernetes?

Install the CloudNativePG operator, then create a Cluster resource in the target namespace. The README directs new users to the Quickstart Guide at cloudnative-pg.io/docs/devel/quickstart/ for the concrete steps.

### How do I use CloudNativePG?

The README points to the Quickstart Guide as the best way to get started, and the project publishes Helm charts as well. The README does not reproduce the chart name or the install commands, so follow the Quickstart for the current procedure.

### What is CloudNativePG?

CloudNativePG is an open-source platform for managing PostgreSQL databases in Kubernetes, covering the operational lifecycle through its core component, the CloudNativePG operator. It is dedicated to vanilla Kubernetes and vanilla PostgreSQL, and the README states it is not a general-purpose database operator.

## Sources

- [cloudnative-pg/cloudnative-pg on GitHub](https://github.com/cloudnative-pg/cloudnative-pg)
- [License: Apache-2.0](https://github.com/cloudnative-pg/cloudnative-pg/blob/main/LICENSE)
- [Project website](https://cloudnative-pg.io)
- [README](https://github.com/cloudnative-pg/cloudnative-pg/blob/main/README.md)
- [Releases](https://github.com/cloudnative-pg/cloudnative-pg/releases)

---

Hysen Labs editorial analysis, written from the project's own repository and release notes. Cite the canonical page: https://hysenlabs.com/projects/cloudnative-pg-cloudnative-pg
