新闻详情

新闻详情

首页 / 资讯中心 / 详情

在 OpenShift 上部署 Patroni PostgreSQL 高可用集群:基于模板的动态 UID/GID 适配实战

发布时间:2026/9/25 7:25:00来源:尧图网络
在 OpenShift 上部署 Patroni PostgreSQL 高可用集群:基于模板的动态 UID/GID 适配实战
数据库高可用集群管理运维后端【免费下载链接】patroniA template for PostgreSQL High Availability with Etcd, Consul, ZooKeeper, or Kubernetes项目地址https://gitcode.com/gh_mirrors/pa/patroni点击查看免费下载本篇技术指南围绕 Patroni 项目仓库中的 OpenShift 示例配置 展开系统讲解如何在 OpenShift 的restrictedSCCSecurity Context Constraints约束下部署一套三副本的 PostgreSQL 高可用集群。你将掌握镜像构建、模板参数化部署、持久化与非持久化两种模式的选择、RBAC 权限模型以及容器内 Patroni 配置自动生成的完整链路可直接复制到自己的 OpenShift 项目中使用。OpenShift 适配的核心问题动态 UID/GID 与 restricted SCCOpenShift 与标准 Kubernetes 的一个显著差异在于安全策略默认的restrictedSCC 不允许容器以任意 UID 运行Pod 会被分配一个随机的、高数值的 UID通常大于 10000并且运行用户无法在构建阶段预先确定。传统的容器镜像如果写死了postgres用户的 UID/GID在 OpenShift 下就会遇到数据目录权限不足、进程无法启动等问题。Patroni 仓库为此在 kubernetes/Dockerfile 和 kubernetes/entrypoint.sh 中做了专门的适配使其可以在标准的restrictedSCC 下直接运行。镜像层的权限预置kubernetes/Dockerfile 基于postgres:16官方镜像构建除了常规的 Patroni 安装pip3 install githttps://github.com/patroni/patroni.git#eggpatroni[kubernetes]即带 Kubernetes DCS 依赖的安装方式外还包含三个面向 OpenShift 的关键步骤chmod 775 $PGHOME将/home/postgres目录权限放宽使非属主的随机 UID 也能进入并读写chmod 664 /etc/passwd让容器启动脚本有能力改写/etc/passwd这正是下面动态 UID 注入所依赖的前提USER postgres默认仍以postgres用户身份启动便于与基础镜像的目录属主保持一致。容器启动时的动态 UID/GID 注入kubernetes/entrypoint.sh 是适配的核心脚本开头执行了这样一段逻辑if [[ $UID -ge 10000 ]]; then GID$(id -g) sed -e s/^postgres:x:[^:]*:[^:]*:/postgres:x:$UID:$GID:/ /etc/passwd /tmp/passwd cat /tmp/passwd /etc/passwd rm /tmp/passwd fi其原理是当 OpenShift 注入的运行时 UID 大于等于 10000即restrictedSCC 的典型随机 UID 范围时脚本用sed将/etc/passwd中postgres行的 UID/GID 替换为当前实际值。由于构建阶段已经chmod 664 /etc/passwd容器内用户可以完成这一改写。此后进程虽然以随机 UID 运行但在/etc/passwd中的身份仍被解析为postgres从而满足 PostgreSQL 对数据目录属主的校验逻辑同时规避了 OpenShift 对固定 UID 的限制。部署准备创建项目并构建 Patroni 镜像按照 OpenShift 示例 README 的流程首先创建一个独立的测试项目oc new-project patroni-test接下来需要准备两样东西PostgreSQL 基础镜像ImageStream和 Patroni 应用镜像。原文档给出的命令如下oc import-image postgres:10 --confirm -n openshift oc new-build https://github.com/patroni/patroni --context-dirkubernetes -n openshift其中两点需要说明oc import-image postgres:10用于将官方postgres镜像导入到openshift命名空间形成 ImageStream当前仓库的 kubernetes/Dockerfile 已基于postgres:16因此实际使用时建议按需调整为postgres:16或直接使用你所在集群已导入的版本原文档特别提示如果该模板要提供给多个用户共享使用上述命令应在共享命名空间如openshift中执行这样所有项目都能通过docker-registry.default.svc:5000/${NAMESPACE}/patroni:latest拉取镜像而不必各自重复构建。oc new-build以仓库kubernetes目录为上下文构建这与 kubernetes/Dockerfile 的COPY entrypoint.sh /指令相吻合——entrypoint 脚本就位于该目录内。两种部署模板Ephemeral 与 Persistentkubernetes/openshift-example目录下提供了两套 OpenShift Templatekind: Template清单原文档明确指出二者唯一的区别是 StatefulSet 是否请求持久化存储模板文件Template 名称存储方式适用场景template_patroni_ephemeral.ymlpatroni-pgsql-ephemeralemptyDir测试、验证部署流程template_patroni_persistent.yamlpatroni-pgsql-persistentPVC默认 5GiReadWriteOnce生产级数据持久化Ephemeral 模板的警告原文直述WARNING: Any data stored will be lost upon pod destruction. Only use this template for testing.——所有数据在 Pod 销毁后即丢失仅限测试使用。两者在 StatefulSet 上的存储差异具体体现为Ephemeral 版在volumes中声明emptyDir: {}见 template_patroni_ephemeral.ymlPersistent 版则通过volumeClaimTemplates声明 PVC并将volumes指向persistentVolumeClaim见 template_patroni_persistent.yaml。此外Persistent 版额外加入了一个名为fix-perms的 initContainerinitContainers: - command: - sh - -c - mkdir -p /home/postgres/pgdata/pgroot/data chmod 0700 /home/postgres/pgdata/pgroot/data image: docker-registry.default.svc:5000/${NAMESPACE}/patroni:latest name: fix-perms volumeMounts: - mountPath: /home/postgres/pgdata name: ${APPLICATION_NAME}这个 initContainer 的意义在于PVC 首次挂载时往往为空目录且属主为root而容器实际以随机 UID 运行因此需要先创建数据目录并收紧权限chmod 0700为 PostgreSQL 的初始化扫清障碍。这正是 OpenShift 场景下「存储卷权限修正」的标准做法。模板参数全解两套模板的参数定义基本一致Persistent 版仅多一个PVC_SIZE。下面是完整的参数表值均来自模板的parameters段默认值参数名默认值说明APPLICATION_NAMEpatroni-ephemeral/patroni-persistent所有资源对象的统一标签与应用名PATRONI_CLUSTER_NAME同APPLICATION_NAMEPatroni 集群名即 DCS scope决定 ConfigMap 归属PATRONI_PRIMARY_SERVICE_NAMEpatroni-ephemeral-primary等指向 primary 的只读 Service按role: primary选择器PATRONI_REPLICA_SERVICE_NAMEpatroni-ephemeral-replica等指向 replica 的只读 Service按role: replica选择器MEMORY_LIMIT512Mi容器内存上限模板中预留供资源配额使用NAMESPACEopenshiftPatroni 与 PostgreSQL ImageStream 所在的命名空间PATRONI_SUPERUSER_USERNAMEpostgres初始化用的超级用户账号PATRONI_SUPERUSER_PASSWORDpostgres超级用户密码写入 Secret生产环境务必覆盖PATRONI_REPLICATION_USERNAMEpostgres复制账号用户名PATRONI_REPLICATION_PASSWORDpostgres复制账号密码写入 Secret生产环境务必覆盖SERVICE_ACCOUNTpatroniocp/patroni-persistentPod 与 RoleBinding 使用的服务账号PVC_SIZE仅 Persistent5Gi持久卷申请大小通过oc new-app实例化模板时可用-p 参数名值覆盖任意默认值例如oc new-app patroni-pgsql-ephemeral -p PATRONI_SUPERUSER_PASSWORD强密码 -p PATRONI_REPLICATION_PASSWORD强密码部署步骤安装模板并实例化应用如果模板需要被整个集群共享先将其安装到openshift命名空间oc create -f templates/template_patroni_ephemeral.yml -n openshift然后切换到自己的项目并实例化oc new-app patroni-pgsql-ephemeraloc new-app会按模板展开所有对象。原文档给出了部署完成后的验证方法——检查 ConfigMap$ oc get configmap NAME DATA AGE patroniocp-config 0 1m patroniocp-leader 0 1m这两个 ConfigMap 正是 Patroni 在 Kubernetes/OpenShift DCS 模式下的核心存储patroniocp-config存放动态配置dynamic configurationpatroniocp-leader存放 leader 选举状态。它们的命名规则是${SERVICE_ACCOUNT}-config与${SERVICE_ACCOUNT}-leader与模板中默认的SERVICE_ACCOUNTpatroniocp完全对应。模板内部对象与 RBAC 权限模型深度解析模板通过objects字段一次性声明了 9 类资源理解它们各自的作用是安全运维的前提。Service 三件套集群入口与角色分流${PATRONI_CLUSTER_NAME}ClusterIP端口 5432→5432无选择器的占位 Service配合同名 Endpoints 对象由 Patroni 自行维护成员列表${PATRONI_PRIMARY_SERVICE_NAME}选择器含role: primary始终将流量导向当前主节点${PATRONI_REPLICA_SERVICE_NAME}选择器含role: replica将流量导向只读副本。其中role: primary/role: replica标签由 Patroni 自身在运行过程中动态打上写入 Pod 标签因此这些 Service 天然支持读写分离接入。Secret 与密码注入模板创建一个${PATRONI_CLUSTER_NAME}类型的 Secret其中包含superuser-password和replication-password两个键随后 StatefulSet 中通过secretKeyRef将其注入为PATRONI_SUPERUSER_PASSWORD/PATRONI_REPLICATION_PASSWORD环境变量——密码不会明文出现在 Pod 定义中。StatefulSet 与环境变量注入链StatefulSet 以podManagementPolicy: OrderedReady、replicas: 3有序拉起三个 Pod并设置updateStrategy: OnDelete避免滚动更新打乱选举。每个 Pod 注入的环境变量分为两类来自 Downward API 的动态值PATRONI_KUBERNETES_POD_IPstatus.podIP、PATRONI_KUBERNETES_NAMESPACEmetadata.namespace、PATRONI_NAMEmetadata.name即 Pod 名来自模板参数的固定值PATRONI_KUBERNETES_LABELS格式{application: xxx, cluster-name: yyy}作为 DCS 资源归属过滤条件、PATRONI_SCOPE、PATRONI_POSTGRESQL_DATA_DIR/home/postgres/pgdata/pgroot/data、PATRONI_POSTGRESQL_LISTEN0.0.0.0:5432、PATRONI_RESTAPI_LISTEN0.0.0.0:8008。容器还配置了基于 REST API 的只读探针readinessProbe: httpGet: scheme: HTTP path: /readiness port: 8008 initialDelaySeconds: 3 periodSeconds: 10 timeoutSeconds: 5 successThreshold: 1 failureThreshold: 3/readiness是 Patroni REST API 的标准健康端点与 patroni/api.py 中实现的就绪检查对应只有节点达到可接受写入或可接受只读状态时才返回 200从而保证 Pod 只有在真正就绪时才会被纳入 Service 端点。RBAC最小权限模型模板为${SERVICE_ACCOUNT}创建了一个 Role权限被严格限定在configmapscreate/get/list/patch/update/watch/delete其中delete仅patronictl remove需要注释已明确说明endpointsget/patch/update外加create/list/watch后三个仅在启用 endpoints 模式时需要delete同样仅patronictl remove需要podsget/list/patch/update/watch用于读取成员状态与打角色标签。随后通过RoleBinding将该 Role 绑定到服务账号。这里值得注意的一个细节是模板末尾还声明了名为patroni-k8s-ep-access的ClusterRole仅允许get名为kubernetes的 endpoints及其ClusterRoleBinding。模板中对此有明确注释这些权限仅当集群部署在非default命名空间、且开启PATRONI_KUBERNETES_BYPASS_API_SERVICEtrue时需要。bypass_api_service的语义在 patroni/dcs/kubernetes.py 中体现为bypass_api_service not self._ctl and config.get(bypass_api_service)即绕过 Kubernetes Service 直连 API Server其内部实现见 kubernetes.py 的 ApiClient会通过解析 endpoints 缓存 API Server 地址列表并在访问失败时自动刷新缓存、轮换节点这正是模板中该 ClusterRole 需要getkubernetesendpoints 的原因。容器内的 Patroni 配置生成链路OpenShift 模板通过环境变量把运行时信息注入容器而最终 Patroni 的 YAML 配置文件由 kubernetes/entrypoint.sh 在启动时动态生成。生成的patroni.yml包含以下关键片段bootstrap: dcs: postgresql: use_pg_rewind: true pg_hba: - host all all 0.0.0.0/0 md5 - host replication ${PATRONI_REPLICATION_USERNAME} ${PATRONI_KUBERNETES_POD_IP}/16 md5 - host replication ${PATRONI_REPLICATION_USERNAME} 127.0.0.1/32 md5 initdb: - auth-host: md5 - auth-local: trust - encoding: UTF8 - locale: en_US.UTF-8 ->oc get pods -L rolePatroni 会自动为节点打上role: primary/role: replica标签确认存在一个主节点与两个副本节点即代表选举正常。进入主节点容器后可通过patronictl list查看集群成员与复制延迟kubernetes/README.md 中展示了标准 Kubernetes 下的同类输出示例OpenShift 环境结果一致。需要说明的运维边界密码类模板参数PATRONI_SUPERUSER_PASSWORD、PATRONI_REPLICATION_PASSWORD在生产环境必须通过-p覆盖默认值且应结合 OpenShift 的 Secret 管理实践如外部 Secrets 同步使用Ephemeral 模板仅适用于功能验证数据落盘需求应使用 Persistent 模板并合理设置PVC_SIZE模板中 Role 对configmaps/endpoints的delete权限仅服务于patronictl remove等显式清理操作日常运维无需担心误删若将集群部署在非default命名空间且启用了PATRONI_KUBERNETES_BYPASS_API_SERVICEtruepatroni-k8s-ep-accessClusterRoleBinding 中的namespace字段必须改为实际部署命名空间。仓库还提供了 Jenkinsfile 示例描述了一条可选的 CI 链路创建独立的 pgbench Pod 对 Patroni 集群执行基准与正确性测试可作为模板部署后的自动化验证参考。赞分享数据库高可用集群管理运维后端【免费下载链接】patroniA template for PostgreSQL High Availability with Etcd, Consul, ZooKeeper, or Kubernetes项目地址https://gitcode.com/gh_mirrors/pa/patroni点击查看免费下载相关推荐Algoliasearch-client-php与Laravel集成构建闪电般快速的搜索体验Algoliasearch client php与Laravel集成构建闪电般快速的搜索体验 Algoliasearch client php是一个功能齐全且数据库高可用集群管理运维后端PDF补丁丁免费强大的PDF处理工具箱完整指南PDF补丁丁免费强大的PDF处理工具箱完整指南 你是否曾经为PDF文档的编辑问题而烦恼想要修改PDF书签却找不到合适的工具需要合并多个PDF文件但不想付费数据库高可用集群管理运维后端Meshery 设计模式基于 CNPG Operator 在 GKE 上部署高可用 PostgreSQL 集群postgreSQL cluster 0.0.1Meshery 设计模式基于 CNPG Operator 在 GKE 上部署高可用 PostgreSQL 集群postgreSQL cluster 0.0.云原生微服务运维DevOps上一篇Rodauth-Rails部署指南生产环境配置与性能优化最佳实践下一篇Kronos源码探秘NTPClient与DNSResolver组件的设计与实现创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
网站建设高端定制企业官网
RELATED

