Upgrade

This page covers upgrading the Alauda build of CloudNativePG operator. PostgreSQL server version upgrades (e.g. PG 17 → PG 18) are a separate concern; see PostgreSQL Major Version Upgrade below.

Compatibility Matrix

Alauda CloudNativePG package versionUpstream CNPG versionPostgreSQL server versionsKubernetes versionACP version
v1.29.0-acp.x (Alpha)v1.29.014, 15, 16, 17, 181.27+4.3+

This is the first release. Future minor releases (v1.30.x-acp.x, v2.0.x-acp.x) will extend this matrix.

Refer to Release Notes for version-specific changes, new features, and known limitations.

Upgrade Path

  • Patch-level upgrade (within same minor): any direction supported. Example: v1.29.0-acp.1 → v1.29.0-acp.2.
  • Minor upgrade: consecutive only. Example: v1.29.0 → v1.30.0. Skipping minors (e.g. v1.29.0 → v1.31.0) is not supported and may break the OLM replaces chain.
  • Major upgrade: read the upstream CNPG release notes for breaking changes; manual CR migration may be required.

Upgrade Strategy

The Subscription's installPlanApproval field controls when upgrades trigger:

  • Automatic: OLM applies upgrades immediately when a new CSV is published to the channel. Recommended for non-production environments.
  • Manual: OLM creates an InstallPlan but pauses for human approval before applying. Recommended for production. Approve via the platform UI or kubectl edit installplan -n cnpg-system <name>.

Pre-upgrade Checks

Before triggering an operator upgrade:

  1. Verify all Clusters are healthy:

    kubectl get cluster.postgresql.cnpg.io -A

    Every Cluster's STATUS should be Cluster in healthy state. Do not upgrade with a degraded Cluster (in-flight failover, replica lag, or pod-pending state).

  2. Verify backup is recent (if Barman Cloud plugin is installed):

    kubectl get scheduledbackup,backup -A

    Most recent successful Backup should be within your RPO window.

  3. Verify catalog source health:

    kubectl get catalogsource -n cpaas-system platform -o jsonpath='{.status.connectionState.lastObservedState}'

    Should output READY.

  4. Verify CRD compatibility (cross-minor-version upgrade only): Check the new release's notes for CRD field deprecations. Cluster CRs using deprecated fields may fail validation post-upgrade.

Operator Upgrade Procedure

Web Console
kubectl
  1. Push the new package to the cluster's catalog (Marketplace administrator action).
  2. In Marketplace > Operator Hub, the cloudnative-pg package will show an upgrade indicator.
  3. (Manual approval only) Click the upgrade banner on the operator detail page → Approve InstallPlan.
  4. Watch the CSV in Operator Hub > Installed Operators. The transition is PendingInstallingReplacing → (old CSV deleted) → Succeeded.
  5. Verify the operator pod has cycled:
    kubectl get pods -n cnpg-system -l app.kubernetes.io/name=cloudnative-pg

Post-upgrade Verification

After the new CSV reaches Succeeded:

  1. Operator pod is Running 1/1:

    kubectl get pods -n cnpg-system
  2. Existing Clusters remain healthy:

    kubectl get cluster.postgresql.cnpg.io -A
  3. PostgreSQL pods do NOT restart unnecessarily: the operator upgrade itself does NOT rebuild PG pods. PG pods are touched only if the new operator detects a configuration drift requiring rollout (e.g. updated spec.imageName referencing a moved tag).

  4. CSV envs sanity check (especially after upgrade through a CSV format change):

    kubectl get deploy cnpg-controller-manager -n cnpg-system \
      -o jsonpath='{.spec.template.spec.containers[0].env}' | python3 -c "
    import json,sys
    [print(e['name'], '=', e.get('value','')) for e in json.load(sys.stdin)
     if e['name'] in ('ENABLE_IMAGE_REWRITE_TOLERANCE','POSTGRES_IMAGE_NAME','PGBOUNCER_IMAGE_NAME')]"

Rollback Considerations

