登录
推荐 文章 Go 技术 课程 下载 专题 AI
首页 >  科技周边 >  业界新闻

OpenBao 与 CloudNativePG 组合带来的密钥管理路径

来源:17golang原创

时间:2026-10-01 21:03:47 151浏览 收藏

OpenBao 与 CloudNativePG 的组合,核心不是“再部署一个数据库”,而是把 OpenBao 的持久化状态交给一个由 CloudNativePG 管理的 PostgreSQL 集群,同时让 OpenBao 使用数据库客户端证书而不是长期密码连接。这样,密钥服务、数据库复制和 Kubernetes 编排各自负责一层,故障排查也有清晰的边界。

官方地址:https://openbao.org/

CloudNativePG 官方地址:https://cloudnative-pg.io/

落地这条路径时,先由 CloudNativePG 创建三实例数据库和客户端证书,再用一次性高权限任务建好 OpenBao 所需表,最后让 OpenBao 以 mTLS、最小 DML 权限和 PostgreSQL storage 运行。不要让运行时角色拥有建表权限,也不要把本地测试集群的调度容忍直接带进生产。

先看清这次组合解决了什么问题

CNCF 最近发布的实践文章展示了一个具体方向:OpenBao 使用原生 PostgreSQL storage backend,CloudNativePG 提供自愈、同步复制和证书认证的 PostgreSQL 集群。OpenBao 保存的是自己的加密键值状态,CloudNativePG 负责数据库实例、主备切换和证书 Secret。应用仍然通过 OpenBao 的 KV、Transit 或其他 secrets engine 访问秘密,不需要直接读取 PostgreSQL 表。

这条链路可以画成:CloudNativePG Cluster → DatabaseRole 证书 Secret → schema-init Job → PostgreSQL storage → OpenBao HA 服务。其中任意一段没完成,OpenBao Pod 可能仍然是 Running,但密钥服务并没有真正可用。

OpenBao 与 CloudNativePG 密钥管理路径架构图
图1:OpenBao 与 CloudNativePG 的组合把数据库高可用、证书认证、表初始化和密钥服务拆成四层。

这篇实践的事实背景来自 CNCF 的《Running OpenBao on Kubernetes with a CloudNativePG PostgreSQL backend》;OpenBao 的 Kubernetes、KV v2 与 PostgreSQL storage 文档用于确认配置边界。

用 CloudNativePG 建立证书认证的数据库底座

测试集群可以先准备 Docker、Kind、Helm 和 kubectl,再按 CloudNativePG playground 的方式安装依赖。生产环境不必照搬 playground,但要保留三个关键设计:数据库实例跨故障域、同步复制的耐久性目标、以及显式的 TLS 客户端认证。

# 创建专用命名空间,数据库和 OpenBao 的 Secret 保持在同一边界内
kubectl create namespace openbao

# 应用 CNPG Cluster、DatabaseRole 和 Database 资源
kubectl apply -f cnpg-stack.yaml

# 先观察三实例,再确认控制器报告的集群状态
kubectl get pods -n openbao -w
kubectl cnpg -n openbao status openbao-db

Cluster 可以设置 instances: 3,并使用 synchronous.method: any 与 number: 1 表示至少一个同步副本满足耐久性条件。两个 DatabaseRole 分别承担一次性建表的 owner 和运行时的 openbao-rw,都打开 clientCertificate。

# 只允许带 TLS 的客户端证书连接,拒绝同一角色的明文连接
postgresql:
  synchronous:
    method: any
    number: 1
  pg_hba:
    - hostssl openbao openbao all cert
    - hostssl openbao openbao-rw all cert
    - hostnossl openbao openbao all reject
    - hostnossl openbao openbao-rw all reject

pg_hba 不是装饰配置:如果没有这几条规则,连接可能回落到默认认证方式,而没有密码 Secret 的角色会直接失败。CloudNativePG 创建的客户端证书 Secret 还要以严格权限挂载,通常把 Secret volume 的 defaultMode 设为 0640,避免 PostgreSQL 客户端拒绝过于宽松的私钥权限。

先由高权限角色初始化 OpenBao 表

OpenBao 开始运行前,需要先准备 PostgreSQL storage backend 使用的表。示例中的 openbao_kv_store 保存键值数据,openbao_ha_locks 保存 HA 锁。表由 owner 角色创建,运行时角色只拿到必要的读写和锁更新权限。

# 该 SQL 由一次性 Job 使用 owner 证书执行,不要让运行时角色建表
CREATE TABLE IF NOT EXISTS openbao_kv_store (
  parent_path TEXT NOT NULL,
  path        TEXT NOT NULL,
  key         TEXT NOT NULL,
  value       BYTEA,
  PRIMARY KEY (path, key)
);

CREATE TABLE IF NOT EXISTS openbao_ha_locks (
  ha_key       TEXT NOT NULL PRIMARY KEY,
  ha_identity  TEXT NOT NULL,
  ha_value     TEXT,
  valid_until  TIMESTAMPTZ NOT NULL
);

-- 运行时只做数据与锁的 DML,不获得 CREATE
GRANT SELECT, INSERT, UPDATE, DELETE
  ON openbao_kv_store, openbao_ha_locks TO "openbao-rw";

-- 收紧数据库和 public schema 的默认可见范围
REVOKE CONNECT ON DATABASE openbao FROM PUBLIC;
GRANT CONNECT ON DATABASE openbao TO "openbao-rw";
REVOKE ALL ON SCHEMA public FROM PUBLIC;
GRANT USAGE ON SCHEMA public TO "openbao-rw";

