fix: 复用 manager kubeconfig 通过 TokenRequest 登录 OpenBao
This commit is contained in:
+20
-11
@@ -168,33 +168,42 @@ Instance 删除首先释放本地连接并撤销 Ready。任何引用它的 Data
|
||||
真实后端覆盖创建/回读、并发唯一创建、重建适配器读取、软删除冲突、固定前缀 token
|
||||
拒绝管理路径,以及成功写入后丢失响应;HTTP 故障测试补充不重试和错误脱敏。
|
||||
|
||||
凭据存储与下面的认证会话尚未接入 manager;Database 状态中的稳定位置和已确认步骤、
|
||||
供应 service/controller、PostgreSQL 创建以及 ESO 交付仍未完成。
|
||||
认证会话已按下面的显式参数接入 manager;凭据存储尚未接入供应用例。
|
||||
Database 状态中的稳定位置和已确认步骤、供应 service/controller、PostgreSQL 创建以及 ESO 交付仍未完成。
|
||||
测试 token 只用于临时 fixture,不是生产静态 token 配置接口。现有绑定不会触发外部写入。
|
||||
|
||||
## OpenBao Kubernetes 认证会话
|
||||
|
||||
`adapter/openbao.KubernetesSession` 复用官方 Kubernetes auth helper 和 `LifetimeWatcher`
|
||||
(均为 v2.7.0)。调用方提供专用 SDK client、固定 auth mount/role 与绝对 SA token 文件路径;
|
||||
构造时清空既有 token,不使用静态 token 作为失败后的回退身份。每次重新登录读取指定文件,
|
||||
拒绝缺失或空文件,避免 SDK 的空 token 默认路径回退。登录结果必须包含有效 token 和有限 TTL。
|
||||
(均为 v2.7.0)。认证与 reconcile 共用 manager 的 Kubernetes 配置:标准 `--kubeconfig` /
|
||||
`KUBECONFIG` 支持 systemd 或其他集群外运行方式,集群内使用 in-cluster 配置,不要求存在 Pod。
|
||||
Kubernetes 身份的签发和更新由部署管理及 client-go 的认证机制负责,不另建 kubeconfig 读取器。
|
||||
|
||||
每次登录前,使用该身份调用固定 namespace/name 的 ServiceAccount TokenRequest,申请
|
||||
audience 匹配 OpenBao role、期望有效期 600 秒的短期 JWT;检查返回值非空且未过期,再交给
|
||||
官方 Kubernetes auth helper。JWT 不缓存,不读取投射文件,也不回退静态 OpenBao token;
|
||||
实际 JWT 有效期由 API server 决定。RBAC 拒绝或 TokenRequest 失败时不会继续 Bao 登录。
|
||||
OpenBao 登录结果必须包含有效 token 和有限 TTL。
|
||||
|
||||
续期、到期阈值与等待时间由 SDK 管理;可续期 token 的续期失败就撤下本地 token,不可续期
|
||||
token 由 SDK 监测剩余寿命。会话结束后最多每 5 秒重新登录一次,读取新的投射内容。
|
||||
token 由 SDK 监测剩余寿命。会话结束后最多每 5 秒重新登录一次,并重新申请 Kubernetes JWT。
|
||||
`Ready()` 仅表示当前 lease 正受 SDK 管理,不授权任何 Database 写入,也不能保证下一次请求
|
||||
必然成功。认证/续期响应不写日志、不返回给调用方;后端操作仍独立检查并返回脱敏错误。
|
||||
|
||||
`Start(ctx)` 退出时清空 client token 并等待续期 goroutine 结束。SDK Stop 不取消已经发出的
|
||||
续期 HTTP 请求,因此专用 client 的请求期限固定为 15 秒;不增加新连接池或自己的续期算法。
|
||||
同一会话拒绝并发 Start。当前还未添加 manager flags、Runnable/健康检查装配或生产 auth 配置,
|
||||
不能把适配器验收当成已部署的认证入口。
|
||||
同一会话拒绝并发 Start。manager 使用 Runnable 管理生命周期,并增加 `openbao-auth` readiness
|
||||
检查;认证故障不影响 liveness。`--openbao-address` 为空时不启用,不自动修改生产 auth/RBAC。
|
||||
HTTPS 和显式 CA/系统信任根不可通过 BAO 环境变量降级,参数见 [部署合同](deployment.md)。
|
||||
|
||||
依据官方 [Kubernetes auth](https://openbao.org/docs/auth/kubernetes/) 与
|
||||
[token 生命周期](https://openbao.org/docs/concepts/auth/)。真实测试使用 envtest 签发 SA token,
|
||||
OpenBao 通过专用 reviewer 调用真实 TokenReview;验证短 TTL 续期、撤销后的清空/重新登录、
|
||||
错误 namespace/audience 拒绝以及凭据访问恢复。临时 TokenReview 入口仅允许对应 POST,
|
||||
OpenBao 通过专用 reviewer 调用真实 TokenReview;集群外受限 kubeconfig 启动实际 manager,
|
||||
验证同一配置申请 JWT、短 TTL 续期、RBAC 撤回/恢复与重新登录、跨 namespace/其他 SA 拒绝、
|
||||
错误 OpenBao audience 拒绝以及凭据访问恢复。临时 TokenReview 入口仅允许对应 POST,
|
||||
两段连接均验证 TLS;其 Docker bridge 入口仅为隔离测试,不修改生产 OpenBao 或 Kubernetes。
|
||||
单元测试补充缺失/空文件无回退、投射 token 更新、无期限 lease 拒绝、并发生命周期与退出清理。
|
||||
单元测试补充 TokenRequest 失败/空 token 无回退、重新申请 JWT、无期限 lease 拒绝、
|
||||
并发生命周期、退出清理及 manager 显式参数不受 BAO 环境身份覆盖。
|
||||
|
||||
## 设计入口
|
||||
|
||||
|
||||
@@ -10,7 +10,7 @@
|
||||
| 最后更新 | 2026-09-25 |
|
||||
|
||||
本文定义 v1alpha1 的运行依赖、启动顺序和部署级配置。Instance 观测已接入 manager;
|
||||
OpenBao、ESO 与完整供应装配仍是后续实现合同。
|
||||
OpenBao 认证可显式启用;ESO 与完整供应装配仍是后续实现合同。
|
||||
|
||||
## 依赖与顺序
|
||||
|
||||
@@ -34,18 +34,21 @@ OpenBao、ESO 与完整供应装配仍是后续实现合同。
|
||||
Instance 观测)与 `--database-root-cert`(公开 PostgreSQL CA PEM 路径)。Deployment
|
||||
通过 downward API 获取 namespace,Secret 权限由该 namespace 的 Role 授予。
|
||||
|
||||
以下是尚待实现的供应/交付配置合同,不表示当前 manager 接受这些 CLI flags。
|
||||
以下表格区分已实现的认证参数与尚待实现的供应/交付参数。
|
||||
必填项缺失、路径无效或 duration 不为正数时,进程必须在启动 manager 前失败;
|
||||
不得等到 reconcile 时才逐个资源报告配置错误。
|
||||
|
||||
| CLI flag | 必填/默认 | 说明 |
|
||||
| --- | --- | --- |
|
||||
| `--openbao-address` | 必填 | controller 可访问的 OpenBao API address |
|
||||
| `--openbao-address` | 已实现,默认空 | HTTPS API 地址;为空时关闭认证会话 |
|
||||
| `--openbao-consumer-address` | 默认同 `--openbao-address` | 写入 Tenant status,必须能被预期外部消费者解析 |
|
||||
| `--openbao-auth-mount` | `kubernetes` | Kubernetes auth mount 名称 |
|
||||
| `--openbao-auth-role` | 必填 | controller ServiceAccount 对应 role |
|
||||
| `--openbao-auth-mount` | 已实现,`kubernetes` | Kubernetes auth mount 名称 |
|
||||
| `--openbao-auth-role` | 已实现,启用时必填 | OpenBao 登录 role |
|
||||
| `--openbao-ca-cert` | 已实现,默认系统信任根 | OpenBao 公开 CA PEM 路径 |
|
||||
| `--openbao-kv-mount` | `kv` | KV v2 mount;开发可显式用 `secret` |
|
||||
| `--openbao-service-account-token-path` | `/var/run/secrets/kubernetes.io/serviceaccount/token` | Kubernetes auth 使用的投射 token 文件 |
|
||||
| `--openbao-service-account-namespace` | 已实现,启用时必填 | TokenRequest 目标 SA 的固定 namespace |
|
||||
| `--openbao-service-account-name` | 已实现,启用时必填 | TokenRequest 目标 SA 名称 |
|
||||
| `--openbao-token-audience` | 已实现,`openbao` | SA JWT audience,必须匹配 OpenBao role |
|
||||
| `--openbao-tenant-base-path` | 默认 `postgresql-tenants` | controller 专属 mount-relative 前缀 |
|
||||
| `--external-secret-store-name` | 必填 | controller 创建的 ExternalSecret 固定引用 |
|
||||
| `--database-root-cert` | 已实现 | 只读 PEM trust bundle,不含私钥;沿用 Instance 连接配置 |
|
||||
@@ -56,6 +59,35 @@ address 必须是绝对 `http` 或 `https` URL,不允许 userinfo、query 或
|
||||
`/` 开头,不含空段、`.` 或 `..`;base path 还不得编码 KV v2 的 `data`/`metadata`
|
||||
API 层。生产环境的 `--openbao-address` 必须使用 HTTPS;HTTP 只用于明确的开发 fixture。
|
||||
|
||||
### 集群内与 systemd 共用 Kubernetes 认证
|
||||
|
||||
controller 是 API 客户端,不要求部署为 Pod。OpenBao 认证直接复用 manager 已加载的
|
||||
Kubernetes 配置:集群外可用标准 `--kubeconfig`(或 `KUBECONFIG`),集群内可使用
|
||||
in-cluster 配置。禁止另要求 `/var/run/secrets/.../token` 文件或解析 kubeconfig 中的 bearer token。
|
||||
每次 Bao 登录前通过 TokenRequest 申请新的短期 SA JWT,Kubernetes JWT 与 Bao token 的
|
||||
生命周期分别由 API 签发和官方 SDK 续期管理;不把 kubeconfig 本身当成永久有效凭据。
|
||||
|
||||
管理员为 controller 的实际 Kubernetes 身份授予目标 namespace 内
|
||||
`create serviceaccounts/token`,用 `resourceNames` 限定目标 SA;示例见
|
||||
[最小 RBAC](../../config/samples/database_openbao_auth_rbac.yaml)。集群外 RoleBinding subject
|
||||
对应 kubeconfig 的用户/组,集群内可绑定 manager SA;登录目标 SA 可以独立于调用者身份。
|
||||
controller 不创建 SA、Role/RoleBinding,也不向自己授予权限。不要求 `get secrets` 来获取 JWT。
|
||||
OpenBao role 还需限制 SA 名称、namespace 与 audience,TokenReview reviewer 身份由管理员配置。
|
||||
|
||||
示例启动参数(仅示意,不包含真实 kubeconfig 或凭据):
|
||||
|
||||
```sh
|
||||
manager --kubeconfig=/etc/ayatori/controller.kubeconfig \
|
||||
--database-secret-namespace=ayatori-system \
|
||||
--openbao-address=https://bao.example:8200 \
|
||||
--openbao-auth-role=ayatori-database \
|
||||
--openbao-service-account-namespace=ayatori-system \
|
||||
--openbao-service-account-name=database-openbao-login
|
||||
```
|
||||
|
||||
这里的认证成功只开放 manager readiness,不代表 Database 已具备供应或交付能力。
|
||||
实例管理 Secret 的 namespace 同样由参数指定,systemd 模式不依赖 `POD_NAMESPACE` 环境变量。
|
||||
|
||||
Tenant 不能选择任意凭据路径。凭据必须能随 Database 保留并安全交付给被授权的新 Tenant;
|
||||
原 `<base-path>/<namespace>/<metadata.name>` 定位规则不再直接作为新 API 合同。
|
||||
动态供应位置使用 `<base-path>/<Database UID>`;导入使用 Database 的显式 credentialRef,
|
||||
|
||||
@@ -24,6 +24,9 @@ Kubernetes 管理员、OpenBao 管理员和 PostgreSQL 管理员是平台信任
|
||||
## 凭据处理
|
||||
|
||||
- controller 使用 Kubernetes auth 获取短期 OpenBao token,不配置长期静态 token。
|
||||
- Kubernetes auth 不等于部署在 Kubernetes 内:复用 manager 的 kubeconfig/in-cluster 身份,
|
||||
通过最小 RBAC 的指定 ServiceAccount TokenRequest 获取 JWT,不依赖 Pod 投射文件。
|
||||
kubeconfig 的签发、更新与撤销由部署管理负责;申请失败不回退其他机器身份。
|
||||
- 管理凭据只从 Instance 引用的 controller namespace Secret 读取,不复制到
|
||||
CR/status/Event/metric/trace;管理员维护 ExternalSecret,由 ESO 同步该 Secret。
|
||||
- 动态供应密码使用密码学安全随机源;已有可靠关联时复用 OpenBao 现值,结果不确定时停止并报冲突。
|
||||
|
||||
Reference in New Issue
Block a user