在 Kubernetes 中使用 Patroni
原始页面: https://patroni.readthedocs.io/en/latest/kubernetes.html
Patroni 可以利用 Kubernetes 对象来存储集群状态并管理领导者键,从而无需任何额外的一致性存储即可在 Kubernetes 环境中运行 PostgreSQL——也就是说,不需要单独部署 Etcd。Patroni 支持两种不同类型的 Kubernetes 对象来存储领导者键和配置键,通过 kubernetes.use_endpoints 配置项或 PATRONI_KUBERNETES_USE_ENDPOINTS 环境变量进行选择。
使用 Endpoints
尽管这是推荐模式,但出于兼容性考虑,默认情况下该模式是关闭的。启用后,Patroni 会将集群配置和领导者键存储在其创建的 Endpoints 对象的 metadata: annotations 字段中。与使用 ConfigMaps 相比,这种方式的领导者切换更为安全——包含领导者信息的注解与指向当前领导者 Pod 的实际地址,会在同一次操作中被原子更新。
使用 ConfigMaps
在此模式下,Patroni 将创建 ConfigMaps 而非 Endpoints,并将键值存储在 ConfigMaps 的元数据中。领导者切换至少需要两次更新操作:一次更新领导者 ConfigMap,另一次更新对应的 Endpoint。
若要将流量引导至 PostgreSQL 主库,您需要将 Kubernetes PostgreSQL Service 配置为使用带有 role_label(在 Patroni 配置中设定)的标签选择器。
请注意,在某些场景下(例如在 OpenShift 上运行时)只能使用 ConfigMaps 模式。
配置
Patroni 的 Kubernetes 配置项 和 环境变量 在文档的通用章节中有详细说明。
自定义角色标签
默认情况下,Patroni 会根据节点角色在其所在 Pod 上设置对应标签,例如 role=primary。标签的键名和值可通过 kubernetes.role_label、kubernetes.leader_label_value、kubernetes.follower_label_value 和 kubernetes.standby_leader_label_value 进行自定义。
如需从默认角色标签迁移到自定义标签,可按照以下步骤操作以减少停机时间:
- 使用
kubernetes.tmp_role_label(如tmp_role)为 Pod 添加一个使用原始角色值的临时标签。所有 Pod 重启后,Patroni 将为其设置以下标签:
labels: cluster-name: foo role: primary tmp_role: primary
- 待所有 Pod 更新完成后,将 Service 的选择器修改为使用临时标签:
selector: cluster-name: foo tmp_role: primary
- 添加自定义角色标签(例如,设置
kubernetes.leader_label_value=primary)。所有 Pod 重启后,Patroni 将为其设置以下新标签:
labels: cluster-name: foo role: primary tmp_role: primary
- 待所有 Pod 再次更新完成后,将 Service 的选择器修改为使用新的角色值:
selector: cluster-name: foo role: primary
- 最后,从配置中删除临时标签并更新所有 Pod:
labels: cluster-name: foo role: primary
示例
- Patroni 仓库的 kubernetes 目录中包含 Docker 镜像示例以及用于测试 Patroni Kubernetes 部署的 Kubernetes 清单文件。请注意,在当前状态下,由于权限问题,无法使用 PersistentVolumes。
- 支持 Persistent Volumes 的完整功能 Docker 镜像可在 Spilo 项目 中找到。
- 此外,还有一个 Helm Chart 可用于在 Kubernetes 上部署配置了 Patroni 的 Spilo 镜像。
- 若要大规模运行基于 Patroni 和 Spilo 的数据库集群,请参阅 postgres-operator 项目,它实现了用于管理 Spilo 集群的 Operator 模式。