升级

本页介绍如何升级 Alauda 构建的 CloudNativePG operator。PostgreSQL server 版本升级(例如 PG 17 → PG 18)是另一项单独的工作;请参见下方的 PostgreSQL 主版本升级

兼容性矩阵

Alauda CloudNativePG 软件包版本上游 CNPG 版本PostgreSQL server 版本Kubernetes 版本ACP 版本
v1.29.0-acp.x (Alpha)v1.29.014, 15, 16, 17, 181.27+4.3+

这是第一个 release。未来的 minor 发布(v1.30.x-acp.x、v2.0.x-acp.x)将扩展此矩阵。

有关版本相关的变更、新功能和已知限制,请参阅 Release Notes

升级路径

  • 补丁级升级(同一 minor 版本内):支持任意方向。例如:v1.29.0-acp.1 → v1.29.0-acp.2
  • minor 升级:仅支持相邻版本。例如:v1.29.0 → v1.30.0。不支持跳过 minor 版本(例如 v1.29.0 → v1.31.0),否则可能破坏 OLM 的 replaces 链。
  • 主版本升级:请阅读上游 CNPG release notes 中的破坏性变更;可能需要手动迁移 CR。

升级策略

Subscription 的 installPlanApproval 字段控制何时触发升级:

  • Automatic:当新的 CSV 发布到该 channel 时,OLM 会立即应用升级。建议用于非生产环境。
  • Manual:OLM 会创建 InstallPlan,但在应用前暂停,等待人工批准。建议用于生产环境。可通过平台 UI 或 kubectl edit installplan -n cnpg-system <name> 进行批准。

升级前检查

在触发 operator 升级之前:

  1. 验证所有 Clusters 都处于健康状态

    kubectl get cluster.postgresql.cnpg.io -A

    每个 Cluster 的 STATUS 都应为 Cluster in healthy state。不要在 Cluster 处于降级状态时升级(正在进行 failover、Replica 堆积量,或 Pod Pending 状态)。

  2. 验证备份是最近的(如果已安装 Barman Cloud plugin):

    kubectl get scheduledbackup,backup -A

    最近一次成功的 Backup 应位于你的 RPO 窗口内。

  3. 验证 catalog source 健康状态

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

    应输出 READY

  4. 验证 CRD 兼容性(仅限跨 minor 版本升级): 请检查新 release notes 中关于 CRD 字段弃用的说明。使用已弃用字段的 Cluster CR 在升级后可能无法通过校验。

operator 升级流程

Web 控制台
kubectl
  1. 将新 package 推送到 cluster 的 catalog(Marketplace 管理员操作)。
  2. Marketplace > Operator Hub 中,cloudnative-pg package 会显示升级标识。
  3. (仅限手动批准)在 operator 详情页中点击升级横幅 → Approve InstallPlan
  4. Operator Hub > Installed Operators 中观察 CSV。状态转换为 PendingInstallingReplacing →(旧 CSV 被删除)→ Succeeded
  5. 验证 operator pod 已完成轮转:
    kubectl get pods -n cnpg-system -l app.kubernetes.io/name=cloudnative-pg

升级后验证

当新的 CSV 达到 Succeeded 后:

  1. Operator pod 处于 Running 1/1

    kubectl get pods -n cnpg-system
  2. 现有 Clusters 仍保持健康

    kubectl get cluster.postgresql.cnpg.io -A
  3. PostgreSQL pods 不会无必要地重启:operator 升级本身不会重建 PG pods。只有当新 operator 检测到需要滚动更新的配置漂移时,PG pods 才会受到影响(例如更新后的 spec.imageName 引用了已移动的 tag)。

  4. CSV envs 健全性检查(尤其是在通过 CSV 格式变更升级之后):

    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')]"

回滚注意事项

OLM 不支持自动回滚。如果升级后 cluster 进入降级状态:

  1. 不要手动删除 CSV——这会升级为下面的“upgrade-stuck”恢复流程。
  2. 先检查 operator 日志kubectl logs -n cnpg-system deploy/cnpg-controller-manager。operator 可能正在报告 reconciliation 错误,而这些错误在根因修复后会自动恢复。
  3. 如果确实需要回滚,请通过 Subscription.spec.startingCSV 手动固定旧 CSV。请注意,这可能会因陈旧状态而导致死锁——请参见下面的恢复序列。

历史恢复:来自带 rc 后缀的构建

CNPG 标签约定 vMAJOR.MINOR.PATCH-acp.N(-rc.M.gSHA) 与 OLM 严格的 SemVer §11 排序方式结合后,会产生一个不直观的结果:预发布标识符越多,版本越高。因此,1.29.0-acp.1-rc.88.ge3a3c0c(5 个预发布标识)会排在 1.29.0-acp.1(2 个预发布标识)之上,从而颠倒了人们预期中的“release > pre-release”语义。

这在从预发布的 -rc.X.gSHA 构建升级到纯发布标签时尤为重要。只要集群中仍存在旧的 rc.X.gSHA ArtifactVersion,OLM 就会将其选为 channel head——这与预期相反。再加上 rc-bundle 可能不正确的 replaces: 字段,自动升级通常会死锁。

恢复序列

# 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

这个恢复序列具有破坏性(在第 4 步和第 6 步之间,operator deployment 会短暂缺失),但不会影响 Cluster CR——PostgreSQL pods 会独立于 operator 继续运行。PG 可用性在此窗口内会保持不变。

如果现有 Cluster CR 在第 6 步之后被新 operator reconciliation,并且 operator 判定需要执行滚动更新(因为 Cluster.status.currentImage 与 CSV 中 POSTGRES_IMAGE_NAME 默认值不同,且 cluster 没有覆盖 imageName),则预计会有短暂的从节点轮转,但不会造成主节点停机。

PostgreSQL 主版本升级

operator 升级与 PostgreSQL 主版本升级是相互独立的。operator 可以在不触碰 PostgreSQL 的情况下升级;PostgreSQL 主版本也可以在不更改 operator 版本的情况下升级。

CNPG 不支持就地 PG 主版本升级(例如在同一个 Cluster 中将 PG 17 升级到 PG 18)。要在主版本之间迁移 Cluster:

  1. 使用 logical replicationSubscription + Publication CR)从旧主版本 Cluster 复制到新主版本 Cluster,然后再切换。
  2. 或使用 backup-and-restore:先进行 pg_dump 风格的逻辑导出,再恢复到一个新主版本 Cluster 中。
  3. 或使用上游的 cnpg-i-pgupgrade CNPG-I plugin(当 Alauda distribution 中提供时)。

全局 PG 镜像版本通过 ClusterImageCatalog 进行集中管理(参见 架构 / Image Catalog Model);更新 catalog 会更新使用 imageCatalogRef 的 Clusters,但不会触发主版本升级——只会在同一 major 内进行 minor/patch 更新。

参考