在 Kubernetes 上跑数据库 Operator,信任链不只落在 GitHub 上的源码。真正启动 Pod 的,是 Operator 拉取的容器镜像;镜像所在的 registry、镜像发布条款、镜像里打包的 PostgreSQL 构建和扩展,都会变成生产系统的一部分。Percona Operator for PostgreSQL 3.0.0 开始提供 Community PostgreSQL Images 技术预览,让用户可以从 PGDG 官方 PostgreSQL 包构建镜像,并推送到自己控制的 registry。3.1.0 起,这条路径会进入正式发布周期并完整文档化。
开源 Operator 的信任链不止源码
很多团队评估 Operator 时会先看代码是否开源、CRD 是否清晰、控制器逻辑是否可审计。这些当然重要,但还不够。
数据库 Operator 的运行依赖至少两类东西:
- Operator 控制器代码:通常在 GitHub 上,容易审计、fork、打补丁。
- Operator 拉取的运行时镜像:PostgreSQL、pgBouncer、pgBackRest 等镜像可能由供应商构建、托管和授权。
问题在第二类。源码仓库不变,不代表容器镜像的授权、商标策略、发布渠道或功能边界不会变。供应商可以继续保持项目源码开放,同时把生产真正依赖的 release artifact、认证发行版、marketplace 包装或高级功能收紧。
这也是 PostgreSQL 社区对供应商控制发行物保持警惕的原因。它不是怀旧,而是对生产依赖关系的现实判断。
为什么供应商发行版仍然有价值
社区镜像不是在否定发行版。供应商维护 PostgreSQL Distribution 有明确工程价值:
- 控制构建流程、依赖和默认配置。
- 在一个发布链路中快速交付 hotfix。
- 为客户需求维护上游尚未接受或需要多年推进的功能,例如发行版里的 Transparent Data Encryption。
- 为 Operator 打包确定支持的工具和扩展,缩小 CVE 暴露面。
- 让 QA 和支持团队面对可预测的运行环境。
- 为合规和审计提供单一责任方。
代价也清楚:一旦选择供应商发行版,你就把供应商 registry、镜像策略、扩展支持矩阵也纳入了自己的基础设施。对需要商业支持、TDE 或明确 SLA 的团队,这是合理选择;对更看重构建透明度和 registry 自主权的团队,则需要另一扇门。
PGO 3.0.0 打开的就是这扇门。
Community PostgreSQL Images 怎么工作
从 Percona Operator for PostgreSQL 3.0.0 开始,Operator 可以使用基于上游 PostgreSQL 包构建的镜像,而不只使用 Percona Distribution 镜像。
这组社区镜像的信任链更短:Dockerfile 从 download.postgresql.org 的 PGDG 仓库拉取官方 PostgreSQL 包,用户可以自己构建、签名并推送到自有 registry。Operator 不关心镜像来自哪里,只要镜像满足它对运行时的预期。
典型 CR 只需要替换三个镜像字段:
apiVersion: pgv2.percona.com/v2
kind: PerconaPGCluster
metadata:
name: cluster1
spec:
image: registry.example.com/postgresql-community:18
postgresVersion: 18
proxy:
pgBouncer:
image: registry.example.com/pgbouncer-community:1.23
backups:
pgbackrest:
image: registry.example.com/pgbackrest-community:2.51
# 其他 spec 字段保持和普通集群一致
落地时,把 registry.example.com/... 换成你自己的镜像仓库和标签。Operator 仍然负责实例、复制、备份、监控等生命周期管理,变化点集中在运行时镜像来源。
社区镜像按职责拆分:
- PostgreSQL 镜像:包含 PostgreSQL server、contrib、Patroni、pgBackRest,以及 Operator 需要的扩展和工具。
- pgBackRest 镜像:只包含备份恢复工具。
- pgBouncer 镜像:只包含连接池。
这种拆分让备份、代理、数据库实例处于不同 failure domain,也减少每个容器的攻击面。
社区镜像中已经包含的扩展示例包括 pg_repack、pgaudit、set_user、pgvector、wal2json、pg_cron。TimescaleDB 和 Citus 也是首批社区请求后加入的例子,不过它们有版本和平台边界:TimescaleDB 标注为 x86_64,PG18 下为 EL9;Citus 支持 PG16+。
可以这样实践:构建并接入自己的镜像
下面命令来自该社区镜像构建路径的典型使用方式。运行前需要准备 Docker buildx 多平台 builder,并把 REGISTRY 改成你有推送权限的镜像命名空间。
# 准备 multi-platform builder
docker buildx create --use --name multiarch
# 拉取构建仓库
git clone https://github.com/percona/percona-docker
cd percona-docker/postgresql-containers/community
# 构建并推送 UBI9 / EL9 的全套社区镜像:PostgreSQL、pgBouncer、pgBackRest
make all TAG=1.0.0 REGISTRY=myrepo/percona-postgresql-operator
# 只构建 PostgreSQL 17 镜像
make postgres17 TAG=1.0.0 REGISTRY=myrepo/percona-postgresql-operator
# 构建 UBI8 / EL8 变体
make all-ubi8 TAG=1.0.0-ubi8 REGISTRY=myrepo/percona-postgresql-operator
构建完成后,在 CR 中引用你的镜像:
apiVersion: pgv2.percona.com/v2
kind: PerconaPGCluster
metadata:
name: cluster1
spec:
image: myrepo/percona-postgresql-operator:1.0.0-postgres17-community
postgresVersion: 17
proxy:
pgBouncer:
image: myrepo/percona-postgresql-operator:1.0.0-pgbouncer-community
backups:
pgbackrest:
image: myrepo/percona-postgresql-operator:1.0.0-pgbackrest-community
实际标签格式以你的构建产物为准。建议在 CI 中做三件事:
- 固定
TAG,不要在生产集群里使用漂移标签。 - 对镜像做漏洞扫描和签名。
- PostgreSQL、pgBouncer、pgBackRest 三类镜像使用同一发布批次,避免运行时版本错位。
如果只是评估技术预览,也可以使用 perconalab/percona-postgresql-operator 下发布的测试镜像。但 perconalab 是非生产命名空间,生产环境更适合自己构建和签名。
边界要提前写进决策
社区镜像的目标是透明和自主,不是复制 Percona Distribution 的全部能力。
最重要的边界有两个:
- 发行版专属能力不会出现在上游构建镜像里。比如 TDE 属于 Percona Distribution 构建,依赖它就应该继续使用发行版镜像。
- 自建镜像意味着你要承担镜像构建、扫描、签名、发布、回滚和内部支持流程。Operator 代码和供应商发行版镜像的支持边界,与自建社区镜像的责任边界不同。
采用前可以用这份检查清单快速判断:
- 是否必须使用 TDE 或其他发行版专属功能?如果是,社区镜像不是合适路径。
- 是否有内部 registry、镜像签名和 SBOM 流程?没有的话,先补供应链能力。
- 是否需要 TimescaleDB、Citus 或其他不在供应商发行版中的扩展?社区镜像更适合试点。
- 是否能接受 3.0.0 阶段的 tech preview 属性?生产采用建议等 3.1.0 正式发布和文档完善后再评估。
Community PostgreSQL Images 的价值不在于“去供应商化”这个口号,而在于把选择权重新放回平台团队手里:需要商业发行版时用发行版,需要可审计、可重建、可托管在自有 registry 的运行时时,就用社区镜像。对数据库基础设施来说,这种选择权本身就是可靠性的一部分。