#清单映射
从 Zalando CR(acid.zalan.do/v1 postgresql)到 CloudNativePG 资源(postgresql.cnpg.io/v1)的逐字段映射。
随产品交付提供一个自动化转换脚本,zalando-to-cnpg(operator 源代码仓库,hack/zalando-to-cnpg/):
它会生成一个 Cluster 以及 Pooler/Database 资源,并为每个无法映射的字段输出明确的 WARN —— 请将每条警告视为一项检查项。
图例:direct = 复制;transform = 重命名/转换; mechanism = 不同的资源或方法;none = 无对应项(工具会发出警告)。
#目录
核心存储和资源用户和数据库PostgreSQL 配置Pooling、服务、网络调度和 pod 属性备份、克隆、待机、TLS、CDCACP PostgreSQL 旧版本中的 Zalando 专有字段实战示例#核心
| Zalando | CloudNativePG | Kind | 说明 |
|---|---|---|---|
metadata.name | metadata.name | direct | CNPG 中没有 teamId- 前缀规则;重命名会改变 service DNS 名称。 |
spec.teamId | — | none | 仅为约定;通过 inheritedMetadata 作为 label 保留。 |
spec.numberOfInstances | spec.instances | direct | Zalando 的 0(hibernation)→ 注解 cnpg.io/hibernation: "on",而不是 instances: 0。 |
spec.dockerImage | spec.imageName | transform | 绝不要直接复制——Spilo 镜像无法与 CNPG 配合使用。根据 postgresql.version 推导出对应 major 的 PostgreSQL operand 镜像。 |
spec.postgresql.version | image major | transform | CNPG 会从镜像中推断版本。 |
spec.env | spec.env | transform | 删除 Spilo/WAL-G 变量(WAL_S3_BUCKET、USE_WALG_*、AWS_* 等)——备份配置会迁移到 barman-cloud ObjectStore。 |
#存储和资源
| Zalando | CloudNativePG | Kind | 说明 |
|---|---|---|---|
spec.volume.size | spec.storage.size | direct | 支持原地扩容;不支持缩容(任一侧均不支持)。 |
spec.volume.storageClass | spec.storage.storageClass | direct | |
spec.volume.selector | spec.storage.pvcTemplate.selector | transform | |
spec.volume.subPath / iops / throughput | — | none | 固定的 PGDATA 布局;IOPS/throughput 过去是 AWS EBS API 调用——请通过 StorageClass 表达。 |
spec.additionalVolumes | — | none (partial) | Secrets/ConfigMaps → spec.projectedVolumeTemplate;数据卷 → spec.tablespaces / spec.walStorage。 |
spec.resources | spec.resources | direct | 如果在 Zalando CR 中缺失,则会应用 operator-config 默认值——在 CNPG 中应显式设置。 |
#用户和数据库
| Zalando | CloudNativePG | Kind | 说明 |
|---|---|---|---|
spec.users | spec.managed.roles[] | transform | 标志位按 1:1
映射(superuser、createdb、createrole、replication、bypassrls;nologin → login: false)。⚠ Zalando 用户默认具有 LOGIN;CNPG managed roles 默认 login: false —— 工具始终会显式输出 login。 |
| credential secrets | managed.roles[].passwordSecret | mechanism | CNPG 期望使用 kubernetes.io/basic-auth Secret。将密码从 Zalando 的 <user>.<cluster>.credentials... Secret 中复制出来,以保持应用凭证可用。 |
spec.usersWithSecretRotation (+ in-place variant) | — | none | 不支持自动密码轮换。 |
spec.databases | bootstrap.initdb.{database,owner} + Database CRs | transform | 第一项用于引导集群;其余每一项都会成为一个 Database 资源。 |
spec.preparedDatabases | Database CR (schemas, extensions) + roles | transform | Zalando 的自动角色层次结构(<db>_owner/_reader/_writer + 默认权限)不会自动创建——需要合成 roles 和 GRANT(例如 postInitApplicationSQL)。 |
#PostgreSQL 配置
| Zalando | CloudNativePG | Kind | 说明 |
|---|---|---|---|
spec.postgresql.parameters | spec.postgresql.parameters | transform | 直接复制,但要排除由 operator 控制的参数(工具会剥离并告警):archive_*、restore_command、port、hot_standby、recovery targets、ssl*、synchronous_standby_names、shared_preload_libraries(→ 专用字段)、listen/log/file-path 设置。调优参数(max_connections、shared_buffers 等)都会透传。 |
spec.patroni.pg_hba | spec.postgresql.pg_hba | transform | CNPG 会前置固定规则,并追加 host all all all scram-sha-256;Zalando 的列表会替换整个文件。Spilo 特有的行(pam、standby)会被剥离。 |
spec.patroni.initdb | spec.bootstrap.initdb | transform | encoding/locale/data-checksums 会映射;仅在全新引导时相关。 |
spec.patroni.synchronous_mode | spec.postgresql.synchronous | transform | → {method: any, number: <synchronous_node_count or 1>};非 strict → dataDurability: preferred,synchronous_mode_strict: true → required。 |
spec.patroni.slots | spec.replicationSlots | mechanism | HA slots 会自动创建;用于 CDC 的永久逻辑 slot → Publication/Subscription 资源或 SQL。 |
spec.patroni.ttl / loop_wait / retry_timeout / maximum_lag_on_failover / failsafe_mode | — | none | Patroni/DCS 调优没有对应项(相关字段:spec.failoverDelay、spec.probes)。 |
#Pooling、服务、网络
| Zalando | CloudNativePG | Kind | 说明 |
|---|---|---|---|
spec.enableConnectionPooler | separate Pooler resource | mechanism | ⚠ Zalando 的默认 pool 模式是 transaction;CNPG 的默认值是 session —— 请显式设置 pgbouncer.poolMode: transaction。Zalando 默认 2 个实例,而 CNPG 为 1 个。应用需要重定向到 Pooler service。 |
spec.enableReplicaConnectionPooler | second Pooler with type: ro | mechanism | |
spec.connectionPooler.* | Pooler.spec.* | transform | numberOfInstances → instances;mode → pgbouncer.poolMode;maxDBConnections → pgbouncer.parameters;resources/image → pod template。 |
spec.enableMasterLoadBalancer / enableReplicaLoadBalancer | spec.managed.services.additional[] | mechanism | 添加 {selectorType: rw or ro, serviceTemplate: {spec: {type: LoadBalancer}}}——默认服务不会被修改;service DNS 名称会改变。 |
spec.allowedSourceRanges | …serviceTemplate.spec.loadBalancerSourceRanges | transform | |
spec.serviceAnnotations (+ per-role variants) | service templates / inheritedMetadata.annotations | transform | |
spec.podAnnotations | spec.inheritedMetadata.annotations | transform | 作用于所有生成的对象。 |
#调度和 pod 属性
| Zalando | CloudNativePG | Kind | 说明 |
|---|---|---|---|
spec.nodeAffinity | spec.affinity.nodeAffinity | direct | CNPG 还提供了反亲和控制(podAntiAffinityType、topologyKey)。 |
spec.tolerations | spec.affinity.tolerations | direct | 注意其嵌套在 affinity 下。 |
spec.podPriorityClassName | spec.priorityClassName | direct | |
spec.schedulerName | spec.schedulerName | direct | |
spec.spiloRunAsUser / spiloRunAsGroup / spiloFSGroup | spec.postgresUID / postgresGID | transform | CNPG 默认 uid/gid 为 26(Spilo 使用 101);通常应去掉。 |
spec.sidecars / spec.initContainers | — | none | 有意不支持。Metrics sidecar → 内置 exporter;初始化逻辑 → bootstrap.initdb.postInit*SQL。 |
spec.maintenanceWindows | — | none | 最接近的选项:spec.primaryUpdateStrategy: supervised。 |
#备份、克隆、待机、TLS、CDC
| Zalando | CloudNativePG | Kind | 说明 |
|---|---|---|---|
spec.enableLogicalBackup + schedule | — | none | CNPG 备份通过 ScheduledBackup 执行物理备份(⚠ 6 字段 cron——需要在前面加一个秒字段)。如有需要,请将逻辑导出保留为你自己的 CronJob。 |
spec.clone(无 timestamp) | spec.bootstrap.pg_basebackup + externalClusters | mechanism | 从运行中的集群克隆——可对正在运行的 Zalando 集群执行(这是受支持的迁移路径)。 |
spec.clone(timestamp / s3 fields) | bootstrap.recovery + externalClusters[].barmanObjectStore | mechanism | 仅可从 barman 格式归档恢复——Spilo WAL-E/WAL-G 归档对 CNPG 不可读。 |
spec.standby(S3 WAL path) | — | none | 同样存在归档不兼容问题。 |
spec.standby(host/port) | spec.replica + externalClusters | mechanism | 外部 primary 的流式 standby;通过切换 replica.enabled 完成提升。 |
spec.tls | spec.certificates | transform | 单 Secret 模型会拆分为 server/client(+ replication)证书;SAN 必须覆盖 <cluster>-rw.<ns>.svc。最简单的做法是省略,让 CNPG 自行管理。 |
spec.streams (CDC) | — | none | 需要基于 Publication/Subscription 资源或外部 Debezium 重新设计(wal_level=logical 是 CNPG 的默认值)。 |
#ACP PostgreSQL 旧版本中的 Zalando 专有字段
| Zalando (ACP fork) | CloudNativePG | 说明 |
|---|---|---|
spec.backup (WAL-G schedule/retention/storage) | barman-cloud ObjectStore + spec.plugins + ScheduledBackup + retentionPolicy | CNPG 的第一次备份是全新的完整备份。 |
spec.exporter / enableExporter | spec.monitoring (built-in exporter) | 参见 Grafana dashboards 指南(How To 部分)。 |
spec.enablePgpool2 | — | 仅支持 PgBouncer Pooler;查询负载均衡 ≈ -ro service + 应用路由。 |
spec.clusterReplication | spec.replica + externalClusters (+ promotion/demotion tokens) | CNPG 的 replica-cluster(分布式拓扑)模型。 |
spec.usersCustomizedPasswd | managed.roles[].passwordSecret | 将密码从 CR 中移出,放入 basic-auth Secret。 |
spec.ipFamilyPrefer | service templates ipFamilies/ipFamilyPolicy | 单栈 IPv6 需要 operator 中的 url.Build 修复(参见 配置)。 |
#实战示例
Zalando 源:
apiVersion: acid.zalan.do/v1
kind: postgresql
metadata:
name: acid-orders
spec:
teamId: acid
numberOfInstances: 3
postgresql:
version: "16"
parameters:
shared_buffers: 512MB
max_connections: "300"
volume:
size: 20Gi
storageClass: sc-topolvm
users:
orders_svc: [createdb]
analyst: []
databases:
orders: orders_svc
patroni:
pg_hba: [host all all 10.0.0.0/8 md5]
synchronous_mode: true
synchronous_node_count: 1
resources:
requests: {cpu: "1", memory: 2Gi}
limits: {cpu: "2", memory: 4Gi}
enableConnectionPooler: true转换后的结果(工具输出的内容——一个 Cluster 加一个 Pooler):
apiVersion: postgresql.cnpg.io/v1
kind: Cluster
metadata:
name: acid-orders
spec:
instances: 3
imageName: <postgresql-16-operand-image> # per your platform registry
inheritedMetadata:
labels:
acid.zalan.do/team: acid
bootstrap:
initdb:
database: orders
owner: orders_svc
managed:
roles:
- {name: analyst, ensure: present, login: true}
- {name: orders_svc, ensure: present, login: true, createdb: true}
postgresql:
parameters:
shared_buffers: 512MB
max_connections: "300"
pg_hba: [host all all 10.0.0.0/8 md5]
synchronous:
method: any
number: 1
dataDurability: preferred # synchronous_mode without 'strict'
storage: {size: 20Gi, storageClass: sc-topolvm}
resources:
requests: {cpu: "1", memory: 2Gi}
limits: {cpu: "2", memory: 4Gi}
---
apiVersion: postgresql.cnpg.io/v1
kind: Pooler
metadata:
name: acid-orders-pooler-rw
spec:
cluster: {name: acid-orders}
type: rw
instances: 2 # Zalando default
pgbouncer:
poolMode: transaction # Zalando default (CNPG default is session!)在发布验收期间,这一转换已完成端到端验证:转换后的 manifest 成功部署到了一个健康的 3 实例集群中,并通过 SQL 验证了引导数据库/owner、角色标志、同步复制(ANY 1 (...))、参数以及 pg_hba;写入则通过 transaction 模式下的 Pooler 执行。
对应用而言,变化如下:
| Zalando | CloudNativePG | |
|---|---|---|
| write endpoint | acid-orders.<ns>.svc | acid-orders-rw.<ns>.svc(或 Pooler service) |
| read endpoint | acid-orders-repl.<ns>.svc | acid-orders-ro.<ns>.svc |
| credentials | orders_svc.acid-orders.credentials... secret | acid-orders-app(bootstrap owner)/ 你的 basic-auth Secret |