相关资讯

更多精彩内容,欢迎继续阅读

较早相关资讯

最新相关资讯

Kata Containers 开源许可策略解析:Apache 2.0 双轨授权与 SPDX 标识的工程落地 2026/9/25 8:04:29

Kata Containers 开源许可策略解析:Apache 2.0 双轨授权与 SPDX 标识的工程落地

云原生容器运行时 【免费下载链接】kata-containers Kata Containers is an open source project and community working to build a standard implementation of lightweight Virtual Machines (VMs) that feel and perform like containers, but provide the workload isolat…

阅读更多 →
RVC 零基础实战:用 10 分钟语音训练专属 AI 变声音色,一次跑通 2026/9/25 8:04:29

RVC 零基础实战:用 10 分钟语音训练专属 AI 变声音色,一次跑通

RVC 零基础实战&#xff1a;用 10 分钟语音训练专属 AI 变声音色&#xff0c;一次跑通 【免费下载链接】Retrieval-based-Voice-Conversion-WebUI Easily train a good VC model with voice data < 10 mins! 项目地址: https://gitcode.com/GitHub_Trending/re/Retrieval-…

阅读更多 →
opencodex Claude Desktop 分支拆分实战:用 `--force-with-lease` 在 `dev` 上安全重写历史并保留完整功能分支 2026/9/25 8:04:28