这里的顺序很重要:先创建表和授权,再部署 OpenBao,并在 storage 配置中打开 skip_create_table。否则 OpenBao 第一次连接时可能尝试自行建表,而 openbao-rw 的最小权限设计会让启动失败。

用 Helm 让 OpenBao 只把状态放进 CNPG

OpenBao 官方 Helm chart 支持 HA 部署。下面是需要关注的配置片段,连接串使用 CNPG 的读写 Service,并通过客户端证书和 CA 校验 PostgreSQL。示例中的明文 listener 只适合被集群内 TLS 终止层保护的实验环境,生产部署应按实际入口启用端到端 TLS。

# openbao-values.yaml:关闭每个 OpenBao Pod 自己的本地数据盘
server:
  dataStorage:
    enabled: false
  ha:
    enabled: true
    replicas: 3
    config: |
      storage "postgresql" {
        # 证书文件来自 CloudNativePG DatabaseRole Secret
        connection_url    = "postgres://openbao-rw@openbao-db-rw:5432/openbao?sslmode=verify-full&sslcert=/etc/openbao/certs/tls.crt&sslkey=/etc/openbao/certs/tls.key&sslrootcert=/etc/openbao/ca/ca.crt"
        table             = "openbao_kv_store"
        ha_table          = "openbao_ha_locks"
        ha_enabled        = "true"
        skip_create_table = "true"
      }
  # Secret volume 的结构直接传给 StatefulSet Pod
  volumes:
    - name: cnpg-client-cert
      secret:
        secretName: role-openbao-rw-client-cert
        defaultMode: 0640
    - name: cnpg-client-ca
      secret:
        secretName: openbao-db-ca
        defaultMode: 0640
  volumeMounts:
    - name: cnpg-client-cert
      mountPath: /etc/openbao/certs
      readOnly: true
    - name: cnpg-client-ca
      mountPath: /etc/openbao/ca
      readOnly: true

# 安装官方 chart,配置文件只在本地测试目录保存
helm repo add openbao https://openbao.github.io/openbao-helm
helm repo update
helm install openbao openbao/openbao -n openbao -f openbao-values.yaml

dataStorage.enabled: false 表示 OpenBao 不再为每个副本申请一块无用的本地 PVC;实际状态由 CNPG 提供。ha_enabled 和 ha_table 让多个 OpenBao 副本共享锁状态。证书 Secret 的文件路径、Service 名称、CA 名称必须和实际资源一致,不能只复制配置片段。

按结果检查链路,而不是只看 Pod Running

建议按由下到上的顺序检查。第一层是三台 PostgreSQL 实例是否 Ready、至少一个 standby 是否处于同步状态;第二层是两个 DatabaseRole 证书 Secret 是否生成,挂载后的私钥权限是否可读;第三层是 schema-init Job 是否创建两张表并完成撤销/授权;第四层才是 OpenBao 是否能完成初始化、解封和 HA 加入。

# 检查资源与一次性初始化任务
kubectl get cluster,databaserole,database -n openbao
kubectl get secret -n openbao | grep client-cert
kubectl wait --for=condition=complete job/openbao-schema-init -n openbao --timeout=120s
kubectl logs job/openbao-schema-init -n openbao

# 最后看 OpenBao 副本与服务状态;失败时回到上一层排查
kubectl get pods,svc -n openbao
kubectl logs statefulset/openbao -n openbao

如果日志提示 permission denied,优先检查表授权和 skip_create_table;如果提示证书校验失败,检查 Service DNS、CA、证书文件名和 sslmode=verify-full;如果只有一个副本被创建,检查 StatefulSet 的 unseal 顺序与节点反亲和,而不是马上增加资源。

区分示例可用与生产可用的边界

这条路径的价值在于职责清楚,并不意味着三副本就自动等于完整灾备。同步复制可以提高数据耐久性,但仍需单独规划备份、恢复演练、CA 与 unseal/recovery key 的保管、监控和升级顺序。CloudNativePG 的数据库故障域、OpenBao 的 HA 副本故障域和 Kubernetes 控制面故障域也不一定相互独立。

OpenBao mTLS 与权限边界图
图2:生产边界的关键是一次性建表角色与运行时角色分离,并把证书、恢复和故障域单独管理。

本地 playground 为了凑够调度节点,可能允许 OpenBao 容忍 control-plane 污点;生产集群应提供足够的普通工作节点,保留反亲和规则,不让普通密钥服务工作负载跑到控制面。最后,OpenBao 的 KV v2 使用 data/ 与 metadata/ 等不同路径,ACL 不能沿用 KV v1 的旧路径,迁移时要同步调整策略和客户端。

常见问题

为什么不直接让 OpenBao 使用本地 PVC?

可以,但这会把状态复制、故障切换和数据库运维分散到另一套机制。本文讨论的组合把持久化交给 CNPG,因此关闭 chart 默认的数据盘,避免形成两套事实来源。

为什么要保留一个 owner 角色?

owner 只在初始化或受控迁移时使用,运行时交给 openbao-rw。这样 OpenBao 启动时即使遭遇异常,也不能随意创建或修改数据库结构。

这是不是自动完成了密钥轮换?

不是。CloudNativePG 的客户端证书、OpenBao 的访问身份、应用使用的秘密和 unseal/recovery key 是不同对象,需要分别设计轮换、吊销、备份和恢复流程。

如果只记住一条实施顺序,可以按“CNPG 健康与证书 → schema-init 权限 → OpenBao PostgreSQL storage → 初始化与 HA → 备份恢复演练”推进。这个顺序能把数据库、证书、Helm 和密钥服务的故障边界逐层收窄。

声明:本文转载于:17golang原创 如有侵犯,请联系study_golang@163.com删除
相关阅读
更多>
最新阅读
更多>
课程推荐
更多>