Files
postgresql-tenant-operator/docs/deployment.md
T
panxiao81 a4d835e612
E2E Tests / Run on Ubuntu (pull_request) Failing after 59s
Tests / Run on Ubuntu (pull_request) Successful in 3m55s
Lint / Run on Ubuntu (pull_request) Successful in 4m18s
refactor: assemble and reuse Instance dependencies
2026-09-11 15:54:05 +00:00

137 lines
7.5 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# 部署与配置
| 项目 | 内容 |
| --- | --- |
| 状态 | Review |
| 环境 | homelab Kubernetes + 外部 PostgreSQL/OpenBao |
| 最后更新 | 2026-09-10 |
本文定义 v1alpha1 的运行依赖、启动顺序和部署级配置。当前 manifests 尚未实现这些
配置,示例是后续实现合同,不可直接用于现有脚手架。
## 依赖与顺序
1. 准备 PostgreSQL VM、持久盘、备份和网络入口。
2. 用 OpenBao PKI 签发 PostgreSQL server 证书,包含 Instance `host` 的 DNS SAN 与
`hostaddr` 的 IP SAN;配置 PostgreSQL 强制 TLS。
3. 创建 PostgreSQL controller 管理 role 和管理 database 连接权限。
4. 在 OpenBao KV v2 写入管理 role 凭据。
5. 配置 OpenBao Kubernetes auth、controller policy 和面向 ESO 的读取 policy。
6. 在 Kubernetes 安装 ESO,创建可读取租户路径的 `ClusterSecretStore`。
7. 创建公开 CA bundle ConfigMap,并挂载到 controller 和需要直接验证数据库的应用。
8. 部署 controller,再创建 Instance;等待 Ready 后才创建 Tenant。
任何一步都不得把真实密码、Token、kubeconfig 或 CA 私钥提交进 Git。
## Controller 配置合同
controller 使用以下 CLI flags。启动入口加载配置、检查本切片必需项并创建共享依赖,
配置错误在启动 manager 前失败。外部服务暂时不可用由 reconcile 重试,不阻止进程启动。
| CLI flag | 必填/默认 | 说明 |
| --- | --- | --- |
| `--openbao-address` | 必填 | controller 可访问的 OpenBao API address |
| `--openbao-consumer-address` | 默认同 `--openbao-address` | 写入 Tenant status,必须能被预期外部消费者解析 |
| `--openbao-auth-mount` | `kubernetes` | Kubernetes auth mount 名称 |
| `--openbao-auth-role` | 必填 | controller ServiceAccount 对应 role |
| `--openbao-kv-mount` | `kv` | KV v2 mount;开发可显式用 `secret` |
| `--openbao-tenant-base-path` | 默认 `postgresql-tenants` | controller 专属 mount-relative 前缀 |
| `--external-secret-store-name` | Tenant 投射时必填 | controller 创建的 ExternalSecret 固定引用;Instance Ready 不依赖此项 |
| `--postgresql-ca-bundle-path` | PostgreSQL TLS 模式必填 | 只读 PEM trust bundle,不含私钥 |
| `--reconcile-timeout` | `30s` | 单轮 reconcile 中外部操作的总期限,必须大于零 |
连接地址由 OpenBao SDK 解析,移除末尾 `/`;配置错误不得携带原始地址中的认证信息。
生产环境使用 HTTPS;HTTP 只用于开发 fixture。consumer URL 的认证信息限制和 Tenant
派生路径限制由对应输出边界负责,Instance 服务不校验尚未使用的 Tenant 配置。
Kubernetes auth 使用 SDK 默认的 ServiceAccount token 挂载路径,不单独暴露路径参数。
启动时创建一个共享 OpenBao client 和凭据源,再注入 Instance 服务。凭据源在有读取需求且
token 即将过期时重新登录;每次登录重新读取投射的 ServiceAccount token。token 被撤销导致
403 时最多重新认证一次,持续 policy 拒绝仍返回错误。
每个 Instance 首次使用时读取管理 username/password 并创建自己的 PostgreSQL 连接池。
后续 reconcile 复用连接池和内存中的凭据,不做自动 PostgreSQL 密码轮换。UID、endpoint
或管理凭据引用改变时释放旧连接并重新装配;只修改 extension allowlist 不重建连接。
删除 Instance 或 controller 正常退出时关闭连接池;重启后按需重新读取 Bao。
仅修改 Bao 中原路径的密码不会触发刷新,管理员需要重启 controller 或修改凭据引用。
基础 manager manifest 不携带 OpenBao 地址、role 等环境值。实际部署通过环境专属
Kustomize overlay 注入上述 args;E2E 由测试 fixture 注入一次性环境配置。
Tenant 路径固定推导为 `<base-path>/<namespace>/<metadata.name>`。namespace/name 都已通过
Kubernetes 名称校验,因此不再允许 CR 提供任意路径。KV v2 API URL 使用 consumer
address 拼为 `<address>/v1/<mount>/data/<base-path>/<namespace>/<metadata.name>`。
base path 必须是合法 mount-relative path,不以 `/` 开头且不包含空段、`.`、`..`、
`data`/`metadata` API 层。ExternalSecret 固定命名为
`<instanceRef>-<metadata.name>-postgresql`;目标 Secret 可由 Tenant 指定,但名称必须
满足 Kubernetes Secret 名称校验,不限制命名内容,默认与 ExternalSecret 同名。
配置变化不得隐式迁移既有凭据。修改 KV mount/base path 或 consumer address 前必须
停止 controller、评估现有 Tenant,并走明确迁移;实现应把 mount/base path 视为安装
身份的一部分并在 registry 留存,以便检测错误配置。
## PostgreSQL 管理 role
生产部署禁止使用 superuser。管理 role 至少需要:
- 连接管理 database、读取必要 catalog;
- 创建/修改受管 login role;
- 创建 database 并指定 owner;
- 撤销 `PUBLIC` CONNECT、授予租户 role CONNECT;
- 连接租户 database 并创建 allowlist extension;
- 创建和维护 controller 专属 registry schema/table;
- `Delete` 时禁止连接、终止目标 database session、删除已验证归属的 database/role。
部分 PostgreSQL 操作天然要求较高权限,尤其终止其他 session 和安装某些 extension。
应优先使用 PostgreSQL 预定义角色、受控 SECURITY DEFINER 管理函数或限定数据库的
授权;任何不得不使用 superuser 的 extension 都必须按实例单独记录,不得扩大默认
controller 权限。最终可执行 SQL grant 将随 PostgreSQL adapter 集成测试固化。
## OpenBao 与 ESO
controller policy 分成两个范围:
- 只读 Instance 管理凭据路径;
- 在固定 tenant base path 下 create/read/update/delete KV v2 data 和 metadata,Delete
必须能永久删除全部版本及 metadata。
ESO 使用独立身份,只需读取 tenant base path;它不应读取 PostgreSQL 管理凭据。
`ClusterSecretStore` 由平台管理员创建,controller 只引用,不创建或修改 Store。
controller 创建的 ExternalSecret 与 Tenant 同 namespace,并设置 ownerReference;目标
Secret 包含固定七键:`username`、`password`、`database`、`host`、`hostaddr`、`port`、
`sslmode`。
## Kubernetes RBAC
- controller 可读/写 Instance、Tenant 的 status/finalizer 和 Event。
- controller 可在 Tenant namespace 创建、读取、更新、删除 ExternalSecret,并只读检查
对应 Secret 是否完成投射。
- namespace 用户可以管理本 namespace Tenant,但不能管理 Instance、Store、controller
配置或其他 namespace 的 ExternalSecret。
- controller 无需读取目标 Secret 的 data;验证登录使用从 OpenBao 读取的应用凭据,
对 Secret 只检查存在性和 ESO 状态。
## 升级与回滚
v1alpha1 尚不承诺跨版本转换。升级前备份 CR、PostgreSQL registry 和 OpenBao metadata,
先在隔离 Kind 环境运行 E2E。禁止在同一组 CR 上同时运行两个 controller 版本。若新版本
在执行任何破坏性迁移前失败,可回滚镜像;涉及 API/storage 或 registry schema 迁移时,
必须先写独立升级规格和回滚步骤。
## 上线验证
```text
PostgreSQL TLS 与备份验证
-> OpenBao auth/policy 验证
-> ClusterSecretStore Ready
-> controller Ready/leader elected
-> Instance Ready
-> 测试 Tenant Ready
-> DNS host 与 IP hostaddr 分别登录
-> 删除测试 Tenant 并验证所选策略
```
生产 homelab 上线前还必须完成 [`security.md`](security.md) 的权限检查和
[`operations.md`](operations.md) 的备份/逃生检查。