CloudNativePG vs Crunchy PGO:在 Kubernetes 上跑 PostgreSQL,该选哪个 Operator?

2026-05-18 42 预计阅读时间:1 分钟
来源:postgr.es AI 摘要 原文链接

免责声明:本文为 AI 摘要整理,建议结合原文阅读。摘要可能省略上下文、版本差异或边界条件,不作为官方说明。

预计阅读时间:11 分钟

在 Kubernetes 上运行 PostgreSQL,目前社区里两个最受关注的开源 Operator 是 CloudNativePG(CNPG)和 Crunchy Data 的 Crunchy PGO。这篇文章的作者 Gabriele Bartolini 正是 CNPG 的联合创始人和核心维护者——他坦率承认自己不可能中立,但多年深耕项目让他对两者的差异有着"有据可偏"的理解。本文基于他的对比分析,梳理两个 Operator 在架构、镜像、备份、大版本升级、可观测性、许可证与社区健康度上的关键分歧,并给出选型建议。

架构哲学:单集群 vs 多集群管理

CloudNativePG 的核心设计思路是"一个 Operator 管理一个 Kubernetes 集群内的所有 PostgreSQL 集群"。它没有引入额外的 CRD 层级——一个 Cluster 资源就定义了一组主从实例,Operator 直接监听这个 CRD 并完成实例编排。这种设计的好处是简单:你不需要理解额外的抽象层,kubectl get cluster 就能看到所有数据库集群的状态。

Crunchy PGO 的架构则更偏向"多集群集中管控"。它使用 PostgresCluster CRD,但 Operator 本身可以跨多个 Kubernetes 集群管理 PostgreSQL 实例。如果你的数据库需要分布在不同地域的多个 K8s 集群中,PGO 的集中管理视角可能更贴合需求。

取舍点:单集群场景下 CNPG 的 CRD 更轻量、更易上手;多集群场景下 PGO 的管控模型更成熟。

镜像设计:谁拥有 PostgreSQL 二进制?

这是两者最根本的分歧之一。

CNPG 的镜像策略是直接包含 PostgreSQL 官方二进制。容器镜像里就是 PostgreSQL 本身,加上少量管理脚本。升级 PostgreSQL 版本意味着拉取新镜像——版本切换由镜像标签驱动,简单直接。

PGO 的镜像策略是将 PostgreSQL 二进制与管理工具分离。Crunchy Data 构建了自己的 PostgreSQL 容器镜像(基于 Red Hat UBI 或 Debian),镜像中包含 Crunchy 的管理工具集(如 crunchy-backrestcrunchy-pgbench 等)。这种分离让管理工具可以独立演进,但也意味着你运行的不是"原版" PostgreSQL 镜像,而是 Crunchy 打包后的版本。

取舍点:如果你希望尽可能贴近 PostgreSQL 官方发行版,CNPG 的镜像更"干净";如果你更看重配套管理工具的一体化交付,PGO 的镜像体系更完整。

备份策略:Barman vs pgBackRest

备份是生产环境的生命线,两个 Operator 选了不同的备份引擎。

CNPG 使用 Barman(由 2ndQuadrant/EDB 开发)作为备份工具,支持全量备份、增量备份和 WAL 持续归档。Barman 在 PostgreSQL 社区有长期的生产验证,CNPG 将其集成进 Operator 的备份 CRD 中:

apiVersion: barmancloud.cnpg.io/v1
kind: ObjectStore
metadata:
  name: backup-s3
spec:
  configuration:
    destinationPath: s3://my-pg-backups/cnpg
    s3Credentials:
      accessKeyId:
        name: s3-creds
        key: ACCESS_KEY_ID
      secretAccessKey:
        name: s3-creds
        key: SECRET_ACCESS_KEY
  wal:
    encryption: AES256
  data:
    encryption: AES256
    compression: bzip2
    immediateCheckpoint: false

PGO 使用 pgBackRest(Crunchy Data 开发)作为备份工具,同样支持全量、增量、WAL 归档,并且有专用的备份 Sidecar 容器。pgBackRest 在 Crunchy 的商业产品中经过大量生产验证,功能丰富(如增量备份的页级增量、备份保留策略等)。

取舍点:Barman 更贴近 EDB 生态,pgBackRest 更贴近 Crunchy 生态。两者都能满足生产级备份需求,但如果你已有 Barman 运维经验,CNPG 的集成更自然;反之同理。

大版本升级:在线 vs 璇转

PostgreSQL 大版本升级(如 15 → 16)是运维中最紧张的操作之一。

CNPG 采用 pg_upgrade 在线升级策略。你在 Cluster CRD 中修改 imageName 指向新版本镜像,Operator 会自动执行 pg_upgrade 流程:创建新版本实例、迁移数据、切换主节点。整个过程在同一个 Cluster 资源内完成,不需要创建新的 CRD。

PGO 采用 旋转升级(rolling upgrade)策略。升级时需要创建一个新的 PostgresCluster 资源指向新版本,Operator 通过逻辑复制(pglogical)或 pg_upgrade 将数据从旧集群迁移到新集群,然后切换流量。这种方式更"安全"——旧集群始终保留,回滚更容易,但流程更复杂,需要管理两个 CRD。

取舍点:CNPG 的升级更简洁,适合对升级流程有信心、追求操作效率的团队;PGO 的旋转升级更保守,适合对回滚有硬性要求的场景。

可观测性:指标暴露方式

CNPG 通过 Patroni 管理 PostgreSQL 实例的生命周期,Patroni 自带 /metrics 端点暴露集群状态指标。CNPG 还额外暴露了 PostgreSQL 统计指标(如 pg_stat_statements),可以直接被 Prometheus 抓取:

