来源:https://www.percona.com/blog/postgresql-community-images-operator/
社区 Docker 镜像:保持 Operator 开源,避免供应商注册表锁定
作者:Slava Sarzhan
日期:2026年6月30日
分类:Kubernetes, 开源, PostgreSQL
PostgreSQL 社区镜像解决了 Kubernetes 数据库 Operator 如何赢得你信任过程中的一个真正空白。在 Kubernetes 上运行数据库 Operator 意味着信任两件事:代码本身,以及 Operator 拉取的容器镜像。代码在 GitHub 上,易于审查,易于复刻(fork)。而容器镜像、托管它们的注册表以及管理它们的许可证,都掌握在供应商手中,这三者中的任何一个都可能在不改变源代码仓库的情况下发生变动。从 Percona Operator for PostgreSQL 3.0.0 开始,你可以让 Operator 运行在你自己从 download.postgresql.org 上的官方 PostgreSQL 包构建的社区镜像上,并放在你控制的注册表中。
TL;DR
- 社区 Docker 镜像:在 PGO 3.0.0 中作为技术预览,在 3.1.0 中正式发布。让 Operator 使用上游构建的 PostgreSQL 镜像,而不是 Percona 发行版镜像。
- 你可以从官方的 PostgreSQL 源代码自行构建。Dockerfile 从 download.postgresql.org(PGDG 仓库)拉取包,因此信任链直接从 PGDG 到你的注册表,中间没有供应商。
- 存在局限性。任何 Percona 特有的功能(例如我们发行版中的 TDE)在上游构建的镜像中都不存在。这种权衡是有意为之。
本文将涵盖:
- 开源在实践中如何被稀释
- 诚实地说明为什么发行版仍然存在
- 社区 Docker 镜像如何工作
- 上游路径的局限性
- 如何试用以及如何向我们反馈
开源如何被稀释
开源在过去几年发生了变化,而且并不总是向好的方向发展。公司已经学会,你可以保持项目的源代码完全开放,同时通过悄悄关闭生产环境中重要的部分来锁定大部分用户:发布构件、容器镜像、受支持的操作系统列表、经过认证的 Kubernetes 发行版、市场列表。
同一个项目,闭源的构件
你可能有一个完全社区的 CNCF 项目,但它不会出现在 Red Hat Marketplace 上,除非作为付费的企业版。同样,一个供应商可能在社区中提供一个打包版本,而在企业版中提供包含你在生产中实际所需功能的更丰富的版本。许可证仍然写着“开源”。实际体验却是“你依赖我们”。而且,源代码仓库的许可证并不是这里唯一重要的许可证:供应商可以仅更改许可证、商标政策或容器镜像的分发条款,而完全不触动源代码仓库。这种情况最近在 PostgreSQL Operator 领域发生过,社区已经注意到了。
为什么社区保持警惕是合理的
供应商之外没有人能预测许可证何时会更改,某个功能何时会被移到付费墙后面,或者某个外部贡献何时会因与企业版功能竞争而被拒绝。最近的历史有很多这样的例子,PostgreSQL 社区一直在关注。当这个社区抵制供应商控制的发行版时,这不是怀旧。这是对过去发展趋势的理性解读。
我在 Percona 的 PostgreSQL Operator 团队工作,所以我是从供应商的角度看待这个对话。这种怀疑是合理的。对我们来说,诚实的问题是该如何应对。
为什么发行版仍然存在
承认社区的担忧并不意味着发行版没有意义。有充分的理由推出一个发行版,假装没有会使这篇博客文章失去说服力。
发行版能带来什么
一个由供应商构建的发行版可以让供应商:
- 控制构建过程、依赖项和默认设置,使其适合特定用户的需求。
- 更快地发布热修复补丁,因为整个发布路径都在一个地方。
- 当上游社区不接受(或可能需要数年才能接受)的某些功能(例如透明数据加密)对客户很重要时,可以复刻 PostgreSQL 本身。
- 对于 Kubernetes Operator,可以只打包 Operator 支持的工具和扩展的镜像,并排除其他所有内容。这样 CVE 攻击面会更小。
- 为 QA 和服务团队提供一个可预测的环境。“我们支持扩展 A、B、C,不支持 D、X、Z”只有在其 QA 确实测试了 A、B、C 并且服务团队能够在生产环境中使用它们时才是诚实的。
- 为客户提供一个对整个发布周期(从热修复到包可用性)负责的单一责任方。一些团队出于合规和审计原因明确需要这种契约。
- 当然,我们上面提到的一些不太积极的原因也存在,而这正是社区不断指出的部分。
你接受的权衡
如果你运行供应商的发行版,你接受供应商的注册表、镜像策略和支持的扩展矩阵成为你技术栈的一部分。如果供应商更改其中任何一项,你的 Operator 部署也会随之更改。对于在其他产品上经历过这种情况的用户来说,这不是假设。
因此,真正的问题是,你是否可以既为需要这些好处的用户保留发行版提供的优势,同时又为一个诚实的、受支持的大门向不需要这些的用户敞开。这就是 PGO 3.0.0 打开的那扇门。
PGO 3.0.0 中的社区 PostgreSQL 镜像
从 Percona Operator for PostgreSQL 3.0.0 开始,Operator 可以针对从上游 PostgreSQL 包构建的镜像运行,而不仅仅是 Percona 发行版镜像。这就是我们所说的社区 PostgreSQL 镜像。在 3.0.0 中,该功能作为技术预览提供。在 3.1.0 中,这些镜像将成为我们官方发布周期的一部分,并有完整的文档支持。
社区 Docker 镜像的一个主要优点是,社区可以请求或贡献官方 Percona PostgreSQL 发行版中不存在的任何扩展。TimescaleDB 和 Citus 就是第一批例子:社区要求了它们,我们从第一天起就将两者包含在了社区镜像集中。
如何使用“社区 PostgreSQL 镜像”
Operator 不关心镜像来自哪里,只要该镜像满足 Operator 的运行时期望即可。
一个使用社区镜像的典型 CR 如下所示:
apiVersion:pgv2.percona.com/v2kind:PerconaPGClustermetadata:name:cluster1spec:image:registry.example.com/postgresql-community:18postgresVersion:18proxy:pgBouncer:image:registry.example.com/pgbouncer-community:1.23backups:pgbackrest:image:registry.example.com/pgbackrest-community:2.51# 其他 spec 字段与普通 CR 相同发生变化的字段是spec.image、spec.proxy.pgBouncer.image和spec.backups.pgbackrest.image。你可以在自己的注册表下构建和发布所有三个镜像,如果这有助于你跟踪版本,也可以使用自己的标签。Operator 驱动部署的其余部分(实例、备份、复制、监控等)的方式与以往完全相同。
每个镜像中包含什么
每个社区 Docker 镜像都是在选定基础镜像(UBI9 或 UBI8)上的一个薄层,加上该角色所需的 Operator 包。其中{N}代表你构建的 PostgreSQL 主版本(17、18 等)。
postgres 镜像(例如 postgres17):
| 包 | 角色 |
|---|---|
| postgresql{N}-server | PostgreSQL 服务器 |
| postgresql{N}-contrib | 贡献模块 |
| pg_repack_{N} | 在线表和索引重组 |
| pgaudit_{N} | 审计日志 |
| set_user_{N} | 权限提升控制 |
| pgvector_{N} | 向量相似性搜索 |
| wal2json_{N} | WAL 到 JSON 的逻辑解码 |
| pg_cron_{N} | 数据库内 cron 调度器 |
| pgbackrest | 备份/恢复工具 |
| patroni | 高可用集群管理器 |
| timescaledb-2-postgresql-{N} | 时间序列扩展(仅限 x86_64;PG18 仅限 EL9) |
| citus_{N} | 分布式 PostgreSQL(仅限 PG16+) |
pgbackrest 镜像:
| 包 | 角色 |
|---|---|
| pgbackrest | 仅备份/恢复工具 |
pgbouncer 镜像:
| 包 | 角色 |
|---|---|
| pgbouncer | 仅连接池 |
这种拆分是有意为之。postgres 镜像包含了完整的 Operator 感知运行时。备份和代理镜像保持最小化。因此,Operator 的组件位于独立的故障域中,并缩小了每个容器的攻击面。
需要诚实面对的局限性
社区镜像不是 Percona 发行版镜像。两个实际后果:
- 发行版独有功能将无法工作。例如,透明数据加密(TDE)存在于 Percona 发行版构建中。从上游 PostgreSQL 构建的社区镜像不包含它。如果你依赖 TDE,请运行发行版镜像。
- 支持边界不同。Percona 支持团队负责 Percona 发行版镜像和 Operator 代码。对于你自己构建的社区镜像,你需要自行承担维护责任。
最终,这些都是正确的权衡。社区镜像的意义在于为你提供透明度和控制权。自行管理镜像是这种协议的一部分。同时,我们在 Docker Hub 的perconalab/percona-postgresql-operator下发布了所有三个镜像,以便你无需先搭建自己的构建管道即可评估技术预览。perconalab是 Percona 的非生产命名空间,因此请使用这些镜像进行测试。对于生产环境,请自行构建并签名你的镜像。
UBI9 (EL9) 镜像:
docker.io/perconalab/percona-postgresql-operator:main-postgres14-communitydocker.io/perconalab/percona-postgresql-operator:main-postgres15-communitydocker.io/perconalab/percona-postgresql-operator:main-postgres16-communitydocker.io/perconalab/percona-postgresql-operator:main-postgres17-communitydocker.io/perconalab/percona-postgresql-operator:main-postgres18-communitydocker.io/perconalab/percona-postgresql-operator:main-pgbackrest-communitydocker.io/perconalab/percona-postgresql-operator:main-pgbouncer-communitydocker.io/perconalab/percona-postgresql-operator:main-upgrade-community
UBI8 (EL8) 镜像:
docker.io/perconalab/percona-postgresql-operator:main-ubi8-postgres14-communitydocker.io/perconalab/percona-postgresql-operator:main-ubi8-postgres15-communitydocker.io/perconalab/percona-postgresql-operator:main-ubi8-postgres16-communitydocker.io/perconalab/percona-postgresql-operator:main-ubi8-postgres17-communitydocker.io/perconalab/percona-postgresql-operator:main-ubi8-postgres18-communitydocker.io/perconalab/percona-postgresql-operator:main-ubi8-upgrade-community
如何构建镜像
Dockerfile、包列表和示例 CI 作业位于percona-docker/postgresql-containers/community。构建是在docker buildx之上的常规make目标,因此你可以在任何多平台构建器上运行它。
# 先决条件:带有 多平台构建器的 docker buildxdockerbuildx create--use--namemultiarch# 构建并推送所有 PostgreSQL 社区镜像(UBI9 / EL9)gitclone https://github.com/percona/percona-dockercdpercona-docker/postgresql-containers/communitymakeallTAG=1.0.0REGISTRY=myrepo/percona-postgresql-operator# 或者构建单个镜像makepostgres17TAG=1.0.0REGISTRY=myrepo/percona-postgresql-operator# UBI8 / EL8 变体makeall-ubi8TAG=1.0.0-ubi8REGISTRY=myrepo/percona-postgresql-operatormake all会构建所有三个镜像(postgres、pgBouncer、pgBackRest),以便它们保持版本对齐。覆盖REGISTRY和TAG以指向你自己的命名空间和标签方案。一旦镜像进入你的注册表,将它们插入前面所示的 CR 字段中,Operator 就会使用它们。
完整构建文档:percona-docker/postgresql-containers/community/README.md。
如何贡献
社区镜像位于percona/percona-docker中,构建由一个transform.py生成器驱动,该生成器在build/下生成 Dockerfile。build/下的文件在每次同步时都会重新生成,因此贡献应通过生成器进行,而不是通过生成的文件。
完整贡献指南:community/CONTRIBUTING.md。
如何提供反馈
根据反馈的类型,有两个渠道:
- 在
percona/percona-postgresql-operator的 GitHub issue 中,使用community-images标签。用于错误报告、缺失的扩展、构建问题和具体的请求。该标签将所有社区镜像报告集中到一个团队关注的过滤器中。
下一步
第一步是全面承担 Percona Operator for PostgreSQL 作为一个独立项目的工程所有权,使路线图、发布节奏和治理由一个社区可以直接对话的团队负责。社区 PostgreSQL 镜像是在这一承诺上的下一步。如果社区采纳这条路径,我们对下一步投资什么有一些想法。
我们将让社区告诉我们。如果这有用,我们会继续在这里投资。我们准备在 Operator 中添加更多围绕社区镜像的功能。反之,如果没有人采用,那也是一个信号,而且是一个诚实的信号。
在 3.0.0 中试用技术预览。如果构建流程不够顺畅,请提交一个 issue。在论坛或直接在 GitHub 上告诉我们你接下来想要什么。
立即试用
- Percona Operator for PostgreSQL 文档:https://docs.percona.com/percona-operator-for-postgresql/
- GitHub:https://github.com/percona/percona-postgresql-operator
- 社区论坛:https://forums.percona.com,分享你的反馈、提问或报告问题