opencodex Claude Desktop 分支拆分实战:用 `--force-with-lease` 在 `dev` 上安全重写历史并保留完整功能分支

【免费下载链接】opencodex Universal provider proxy for OpenAI Codex & Claude Code — use any LLM (Claude, Gemini, Grok, DeepSeek, Ollama…) with Codex CLI, App, SDK, and Claude Code 项目地址&#xff1a; https://gitcode.com/gh_mirrors/ope/opencodex 点击…

阅读更多 →
VS Code + Codex 在 WSL 中使用的正确姿势:TaoToken 统一 Key 配置与 UNC 路径避坑指南 2026/9/25 8:04:22

VS Code + Codex 在 WSL 中使用的正确姿势:TaoToken 统一 Key 配置与 UNC 路径避坑指南

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

阅读更多 →
人生堆栈|庖丁解牛 2026/9/25 8:04:22

人生堆栈|庖丁解牛

总纲&#xff1a;借用计算机「堆栈&#xff08;Stack&#xff09;」的底层逻辑&#xff0c;映射人生里任务、思绪、目标、压力的处理秩序。堆栈遵循后进先出&#xff1a;最后压进来的事情&#xff0c;最先被拿出来处理&#xff1b;更早埋下的底层事项&#xff0c;被压在最下面&…

阅读更多 →
buildah 依赖深读:pkg/errors 错误处理库的上下文包装、Cause 溯源与调用栈追踪 2026/9/25 8:04:22

buildah 依赖深读:pkg/errors 错误处理库的上下文包装、Cause 溯源与调用栈追踪

云原生 【免费下载链接】buildah A tool that facilitates building OCI images. 项目地址&#xff1a; https://gitcode.com/gh_mirrors/bu/buildah 点击查看 免费下载 本篇技术指南以 buildah 仓库中 vendored 的 github.com/pkg/errors 库的官方 README&#xff08;vendor/…

阅读更多 →

今日资讯

本周资讯

本月资讯

看完文章仍有疑问?

联系尧图顾问,获取一对一建站咨询

立即免费咨询 📞 400-888-8888
📞 ✉