apiVersion: monitoring.coreos.com/v1
kind: PodMonitor
metadata:
  name: cnpg-cluster-monitor
spec:
  selector:
    matchLabels:
      cnpg.io/cluster: my-pg-cluster
  podMetricsEndpoints:
    - port: metrics
      path: /metrics
      interval: 30s

PGO 的可观测性更"模块化"。它通过专用的 Collector Sidecar 容器暴露指标,Collector 基于 Crunchy 的 crunchy-postgres-exporter,提供了更细粒度的 PostgreSQL 内部指标。PGO 还内置了 Grafana Dashboard 的部署选项。

取舍点:CNPG 的指标暴露更轻量,依赖 Patroni 自身能力;PGO 的指标体系更丰富,但引入了额外的 Sidecar 容器。

许可证与社区健康度

CNPG 采用 Apache 2.0 许可证,代码完全开放,社区贡献流程透明。项目由 EDB 赞助但社区治理结构开放,GitHub 上活跃度较高,Issue 和 PR 的响应速度较快。

PGO 采用 Apache 2.0 许可证(核心 Operator 部分),但 Crunchy Data 的部分配套工具(如某些监控组件)可能受更严格的许可证约束。PGO 的社区同样活跃,但作为 Crunchy Data 的核心商业产品之一,其演进方向与 Crunchy 的商业策略绑定更深。

取舍点:两者核心都是 Apache 2.0,但 CNPG 的社区治理更独立于单一商业实体;PGO 的生态更依赖 Crunchy Data 的产品路线图。

实践示例:用 CNPG 快速部署一个高可用 PostgreSQL 集群

以下是一个可以直接复制运行的 CNPG 部署示例,展示从安装 Operator 到创建集群到配置备份的完整流程:

# 1. 安装 CNPG Operator(v1.24.x)
kubectl apply -f \
  https://raw.githubusercontent.com/cloudnative-pg/cloudnative-pg/main/releases/cnpg-1.24.0.yaml

# 等待 Operator 就绪
kubectl wait -n cnpg-system deployment/cnpg-controller-manager \
  --for=condition=Available --timeout=120s
# 2. 创建 S3 备份凭证 Secret
apiVersion: v1
kind: Secret
metadata:
  name: s3-creds
type: Opaque
stringData:
  ACCESS_KEY_ID: "your-access-key"
  SECRET_ACCESS_KEY: "your-secret-key"
---
# 3. 定义备份存储目标
apiVersion: barmancloud.cnpg.io/v1
kind: ObjectStore
metadata:
  name: minio-backup
spec:
  configuration:
    destinationPath: s3://pg-backups/cnpg-prod
    s3Credentials:
      accessKeyId:
        name: s3-creds
        key: ACCESS_KEY_ID
      secretAccessKey:
        name: s3-creds
        key: SECRET_ACCESS_KEY
    endpointURL: "https://minio.example.com"  # 如用 MinIO 替代 AWS S3
  wal:
    maxParallel: 8
    encryption: AES256
  data:
    compression: bzip2
    encryption: AES256
---
# 4. 创建 PostgreSQL 集群(3 实例:1 主 + 2 从)
apiVersion: postgresql.cnpg.io/v1
kind: Cluster
metadata:
  name: pg-prod
spec:
  imageName: ghcr.io/cloudnative-pg/postgresql:16.4
  instances: 3
  minSyncReplicas: 1
  maxSyncReplicas: 2
  postgresql:
    parameters:
      max_connections: "200"
      shared_buffers: "256MB"
      pg_stat_statements.track: all
  bootstrap:
    initdb:
      database: appdb
      owner: appuser
  backup:
    barmanObjectStore:
      objectStore:
        name: minio-backup
      retentionPolicy: "30d"
  monitoring:
    enablePodMonitor: true
# 5. 验证集群状态
kubectl get cluster pg-prod
kubectl get pods -l cnpg.io/cluster=pg-prod

# 6. 连接数据库(CNPG 自动创建 Service)
kubectl run psql-client --rm -it --image=postgres:16 \
  --env=PGPASSWORD=$(kubectl get secret pg-prod-appuser -o jsonpath='{.data.password}' | base64 -d) \
  -- psql -h pg-prod-rw -U appuser -d appdb

运行前需要修改的地方:S3 凭证替换为你的真实值,endpointURL 如用 AWS S3 可删除该行,imageName 版本号按需调整。

选型清单

维度 CNPG 更合适 PGO 更合适
部署规模 单 K8s 集群 多 K8s 集群集中管控
镜像偏好 贴近 PG 官方发行版 一体化打包管理工具
备份工具 已有 Barman 经验 已有 pgBackRest 经验
大版本升级 追求简洁、一次到位 需要保留旧集群、随时回滚
可观测性 轻量够用即可 需要细粒度 PG 内部指标
商业依赖 希望社区独立演进 接受 Crunchy 产品路线绑定
团队背景 EDB/2ndQuadrant 生态 Crunchy Data 生态

两个 Operator 都是成熟的生产级方案,选择的核心不是"谁更好",而是"谁的架构假设更匹配你的运维模型"。如果你的 PostgreSQL 集群主要跑在一个 K8s 集群内、团队偏好简洁的 CRD 模型、升级时追求操作效率,CNPG 是更自然的选择。如果你需要跨集群管理、升级时必须保留回滚窗口、或已经在 Crunchy 的工具链上投入了大量运维经验,PGO 更值得采用。


相关推荐