OLM does NOT support automatic rollback. If an upgrade leaves clusters in a degraded state:

  1. Don't delete CSVs by hand — that escalates to "upgrade-stuck" recovery (below).
  2. First, check operator logs: kubectl logs -n cnpg-system deploy/cnpg-controller-manager. The operator may be reporting reconciliation errors that resolve once the cause is fixed.
  3. If rollback is genuinely needed, manually pin the old CSV via Subscription.spec.startingCSV. Note this can deadlock with stale state — see the recovery sequence below.

Historical Recovery: from rc-suffixed builds

The CNPG tag convention vMAJOR.MINOR.PATCH-acp.N(-rc.M.gSHA) interacts with OLM's strict SemVer §11 ordering in an unintuitive way: more pre-release identifiers means HIGHER version. So 1.29.0-acp.1-rc.88.ge3a3c0c (5 pre-release ids) ranks ABOVE 1.29.0-acp.1 (2 pre-release ids), inverting the expected "release > pre-release" semantic.

This matters when upgrading from a pre-release -rc.X.gSHA build to a bare release tag. As long as the old rc.X.gSHA ArtifactVersion exists on the cluster, OLM picks it as channel head — opposite of what you want. Combined with the rc-bundle's potentially incorrect replaces: field, automatic upgrades typically deadlock.

Recovery sequence

# 1. Push the new bundle (creates the bare ArtifactVersion alongside the existing rc)
violet push --platform-address <ACP_URL> ... cloudnative-pg.stable.ALL.<new-version>.tgz

# 2. Delete the old rc.X.gSHA ArtifactVersion — REQUIRED to remove the SemVer §11 winner
kubectl delete artifactversion cloudnative-pg.<old-version-with-rc-suffix> -n cpaas-system

# 3. Bounce OLM components to rebuild the gRPC catalog index
kubectl delete pod -n cpaas-system -l service_name=olm-registry-platform
kubectl delete pod -n cpaas-system -l app=catalog-operator

# 4. Nuke stale CSVs + InstallPlans in cnpg-system
kubectl delete csv -n cnpg-system --all
kubectl delete installplan -n cnpg-system --all

# 5. Delete + recreate the Subscription — WITHOUT startingCSV pin
#    (startingCSV pin can deadlock in this state; let OLM resolve to the channel head naturally)
kubectl delete subscription -n cnpg-system cloudnative-pg
cat <<EOF | kubectl apply -f -
apiVersion: operators.coreos.com/v1alpha1
kind: Subscription
metadata:
  name: cloudnative-pg
  namespace: cnpg-system
spec:
  channel: stable
  installPlanApproval: Automatic
  name: cloudnative-pg
  source: platform
  sourceNamespace: cpaas-system
EOF

# 6. Wait for the new CSV to reach Succeeded
kubectl wait csv/cloudnative-pg.<new-version> -n cnpg-system \
  --for=jsonpath='{.status.phase}'=Succeeded --timeout=5m

This recovery sequence is destructive (the operator deployment is briefly absent between steps 4 and 6), but Cluster CRs are not affected — PostgreSQL pods continue running independent of the operator. PG availability is preserved across this window.

If an existing Cluster CR is reconciled by the new operator after step 6 and the operator decides a rolling update is needed (because Cluster.status.currentImage differs from the CSV's POSTGRES_IMAGE_NAME default and the cluster doesn't override imageName), expect a brief replica-cycling but no primary downtime.

PostgreSQL Major Version Upgrade

Operator upgrades and PostgreSQL major version upgrades are independent. The operator can be upgraded without touching PostgreSQL; PostgreSQL major versions can be upgraded without changing operator versions.

CNPG does NOT support in-place PG major version upgrade (e.g. PG 17 → PG 18 in the same Cluster). To migrate a Cluster between major versions:

  1. Use logical replication (Subscription + Publication CRs) to replicate from old-major Cluster to new-major Cluster, then cut over.
  2. Or use backup-and-restore: pg_dump-style logical export, then restore into a new-major Cluster.
  3. Or use the upstream cnpg-i-pgupgrade CNPG-I plugin (when available in Alauda distribution).

The fleet-wide PG image version is centralized via ClusterImageCatalog (see Architecture / Image Catalog Model); updating the catalog updates imageCatalogRef-using Clusters but does NOT trigger a major-version upgrade — only minor/patch updates within the same major.

Reference