docs: 完善 v1alpha1 设计与运维合同

This commit is contained in:
2026-09-10 05:23:33 +00:00
parent 4823eeb767
commit a723372c6e
10 changed files with 732 additions and 91 deletions
+76 -41
View File
@@ -1,59 +1,94 @@
# 初始架构
# 系统架构
## 职责边界
本文是已批准 [`specification.md`](specification.md) 的架构视图。规范定义外部行为,
本文解释组件边界;二者冲突时以规范为准。当前仓库仍处于 API 骨架阶段。
Kubernetes API 保存期望状态和最近一次观察结果;PostgreSQL catalog 是 database、
role 和权限的事实来源;OpenBao 是凭据的事实来源。controller 不把明文密码写入
Kubernetes API、Event 或日志。
## 组件与数据流
```text
Git / kubectl / Terraform / Backstage
|
v
Kubernetes API (CRD)
|
v
postgresql-tenant-operator
| |
v v
external PostgreSQL OpenBao
GitOps / kubectl / Terraform / Backstage
|
v
Kubernetes API (CRD)
|
v
postgresql-tenant-operator
| | |
v v v
PostgreSQL DBMS OpenBao KV ExternalSecret
catalog+registry |
v
Kubernetes Secret
```
- Kubernetes `spec` 保存期望状态;`status.phase` 保存 controller 状态机 checkpoint,
其他 status 字段保存可重建的观察结果。整个 status 都必须能由外部事实保守恢复。
- PostgreSQL catalog 保存 database、role、grant 和 extension 的实际状态。
- 两个 CR 的 `status.phase` 是 controller 状态机的权威 checkpoint。
- PostgreSQL 管理 database 中的 controller registry 只负责所有权、安装身份和保留标记。
- OpenBao KV v2 是应用凭据的事实来源。
- External Secrets Operator(ESO)读取 OpenBao,并创建应用使用的 Kubernetes Secret。
controller 不运行 PostgreSQL/OpenBao,不管理 VM、存储、备份或 OpenBao PKI,也不直接
把明文凭据写入 Kubernetes API。
## 资源模型
### PostgreSQLInstance
`PostgreSQLInstance` 是 cluster-scoped,由平台管理员创建,描述外部 PostgreSQL 的
DNS host、IP host address、端口、管理 database、TLS 模式、OpenBao 管理凭据引用和
extension allowlist。
Cluster-scoped,由平台管理员创建。它描述服务器端点、管理凭据的 OpenBao 引用,
以及租户可以申请的 extension 白名单。
`PostgreSQLTenant` 是 namespaced。一个 Tenant 对应一个 database、一个同时作为 owner
的 login role、一组只允许追加的 extension、一个由 controller 推导的 OpenBao KV
记录,以及同 namespace 的 ExternalSecret 和目标 Secret。
### PostgreSQLTenant
Tenant namespace 只提供 Kubernetes RBAC 和身份边界。database 与 role 名称在一个
Instance 内仍然全局唯一。
Namespaced,描述一个应用租户,包括 database、无登录 owner role、应用 login
role、extensions、凭据路径和删除策略。
## Reconcile 与所有权
第一版规定一个 tenant 拥有一个 database 和一个 login role。跨租户 grant、多个
login role 和定时轮换等需求出现后再扩展 API。
系统采用最终一致性,不在 Kubernetes、PostgreSQL、OpenBao 和 ESO 之间假装存在分布式
事务。每个外部写入前在 CR status 记录阶段,执行幂等操作,回读验证,再推进阶段:
## Reconcile 原则
```text
Planned -> CredentialCreated -> RoleCreated -> DatabaseCreated
-> ExternalSecretCreated -> CredentialProjected -> Ready
```
- 每轮从 PostgreSQL 和 OpenBao 读取实际状态,不把 `status` 当作事实来源。
- 所有操作幂等;任意步骤失败后可以从下一轮继续。
- 先验证 extension 白名单,再执行任何变更。
- controller 生成密码,调用方只能得到 OpenBao 路径和状态。
- `metadata.generation` 只表示 spec 变更,不承载凭据版本语义。
controller 每轮同时读取 CR、registry、PostgreSQL catalog、OpenBao metadata 和 ESO
投射状态。`status.phase` 是状态机 checkpoint,但不能替代外部回读;丢失或与事实冲突
时必须保守重建/纠正。`metadata.generation` 只表示 spec 修改;Condition 的
`observedGeneration` 表示该版本是否已经完成一次有结论的协调。
## 删除
所有权使用 Instance UID、Tenant UID 与 namespace/name 验证。database/role COMMENT
可以辅助排障,但不能代替 registry。未知资源只报告 `Conflict`,不得修改、接管或
删除。Retain 后用相同名称重建 CR 会获得新 UID,因此仍然冲突。
默认 `deletionPolicy: Retain`。删除 CR 时保留 PostgreSQL database、roles 和
OpenBao 数据。`Delete` 模式将在实现备份检查、活动连接处理和可测试的 finalizer
状态机后加入实际销毁逻辑。
## 创建与删除边界
## 暂不包含
创建时先校验全部输入和冲突,再生成一次密码并写入 OpenBao,随后创建 role、database、
extension 和 ExternalSecret。只有 ESO 已投射 Secret 且应用凭据实际登录成功,Tenant
才可 Ready。
- PostgreSQL 实例、VM 或存储的创建。
- Web UI 或独立 REST API;Kubernetes API 已提供 get、list、watch 和 RBAC。
- PostgreSQL 高可用和备份编排。
- 凭据轮换;controller 只负责首次生成长期凭据并写入 OpenBao。只有出现能够
重新加载凭据并妥善处理现有连接的实际消费者后,才重新评估轮换协议。
- 自动将 OpenBao 数据投射为 Kubernetes Secret;这由 External Secrets Operator
负责。
`Retain` 是默认删除策略,只移除 Kubernetes 管理关系并保留外部资源。显式 `Delete`
使用 finalizer,在重新验证所有权后依次删除 ExternalSecret/Secret、连接、database、
role、OpenBao KV 历史和 registry。详细恢复与逃生步骤见
[`operations.md`](operations.md)。
## 网络与 TLS
Instance 同时公布 DNS `host` 和 IP `hostaddr`。PostgreSQL server 证书必须包含对应的
DNS SAN 和 IP SAN,消费者自行选择可达目标,并可使用 `verify-full` 验证。OpenBao PKI
持有 CA 私钥并签发服务端证书;controller 只挂载公开 CA bundle。
OpenBao 的 controller 内部地址和外部消费者地址可以不同。Tenant status 同时提供目标
Kubernetes Secret reference 和不含认证信息的 OpenBao KV v2 API URL。
## 文档入口
- API 字段与 Condition:[`api-reference.md`](api-reference.md)
- 安装、依赖和配置:[`deployment.md`](deployment.md)
- 本地与 CI 测试:[`development.md`](development.md)
- 安全模型与最小权限:[`security.md`](security.md)
- 现有数据库迁移:[`migration.md`](migration.md)
- 日常排障和删除逃生:[`operations.md`](operations.md)