Compare commits
41
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
fee5bbccb3
|
||
|
|
409e350c83
|
||
|
|
a8479178f3 | ||
|
|
d5ad5ee568
|
||
|
|
9bd67a36ba
|
||
|
|
39db8406f8
|
||
|
|
cad034148f
|
||
|
|
90764def8a
|
||
|
|
045c28b5c2
|
||
|
|
1dee295639
|
||
|
|
040b68cc25
|
||
|
|
d8a18793f2
|
||
|
|
3b0ca2245a
|
||
|
|
6c0fdc7ecb
|
||
|
|
c1a00cc28e
|
||
|
|
388e3f86f4
|
||
|
|
106fc29001
|
||
|
|
2d408906b4
|
||
|
|
eed96d3494
|
||
|
|
de13ab813c
|
||
|
|
7ba880cb71
|
||
|
|
78d0a8c03b
|
||
|
|
d8f20c017e
|
||
|
|
4f6b916ae5
|
||
|
|
172c17bfa3
|
||
|
|
8a6ce1d1b1 | ||
|
|
bf74d55813
|
||
|
|
0dbabe9ccd | ||
|
|
aae6138fa5
|
||
|
|
e37957f12d
|
||
|
|
42bcf8190e | ||
|
|
0aaf689e2b
|
||
|
|
0eb3f81726
|
||
|
|
6d614d8d08
|
||
|
|
6863474c01
|
||
|
|
e43442c266
|
||
|
|
adf2812767
|
||
|
|
ceb58eb42b
|
||
|
|
8d0992f039
|
||
|
|
7fdc97e02b | ||
|
|
23ec3f4f5c
|
+4
-2
@@ -69,8 +69,10 @@ accepted 不代表部署完成,implemented 必须附实现和验收依据。
|
||||
无需每次修改都更新首页、所有服务页或整个来源索引。
|
||||
原仓库 README 同步按维护者要求暂缓,不阻塞 wiki 的维护。
|
||||
|
||||
PR 使用 [.gitea/PULL_REQUEST_TEMPLATE.md](.gitea/PULL_REQUEST_TEMPLATE.md),简述问题、最终变化、依据与验证。
|
||||
直接提交也遵循相同的检查与证据规则,不为纯文案修改制造额外审批。
|
||||
按维护者于 2026-09-25 的约定,纯文档变更检查通过后直接提交并推送 main,不另开 PR。
|
||||
含代码、配置或检查器行为变更时仍使用 PR;PR 使用
|
||||
[.gitea/PULL_REQUEST_TEMPLATE.md](.gitea/PULL_REQUEST_TEMPLATE.md),简述问题、最终变化、依据与验证。
|
||||
直接提交仍遵循相同的检查与证据规则,不跳过检查或覆盖 main 上的其他更新。
|
||||
|
||||
## 本地与 CI 检查
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
---
|
||||
title: Ayatori 控制面边界
|
||||
last_reviewed: 2026-09-20
|
||||
last_reviewed: 2026-09-24
|
||||
---
|
||||
|
||||
# Ayatori 控制面边界
|
||||
@@ -34,8 +34,31 @@ Agent/CLI 和人工任务。当前 Job controller 是控制循环与 adapter 的
|
||||
内部 Run 能力,不构成 FaaS、Cloud Run 或应用托管承诺。KaaS 只有出现实际需求时才评估,不是
|
||||
产品路线的必达终点。
|
||||
|
||||
Compute 方向已被记录但延后实施:选择性复用 `core/v1 Node` 与 Lease,由 Ayatori Compute Agent
|
||||
实现节点状态并由自有 controller 调度,不引入 kubelet、Pod 或 kube-scheduler。长期 VM 主路径
|
||||
可以是普通 Linux 节点上的 libvirt/QEMU;Proxmox 用于 brownfield adopt 和过渡。OpenSandbox/Kata
|
||||
microVM 属于 Run/Sandbox 的隔离实现,不因此成为 VirtualMachine 资源。
|
||||
|
||||
Database 资源模型于 2026-09-24 明确采用官方 PV/PVC 的资源/申请分离模式:Instance 提供
|
||||
管理入口,独立 Database 表示实际资源,Tenant 表示用户申请。Retain 保留资源对象,支持
|
||||
人工导入和明确授权后的重新绑定;不维护 PostgreSQL ownership registry,不为创建结果不确定
|
||||
提供自动认领保证。详见 [DBaaS 设计](../services/postgresql-tenant-operator.md#当前资源模型2026-09-24-已确认)。
|
||||
|
||||
新增 Kubernetes 资源生命周期前须核对官方设计方式,记录采用与偏离的语义;参考模式不意味着
|
||||
部署对应上游组件,也不意味着复制全部字段与抽象。
|
||||
|
||||
详细设计以 Ayatori 仓库的
|
||||
[ADR-0001](https://git.ddupan.top/panxiao81/ayatori/src/branch/main/docs/decisions/0001-kubernetes-api-machinery.md)
|
||||
、[ADR-0006](https://git.ddupan.top/panxiao81/ayatori/src/branch/main/docs/decisions/0006-demand-driven-resource-scope.md)
|
||||
和[总体架构](https://git.ddupan.top/panxiao81/ayatori/src/branch/main/docs/architecture/overview.md)为准。
|
||||
本页记录跨 homelab 的稳定边界,不表示 Ayatori 已部署或达到生产可用状态。
|
||||
|
||||
## CI 验证约定
|
||||
|
||||
2026-09-24 维护者决定:全量验证自动在 PR 执行,main push 不再重复运行;保留手动入口。
|
||||
直接推送 main 不会自动验证,常规变更仍应经 PR;基线有实质变化时需更新分支并重验,
|
||||
不能把分支 head 的成功当成任何合并结果的成功。测试项目未减少,不修改分支保护设置。
|
||||
配置与边界见 Ayatori
|
||||
[f347ee5 的环境文档](https://git.ddupan.top/panxiao81/ayatori/src/commit/f347ee5292ecf39ac0ecbb21e162ee406d8ce382/docs/concepts/environments.md),
|
||||
已随 [PR #9](https://git.ddupan.top/panxiao81/ayatori/pulls/9) 合并 main;合并后未触发重复全量验证。
|
||||
这不是整个 homelab 的统一 CI 策略。
|
||||
|
||||
@@ -1,20 +1,23 @@
|
||||
# 架构约束索引
|
||||
|
||||
审阅日期:2026-09-20。以下是现有仓库明确记录的约束摘要;Ayatori 条目来自其独立项目的
|
||||
审阅日期:2026-09-25。以下是现有仓库明确记录的约束摘要;Ayatori 条目来自其独立项目的
|
||||
已接受设计,其余来源路径相对于 homelab-infra。修改时必须读原文和对应代码,新出现的差异
|
||||
先向维护者确认;[首轮状态对齐](../verification.md)已完成。
|
||||
|
||||
| 约束 | 原因与边界 | 来源 |
|
||||
|---|---|---|
|
||||
| 新增监控配置优先使用 ServiceMonitor、PodMonitor、PrometheusRule | VictoriaMetrics Operator 负责转换,避免同一目标/规则维护两套声明;历史 VM 配置按需另行迁移 | 维护者 2026-09-25 明确要求;[基础监控运维](../guides/monitoring-foundation.md) |
|
||||
| Ayatori 复用 Kubernetes API machinery,不复用其容器编排产品边界 | kube-apiserver/etcd 提供 API、watch、RBAC 与状态协调;领域调度、生命周期、恢复和 GC 属于 Ayatori controllers;Kubernetes workload 只是可替换 backend | [Ayatori 控制面边界](ayatori-control-plane.md) |
|
||||
| Kubernetes 内置资源不绑定上游实现组件 | 可由 Ayatori Agent/controller 实现和消费 Node、Lease 等 API;使用 Node 不推导必须部署 kubelet、Pod 或 kube-scheduler | [Ayatori 控制面边界](ayatori-control-plane.md) |
|
||||
| Ayatori 只为已验证的管理缺口新增北向资源 | 当前优先 Database、LoadBalancer、Bucket/Object Storage;VM 价值已确认但南向较重;Run 是内部切片,KaaS 按需,FaaS/PaaS 默认不做 | [Ayatori 控制面边界](ayatori-control-plane.md) |
|
||||
| Ayatori Compute 复用 Node/Lease API,但不引入 Kubernetes workload plane | Compute Agent 实现 Node 状态;libvirt 是长期候选主路径,PVE 是 brownfield 过渡;Kata microVM 属于 Sandbox backend | [Ayatori 控制面边界](ayatori-control-plane.md) |
|
||||
| Database 采用独立资源与用户申请分离 | Instance → Database → Tenant;Retain 保留资源并人工回收,显式导入,不维护 PG registry;替代旧所有权持久化合同 | [DBaaS 设计修订](../services/postgresql-tenant-operator.md#当前资源模型2026-09-24-已确认) |
|
||||
| Samba AD、OCI、Proxmox 优先 IaC,以代码为准 | Ansible/Terraform 声明及任务优先于旧 README;声明不等于已验证部署 | 维护者于 2026-09-16 明确、各服务使用指南 |
|
||||
| 服务独立部署,Terraform root/state 按服务隔离 | 避免认证和变更影响范围绑在一起 | `AGENTS.md`、`CLAUDE.md` |
|
||||
| OpenBao 恢复不能依赖 k3s 或读取自己内部的恢复凭据 | 先恢复信任根,再恢复消费者 | `infrastructure/openbao/README.md`、`CLAUDE.md` |
|
||||
| Terraform 管 API 配置,Ansible 管主机及不能安全纳管的密钥材料 | 不可读回秘密和根密钥不能靠反复重建实现收敛 | `infrastructure/openbao/README.md` |
|
||||
| LAN HTTP 入口为 Envoy Gateway;新增服务核对 parentRefs、DNS 和认证 | 不直接套用 archive 中的 Gateway 示例 | `platform/envoy-gateway/README.md`、`AGENTS.md` |
|
||||
| 人类身份由 Samba AD / Authelia 提供,Authelia 是 active 的唯一主 OIDC broker;workload 身份由 SPIRE 提供 | 身份签发不等于资源授权;SPIRE 基础设施与最小 PoC 已完成,后续集成以 #34 为准 | [Authelia](../services/authelia.md)、[SPIRE 状态与依据](../services/spire.md) |
|
||||
| 人类认证仍由 Samba AD / Authelia 提供;Hydra 作为 Gitea 的实验性签发入口,通过 OIDC 复用 Authelia;workload 身份由 SPIRE 提供 | 2026-09-25 第一轮人类 PoC 扩展了原单 broker 接入边界,未迁移主入口、机器身份或应用权限 | [Authelia](../services/authelia.md)、[Hydra PoC](../services/hydra.md)、[SPIRE](../services/spire.md) |
|
||||
| SPIFFE 提供跨基础设施的统一机器身份入口,替代 workload-sts 统一 IAM 平台方案 | 服务信任 SPIFFE 身份、签发自己的 token 并维护自身权限;非 Kubernetes 身份不依赖 Kubernetes ServiceAccount,优先复用服务现有接入机制 | [核心设计与取舍](../services/spire.md#核心设计与取舍),维护者于 2026-09-16 补充 |
|
||||
| 已由 Flux 接管的资源通过 Git 修改;brownfield 不全局开启 prune | 防止漂移回滚与误删;未接管资源不能假定受 Flux 管理 | `clusters/homelab/README.md` |
|
||||
| DNS 各视图保留权威边界;只管理明确声明的 RRset | 不清理 Samba 自动维护的域记录;LAN 现状按维护者说明对齐,旧源码文档待同步 | `infrastructure/dns/README.md`、[LAN DNS](../services/lan-dns.md) |
|
||||
@@ -28,3 +31,10 @@
|
||||
|
||||
通用变更约束:先做适用的 plan/check/diff,再操作现场;不将凭据和 Terraform state
|
||||
写入知识库;不更新 homelab-infra 的冻结 `CHANGELOG.md`。
|
||||
|
||||
## 待评估草案
|
||||
|
||||
[独立 IAM 与 agent 身份草案](independent-iam-draft.md)(2026-09-25,draft)提出以 Hydra
|
||||
解耦认证与签发,通过 OIDC 接入人类、machine 和 agent,并作为 Ayatori 的独立外部依赖。
|
||||
完整方案仍为草案。2026-09-25 已按维护者要求先实施人类登录 PoC,上表显式记录其有限
|
||||
变更;SPIFFE、agent 动态授权、组模型及 DNS 迁移未随之实施。
|
||||
|
||||
@@ -0,0 +1,249 @@
|
||||
---
|
||||
title: 独立 IAM 草案:人类、机器与 AI Agent 的统一应用接入
|
||||
status: draft
|
||||
last_reviewed: 2026-09-25
|
||||
last_verified: null
|
||||
sources:
|
||||
- https://git.ddupan.top/panxiao81/iam-login/pulls/3
|
||||
- https://git.ddupan.top/panxiao81/iam-login/commit/9cf2d235dff0cd33f98012b0a114f14a8f9bfcda
|
||||
- 维护者于 2026-09-25 的架构讨论与草案记录要求
|
||||
---
|
||||
|
||||
# 独立 IAM 草案:人类、机器与 AI Agent 的统一应用接入
|
||||
|
||||
本页记录完整 IAM 的设计意图,状态仍为 **draft**。2026-09-25 维护者随后选择先实施
|
||||
[Hydra 人类登录 PoC](../services/hydra.md):通用 OIDC 上游适配器暂用 Authelia,Gitea
|
||||
新增 Hydra 登录源;维护者已确认成功返回原账号且仓库权限正常,第一轮人类 PoC
|
||||
验收通过。这不表示完整方案已采纳或开始全面迁移。
|
||||
长期名称、资源模型及 agent 接口尚未确定。
|
||||
|
||||
## 动机与首要目标
|
||||
|
||||
首要目标是降低下游应用集成成本。原生接入 SPIFFE 的应用覆盖有限,OIDC/OAuth 则已有
|
||||
广泛的应用与 CLI 生态。通过独立 IAM 集中处理身份验证,让应用沿用标准登录和授权流程,
|
||||
即可接入人类、传统机器账户和 AI agent,无需每个应用自行验证 SVID 或集成 SPIRE。
|
||||
|
||||
维护者认为,现有方案缺少好用的、真正区分 AI agent 与传统 service account 的身份及
|
||||
授权模型,这是考虑自行建设的主要原因。拟自建的是主体语义、认证编排与授权能力,
|
||||
OAuth2/OIDC 协议和 token 签发优先交给 Hydra。
|
||||
|
||||
Hydra 的核心价值是把“如何验证身份”与“如何完成标准授权流程并签发 token”解耦。
|
||||
统一 token 格式不是主要目标,也不要求所有应用 API 直接接受 Hydra token。
|
||||
|
||||
## 独立服务边界
|
||||
|
||||
IAM 应当能够独立部署、运行和恢复,不依赖 Ayatori 的 API、CRD、controller 或领域资源。
|
||||
Ayatori 是其消费者,依赖关系类似 OpenStack 其他服务对 Keystone 的依赖;这一类比
|
||||
不意味着复刻 Keystone 的全部 API 或功能。即使未来命名为 Ayatori IAM,也不改变边界。
|
||||
|
||||
| 部分 | 拟承担的职责 |
|
||||
|---|---|
|
||||
| 人类认证后端 | 人类登录与 MFA;已选择 Spring Native 方向,首轮 AD 仍为用户与组权威 |
|
||||
| SPIRE | workload 身份证明与 SVID 签发,可辅助 machine 或 agent 认证 |
|
||||
| Login / Consent 与身份授权服务 | 验证不同主体的证明,映射稳定身份,处理登录、授权、组和必要的动态审批 |
|
||||
| Hydra | OAuth2/OIDC 流程、client 与 token 签发 |
|
||||
| 下游应用 | 关联本地账号,执行应用自身权限,按原有机制签发或使用应用凭据 |
|
||||
|
||||
```text
|
||||
人类:交互登录 / 上游 IdP ──────┐
|
||||
机器:SPIFFE 等预配置身份 ─────┼→ 独立身份验证与授权 → Hydra → OIDC/OAuth 消费者
|
||||
Agent:人类授权 / SPIFFE / │ ├→ Gitea 等应用
|
||||
后续专门认证方式 ──────┘ └→ Ayatori API server
|
||||
```
|
||||
|
||||
Ayatori 使用裁剪的 kube-apiserver,目标是让它信任 Hydra 签发的 token 来验证身份,
|
||||
再由自身 RBAC 执行资源授权。具体 token 类型、claims、audience 与 JWT authenticator
|
||||
兼容性需要验证;不能预先把任意 Hydra access token 都视为 API server 可用凭据。
|
||||
|
||||
## 主体类型与认证方式分离
|
||||
|
||||
人类、machine、agent 是不同的主体类型,不能按所用认证协议决定分类。
|
||||
Agent 可以使用 SPIFFE 辅助证明执行环境,而仍然是 agent 主体,不必冒充传统机器账户。
|
||||
Agent 的负责人、委托人及当前执行实例也不应与 agent 自身身份混为一谈。
|
||||
|
||||
| 维度 | 传统机器账户 / CI | AI agent |
|
||||
|---|---|---|
|
||||
| 任务特征 | 预定义流程与资源范围 | 能理解任务、作出决策,可能跨应用并在执行中改变操作路径 |
|
||||
| 权限需求 | 通常可以预先配置 | 潜在范围更广,可能执行中动态申请 |
|
||||
| 授权方式 | 审核配置后按固定规则授予 | 基础权限与任务、会话或限时授权组合,由策略或人类批准 |
|
||||
| 交互能力 | 固定程序处理约定流程 | 可使用 CLI、MCP 和 skills,自主组织请求并在需要时请求批准 |
|
||||
| 审计语义 | 哪个 workload 执行了操作 | 哪个 agent、哪次执行、代表谁、依据哪次授权执行 |
|
||||
|
||||
更广的潜在权限不等于常驻全权。动态批准应转化为服务端认可的授权和适当凭据,
|
||||
不能由 agent 自报身份或声明 scope 就自动生效。申请、批准、期限、撤销以及下游已有
|
||||
会话和 token 的失效语义需要明确设计,不能假设 Hydra 自动提供完整实现。
|
||||
|
||||
认证入口保持可扩展:
|
||||
|
||||
- Remote MCP 的 OAuth 可提供人类参与的授权入口。设计上允许人类在流程中确认或选择
|
||||
agent 身份、委托关系与权限,再由服务端绑定凭据。普通 MCP OAuth 并不自动定义
|
||||
agent 主体语义;具体绑定属于本方案要实现的能力。
|
||||
- SPIFFE 路径以经人类审核的 workload/身份绑定规则为信任来源,运行时验证证明是否
|
||||
满足规则。交互批准和预配置批准都是可用的信任建立方式。
|
||||
- MCP 和 skills 是 agent 参与流程的工具及操作约定,本身不替代可验证凭据。
|
||||
后续可以增加专门的 agent 认证方式,不必现在锁定一个唯一协议。
|
||||
|
||||
Agent 可以独立使用自身权限,也可以接受人类委托。人类授权 agent 不等于 agent
|
||||
变成人类账号;需要时保留“agent A,经用户 B 授权”的关系与审计信息。
|
||||
|
||||
## 无浏览器的标准登录与 Gitea 示例
|
||||
|
||||
Authorization code flow 不要求必须使用图形浏览器。对于可通过 HTTP 完成的流程,
|
||||
agent 可以用 curl/CLI 保存 cookies、跟随重定向、提交表单和身份证明,并到达 callback。
|
||||
必须保留 state、nonce、PKCE 等协议绑定;以 HTTP 客户端执行不意味着跳过这些校验。
|
||||
专用登录 helper 可以作为便利工具,但不是架构前提。
|
||||
|
||||
关键是 Login 服务支持 machine/agent 的身份证明,而不强迫它们完成人类密码、
|
||||
交互 MFA 等认证。Consent 按已有授权策略处理,必要时请求人类批准。
|
||||
|
||||
Gitea 的目标路径包含内外两层授权:
|
||||
|
||||
```text
|
||||
官方 tea CLI 发起 Gitea OAuth 授权
|
||||
→ Gitea 经 OIDC 请求 Hydra 登录
|
||||
→ Login 服务验证 agent 或 machine 的身份
|
||||
→ 接受 login challenge,按策略完成 Hydra consent
|
||||
→ Hydra 回调 Gitea,Gitea 关联对应 bot 账号
|
||||
→ 完成 Gitea 自身对 tea 的授权确认
|
||||
→ Gitea 回调 tea,由 tea 完成 code 交换并取得 Gitea token
|
||||
→ tea 按 bot 的 Gitea 权限调用 API
|
||||
```
|
||||
|
||||
这里 Hydra token 用于 Gitea 的身份登录,Gitea token 用于 CLI 调用应用 API。
|
||||
因此不要求 Gitea API 直接接受 Hydra bearer token,也不以自建 PAT 分发 broker 为前提。
|
||||
Bot 是下游账号映射,不代表所有 agent 共享一个万能 bot。
|
||||
|
||||
该路径尚未端到端验证。需要验证官方 CLI 的授权 URL/callback 交接、Gitea 本地会话与
|
||||
首次授权确认、账号关联和 scope,以及刷新与重新登录。其他应用可复用相同思路,
|
||||
但支持 OIDC 不等于所有应用的无交互授权路径均已兼容,须按具体流程验收。
|
||||
|
||||
## 统一组与下游授权
|
||||
|
||||
集中维护较统一的粗粒度用户组,避免每个应用都独立维护一套 admins 成员关系。
|
||||
应用仍保留自身角色、team 和资源权限,由明确映射决定中央组在应用内的权限。
|
||||
统一组不等于一个全局 admins 自动拥有所有服务的管理权。
|
||||
|
||||
Agent 的动态授权需要落到应用可识别的 scope、角色、账号权限或其他已有授权机制上。
|
||||
仅在 Hydra token 中增加一个 claim,不意味着下游会自动执行或撤销相应权限。
|
||||
具体组名、角色模型及同步方式尚未确定。
|
||||
|
||||
## 人类后端、Samba AD 与 DNS 演进
|
||||
|
||||
### 人类认证后端的接口边界
|
||||
|
||||
2026-09-25 维护者明确:考虑 ZITADEL 是为了复用认证会话与登录状态机,而不是把它作为
|
||||
另一个 OIDC 上游。下一阶段目标是由人类认证后端处理认证因素与会话,适配层验证结果、
|
||||
映射稳定主体并接受 Hydra login challenge;面向下游的 OAuth2/OIDC 仍由 Hydra 提供。
|
||||
第一轮通过 Authelia OIDC 的 PoC 保留为已验收基线,尚未部署此替代路径。
|
||||
|
||||
早期上游接口与源码评估曾形成以下两个候选;后续决定见下方“已确定的实现方向”:
|
||||
|
||||
| 候选 | 可复用能力 | 尚需承担的接入工作 |
|
||||
|---|---|---|
|
||||
| ZITADEL Session API + Login V2 | 逐步验证认证因素、会话、账号管理;Login V2 有登录编排与 UI | 将登录事务绑定到 Hydra challenge,服务端验证认证结果并接回 Hydra;按选定版本验证 LDAP、MFA 与完整恢复流程 |
|
||||
| Ory Kratos + self-service UI | 登录、MFA、恢复与会话流程;上游已有 Hydra login challenge 集成 | 部署和维护独立 UI,保留主体映射与 consent;Samba AD 不能假设存在开箱即用的 LDAP 认证接入 |
|
||||
|
||||
早期评估认为 Kratos 在认证与签发的职责分离上更直接;但若必须继续使用
|
||||
Samba AD 密码登录,LDAP 过渡成本可能使 ZITADEL 更合适。Kratos 本身是 headless 服务,
|
||||
现成参考 UI 不等于无需维护的内置管理门户,亦不能把 Ory Network 的功能直接视为自托管
|
||||
开源版能力。此判断是方案评估,不是新的部署决定。
|
||||
|
||||
ZITADEL Session API 返回会话不等于已完成全部认证;需要确认已验证因素、有效期、用户
|
||||
状态和所需 MFA。官方 Login V2 的流程编排包含这些判断。无 OIDC 上下文登录及默认完成
|
||||
跳转可用,但普通跳转不是传给 Hydra 的认证证明,也不自动绑定原始 login challenge。
|
||||
|
||||
查阅时上游文档与开发分支存在差异:Hosted Login 文档仍列出 LDAP 限制,而
|
||||
[Login V2 固定源码](https://github.com/zitadel/zitadel/blob/5ca0b54ca311c4be535589e7c375f9bea50e3ec2/apps/login/src/lib/server/idp.ts)
|
||||
已有 LDAP 认证实现;不能据此宣称某个发布版本已经验收。部署前需锁定发行版本再验证。
|
||||
|
||||
参考:[ZITADEL Session API](https://zitadel.com/docs/reference/api/session/zitadel.session.v2.SessionService.CreateSession)、
|
||||
[Login App](https://zitadel.com/docs/guides/integrate/login-ui/login-app)、
|
||||
[Hosted Login 限制](https://zitadel.com/docs/guides/integrate/login/hosted-login)、
|
||||
[Kratos Hydra 集成源码](https://github.com/ory/kratos/blob/master/selfservice/flow/login/handler.go)、
|
||||
[Kratos self-service UI](https://github.com/ory/kratos-selfservice-ui-node)、
|
||||
[LDAP 功能请求](https://github.com/ory/kratos/issues/274)。
|
||||
|
||||
### 已确定的实现方向
|
||||
|
||||
维护者已选择 Java、Spring Security 与 GraalVM Native。阻碍 Java 的是 JVM 部署和运行
|
||||
开销;能够通过 Native 功能与资源验收时,Java 仍是优先选择,不引入 Kotlin。
|
||||
Quarkus、Micronaut 也有相应生态支持;最终选择 Spring 同时考虑了维护者的熟悉程度。
|
||||
Keycloak 可参考认证实现,但其服务端模型与 SPI 不直接复用,采用 Quarkus 也不证明
|
||||
Keycloak 有 Native 发行或完整原生兼容性。
|
||||
|
||||
原先薄 OIDC 适配器在 homelab-infra 内维护;现在直接承担 AD、MFA、认证状态与 Native
|
||||
构建测试,因此按维护者决定拆为独立 [iam-login](https://git.ddupan.top/panxiao81/iam-login)
|
||||
仓库,独立于 Ayatori。环境部署仍归 homelab-infra。
|
||||
|
||||
已按维护者提供的 start.spring.io 配置生成 Java 25、Spring Boot 4.1.1、Gradle 与 YAML
|
||||
项目骨架,包含 LDAP、WebAuthn、校验、Actuator/Prometheus、OpenTelemetry/追踪、
|
||||
Testcontainers、UnboundID、Lombok、配置处理器、DevTools 与 Native 插件。依赖存在不表示认证流程已实现;首次实现及 Native
|
||||
验证由 [issue #1](https://git.ddupan.top/panxiao81/iam-login/issues/1) 跟踪。需在原生二进制上
|
||||
验证 AD、MFA、Hydra、持久化及监控,实测资源成本;不能把编译成功等同完整验收。
|
||||
|
||||
首轮保持 AD 用户与组权威并直接映射组名。LDAP 与 MFA 绑定同一稳定主体;切换前需要
|
||||
明确现役 issuer/sub 哈希主体到新主体的连续性映射。MFA 首先验证官方 WebAuthn 集成,
|
||||
恢复与已有凭据迁移方式仍待实现。维护者接受必要时并存多个登录前端。
|
||||
现役 Go/Authelia PoC 保留为已验收基线,尚未切换生产认证路径。
|
||||
|
||||
### 人类浏览器登录界面
|
||||
|
||||
已确定先借鉴 Keycloakify 的交互方式:React + Vite 开发界面,Spring 在首个 HTML 响应中
|
||||
带齐当前步骤和必要上下文,浏览器渲染组件,默认用原生表单 POST,由服务端认证流程
|
||||
决定下一步页面或重定向。局部交互按需使用 JavaScript;后续根据实际体验决定哪些步骤
|
||||
使用 fetch,避免将整个认证流程都搬到客户端路由和状态机。
|
||||
|
||||
页面与 Spring 后端同仓库维护,前端资源构建后随 Native 应用交付。生产不增加 Node/BFF、
|
||||
嵌入式 JavaScript 运行时或 FreeMarker;首轮接受客户端首屏渲染,不实现 React SSR/RSC。
|
||||
当前仅验证浏览器交互原型,不表示 AD、MFA 或 Hydra 登录链路已完成,也不替换现役入口。
|
||||
原型启动、实现与验证见 [iam-login PR #3](https://git.ddupan.top/panxiao81/iam-login/pulls/3)
|
||||
及其浏览器流程文档;后续机器 API 独立设计。
|
||||
|
||||
### 目录与 DNS 迁移
|
||||
|
||||
人类同样使用这套独立 IAM。首轮由 iam-login 直接连接 Samba AD 验证密码、查询用户与组,
|
||||
按原组名直接映射;之后再推进统一粗粒度组模型与目录迁移,不要求同一步替换目录。
|
||||
更换认证后端时应保持稳定主体与下游账号关联,避免按可变邮箱或用户名重新识别账号。
|
||||
|
||||
维护者认为 Samba AD 使用率较低,长期希望完全删除它。退役需处理 LDAP、Kerberos、
|
||||
SMB 域身份、域成员和域 DNS 等实际依赖,不能用网页登录迁移成功代替全部退出条件。
|
||||
|
||||
DNS 可独立评估迁往 PowerDNS Authoritative,主要考虑其 API 与资源成本。可从简单后端
|
||||
开始评估,不预先要求完整 Recursor/UI/数据库集群。实际资源占用尚未测量。
|
||||
AD 存续期间保留其域记录权威与动态更新边界;普通记录的迁移、Blocky/路由器解析链和
|
||||
最终域退役应分别设计。PowerDNS 不是 IAM 的必需组件。
|
||||
|
||||
## 与现役约束的关系
|
||||
|
||||
现役记录仍以 [架构约束](constraints.md)、[Authelia](../services/authelia.md) 和
|
||||
[SPIFFE/SPIRE](../services/spire.md) 为准。当前文档中的 Authelia 主 OIDC 入口、
|
||||
服务直接验证 SPIFFE 后签发自身 token 的规则,仍是现役基础。第一轮人类 PoC 对
|
||||
Gitea 增加实验性 Hydra 签发入口的有限变更已在约束索引中单独记录。
|
||||
|
||||
本草案提出的变化是:增加独立的多主体 IAM,通过 Hydra 解耦认证与签发,让尚不支持
|
||||
SPIFFE 的下游复用 OIDC;并为 agent 增加区别于传统 service account 的身份授权语义。
|
||||
若采纳,应显式更新现役约束和相关服务文档。已能直接使用 SPIFFE 的服务无需强制改道。
|
||||
这也不构成恢复已归档 [workload-sts](workload-sts-history.md) 项目的决定。
|
||||
|
||||
## 后续验证问题
|
||||
|
||||
以下是草案的验证范围,不是已启动的实施任务或第二份动态进度表:
|
||||
|
||||
1. 一个 SPIFFE 主体,通过官方 tea 的 OAuth 入口,用 CLI/HTTP 完成无浏览器登录,
|
||||
以指定 bot 成功调用 Gitea API,同时验证错误身份不能取得该账号。
|
||||
2. 人类和 agent 使用不同认证方式后,下游仍能通过同一 OIDC 接口识别正确身份与组。
|
||||
3. Ayatori 的 kube-apiserver 验证 Hydra token,并正确映射主体、组与 RBAC。
|
||||
4. Agent 动态申请权限,经过策略或人类批准后生效;到期与撤销行为覆盖下游凭据。
|
||||
5. 明确稳定 agent、执行实例、委托者的绑定方式,以及可供 agent 使用的 MCP/CLI 接口。
|
||||
6. 独立评估 Samba 退出条件、PowerDNS 资源成本与 DNS 迁移边界。
|
||||
|
||||
## 上游依据
|
||||
|
||||
以下文档用于说明协议与产品能力,不代表本方案已验证或已选定具体版本:
|
||||
|
||||
- [Hydra Login / Consent 流程](https://www.ory.com/docs/oauth2-oidc/custom-login-consent/flow)
|
||||
- [Gitea OAuth2 provider 与 tea 内置客户端](https://docs.gitea.com/development/oauth2-provider/)
|
||||
- [tea 登录命令定义](https://pkg.go.dev/code.gitea.io/tea/cmd/login)
|
||||
- [Kubernetes 身份验证](https://kubernetes.io/docs/reference/access-authn-authz/authentication/)
|
||||
- [ZITADEL LDAP 上游](https://zitadel.com/docs/guides/integrate/identity-providers/ldap)
|
||||
- [PowerDNS Authoritative HTTP API](https://doc.powerdns.com/authoritative/http-api/index.html)
|
||||
@@ -0,0 +1,135 @@
|
||||
---
|
||||
title: 监控覆盖与补齐计划
|
||||
last_reviewed: 2026-09-25
|
||||
---
|
||||
|
||||
# 监控覆盖与补齐计划
|
||||
|
||||
结论:监控底座和 Telegram 通知已工作,但业务服务接入与告警覆盖明显不足。
|
||||
“有 exporter”“有 PodMonitor”“数据库里曾出现过指标名”都不能代替当前采集成功和有效规则。
|
||||
本页用于接续覆盖建设,服务使用入口仍见 [Grafana](../services/grafana.md)。
|
||||
|
||||
## 第一批补齐进展
|
||||
|
||||
2026-09-25 已上线 kube-state-metrics,并恢复 NATS PodMonitor 转换与采集。
|
||||
新增集群状态 11 条、主机/ZFS 5 条、采集与通知 5 条规则,共 21 条;正式规则总数为 68。
|
||||
新增资源按维护者要求优先使用 ServiceMonitor/PodMonitor/PrometheusRule。
|
||||
具体阈值、降噪边界、声明转换关系与验收方法见 [基础监控与告警运维](monitoring-foundation.md)。
|
||||
|
||||
下面的规模、矩阵和盲点保留初轮盘点基线,不能再当作第一批实施后的现状。
|
||||
第二批数据库/OpenBao/存储/备份、外部探测和集群外心跳尚未实施。
|
||||
|
||||
## 证据和范围
|
||||
|
||||
2026-09-25 17:26–17:31 UTC,只读检查当前集群工作负载、采集 CR、vmagent 实际 targets、
|
||||
vmalert 已加载规则、VictoriaMetrics 即时查询、CNPG 监控/备份声明、证书资源和本机服务清单。
|
||||
同时查阅服务 wiki、源码配置和运维文档。没有读取 Secret、修改集群或部署 exporter。
|
||||
共享 etcd 正由维护者调整;其瞬时采集异常不作为本轮待修故障。
|
||||
|
||||
没有逐台登录 PVE、OCI、域控和其他 VM,也没有验证所有应用业务接口、备份文件或恢复能力。
|
||||
“未接入”指未进入这套中央 VictoriaMetrics/Alertmanager,不排除服务另有本地日志、
|
||||
健康检查或独立监控;例如 LiteLLM 源码中有独立 Prometheus Compose 配置,本次未验证运行状态。
|
||||
|
||||
源码基线为 [homelab-infra a43b7d3](https://git.ddupan.top/panxiao81/homelab-infra/src/commit/a43b7d3c26f9724b9d5b2ad45058f2d1632741af/platform/observability),
|
||||
共享 etcd 采集/规则另以本次现场 CR 为准(来源工作区尚有未提交配置)。
|
||||
审阅时主工作区落后于远端且有其他改动,不能拿本地旧 :8080 配置覆盖已合并修复。
|
||||
|
||||
## 初轮盘点规模(实施前)
|
||||
|
||||
- 69 个 Deployment/StatefulSet/DaemonSet 对象(44/13/12),不等同于服务数或全部实例数;CNPG 管理的数据库 Pod 不在此统计内。
|
||||
- vmagent 有 17 个目标、15 个 job;其中 node-exporter 与 docker-hosts 重复采集同一个 :9100 地址,实际唯一 URL 为 16 个。
|
||||
- 采集对象:3 VMNodeScrape、1 VMPodScrape、8 VMServiceScrape、3 VMStaticScrape。
|
||||
- 有 1 个 NATS PodMonitor,但没有其转换后的 VMPodScrape 或实际 target;没有 ServiceMonitor、PrometheusRule、VMProbe。
|
||||
- 5 个 VMRule,vmalert 实际加载 47 条告警:vm-health 12、vmagent 14、vmalert 8、vmsingle 7、shared-etcd 6。
|
||||
- 严重性为 critical 16、warning 30、info 1;本次规则 API 未报告执行错误。41 条属于监控栈,6 条属于共享 etcd。
|
||||
- Telegram 已接 warning/critical 和恢复通知;info 不推送。通知接入验收见服务页。
|
||||
|
||||
## 初轮覆盖矩阵(实施前)
|
||||
|
||||
“无专用告警”指没有该服务的业务/运行告警;共享进程或错误日志规则可能部分命中,不能视为完整覆盖。
|
||||
|
||||
| 对象 | 当前指标采集 | 当前告警覆盖 | 主要缺口 |
|
||||
|---|---|---|---|
|
||||
| VictoriaMetrics / vmagent / vmalert | 已采集 | 有基础规则 | 部分规则所依赖功能未启用;核对空结果与指标兼容性 |
|
||||
| Alertmanager | 已采集 | 部分通用进程存活规则 | 缺 Telegram 发送失败、配置加载失败及集群外心跳 |
|
||||
| VictoriaLogs / VictoriaTraces / OTel / VM Operator | 已采集 | 可能命中通用错误/进程规则 | 缺明确的存活、队列丢弃、容量与数据新鲜度覆盖;现有 ServiceDown 的 job 正则不完整覆盖这些名称 |
|
||||
| Grafana | 未见专用目标 | 无专用告警 | 页面/登录可用性、数据源失败 |
|
||||
| laptop node-exporter / process-exporter | 已采集;:9100 重复 | 无主机专用规则 | 内存、swap、磁盘空间/inode、ZFS 健康、IO、主机不可达、进程异常 |
|
||||
| kubelet / Kubernetes cAdvisor | 已采集 | 无 Kubernetes 对象状态规则 | 只有资源指标,不能替代 Pod/Deployment/PVC 状态采集 |
|
||||
| kube-state-metrics | 未部署,只有安装脚本 | 无 | NodeNotReady、CrashLoop/OOM、重启、不可用副本、PVC Pending、Job 失败 |
|
||||
| Blocky | 已采集 | 无 DNS 专用规则 | DNS 实际解析探测、上游失败、响应延迟 |
|
||||
| 共享 etcd | 三个成员已配置采集 | 6 条专用规则 | 维护中;后续补备份新鲜度、证书到期和目标缺失语义 |
|
||||
| NATS | exporter 与 PodMonitor 已存在,未进入实际 targets | 无专用规则 | 先修通采集,再补 JetStream 存储、consumer pending/redelivery、连接与集群健康 |
|
||||
| CNPG PostgreSQL | 现有 Cluster 的 enablePodMonitor=false,无专用 target | 无专用规则 | 连接数、复制/主从、事务、磁盘、备份/WAL 新鲜度;当前单实例 |
|
||||
| OpenBao | 未接入中央采集 | 无专用规则 | sealed/可用性、请求错误、Raft、PKI 到期、快照成功及异机副本 |
|
||||
| SPIRE / Authelia / Hydra | 未接入中央采集 | 无专用规则 | 身份签发/登录失败、证书续期、连接依赖、控制器就绪 |
|
||||
| External Secrets | 未接入中央采集 | 无专用规则 | Secret 同步失败/过期、provider 访问失败 |
|
||||
| cert-manager | 指标 Service 已有,未采集 | 无证书规则 | 证书临期、续签失败、Issuer 状态;本次 4 个 Certificate 均 Ready 不等于已有告警 |
|
||||
| Envoy Gateway / Cloudflared | 未接入中央采集 | 无专用规则 | 入口 5xx/延迟、路由、上游、隧道可用性 |
|
||||
| CoreDNS | 已暴露 :9153 指标,未采集 | 无专用规则 | DNS 请求失败/延迟、实际解析探测 |
|
||||
| Flux | 未接入中央采集 | 无专用规则 | Kustomization/HelmRelease/GitRepository 同步失败、长时间未更新 |
|
||||
| SeaweedFS | master/filer/volume 已有 :9327 指标 Service,未采集 | 无专用规则 | 容量、卷/副本健康、S3 可用性、持久化与备份 |
|
||||
| OpenEBS / ZFS LocalPV | 控制器未专门采集;宿主 ZFS 指标已有 | 无存储专用规则 | PVC/卷挂载、池降级、容量、故障盘;SMART/IPMI 未接入 |
|
||||
| Gitea / zot / Nexus / NetBox / Backstage | 未见应用专用目标 | 无专用规则 | HTTP 可用性、错误率、依赖;按实际使用优先级接入 |
|
||||
| Dynamic Runner | 未接入中央采集 | 无专用规则 | 队列积压、调度失败、孤儿实例、执行基础设施不可用;与 NATS 联动 |
|
||||
| SMTP relay / Tailscale | 未接入中央采集 | 无专用规则 | 邮件队列/投递失败、节点/路由可达性 |
|
||||
| PVE / OCI / Samba AD / 其他 VM | 中央 targets 未覆盖 | 无专用规则 | 主机存活与资源、复制/时间同步、关键服务、站点网络、备份 |
|
||||
| laptop Docker / Incus / libvirt / FRR / NFS/SMB 等 | 主机/进程资源只有部分可见性,无组件专用目标 | 无专用规则 | 虚机/容器生命周期、宿主服务失败、路由邻居/存储服务可用性;独立 Docker cAdvisor 未部署 |
|
||||
| Marker / OpenViking / LiteLLM 等源码服务 | 未见中央 target;运行范围需由各项目确认 | 无中央专用规则 | 先明确现役范围,再接业务指标;不为归档或未部署服务添加空目标 |
|
||||
| e5renew / research-auto | 有集群 workload,但未见专用目标 | 无中央专用规则 | 属外部消费者,业务规则由项目维护;平台提供通用 workload 健康覆盖 |
|
||||
|
||||
## 初轮发现的盲点(实施前)
|
||||
|
||||
### Kubernetes 对象状态
|
||||
|
||||
没有 kube-state-metrics workload,也没有其 targets。即时查询
|
||||
`kube_deployment_status_replicas_available`、`kube_pod_container_status_restarts_total`、
|
||||
`kube_node_status_condition`、`kube_persistentvolumeclaim_status_phase` 均无当前样本。
|
||||
数据库历史指标名列表仍能找到 kube_*,因此不能仅凭 Grafana 自动补全认定已经接入。
|
||||
|
||||
盘点瞬间 Backstage 为 CrashLoopBackOff,SPIRE StatefulSet 的 sandbox controller 不就绪,
|
||||
SPIRE server 主容器仍 Ready。它们可能由其他任务调整;本轮未诊断或操作,
|
||||
只用于说明现有 47 条规则无法承担通用 workload 状态告警。以后需要人工对齐维护窗口。
|
||||
|
||||
### NATS 声明与运行不一致
|
||||
|
||||
NATS StatefulSet 有 :7777 prom-exporter,PodMonitor/nats 已存在,但实际没有 NATS target,
|
||||
即时 nats_* 查询为空。VM Operator Pod 从 2026-07-10 运行,而 PodMonitor CRD 创建于
|
||||
2026-09-16;启动时 CRD 发现/转换控制器启动是排查线索,尚不能据此认定根因。
|
||||
应检查转换器启用状态、watch/RBAC 和启动日志,修复后验证生成对象、target 和实际样本三层。
|
||||
|
||||
### 备份不是“有 PVC 就够了”
|
||||
|
||||
现有 CNPG Cluster 没有 spec.backup,也没有 ScheduledBackup,status.lastSuccessfulBackup 为空。
|
||||
这只证明 CNPG 管理的备份链路未声明,不排除未盘点的宿主脚本;需要另外明确备份方式。
|
||||
OpenBao 源码已有本地 snapshot timer,但成功时间、异机传输和恢复验收没有中央指标/告警。
|
||||
Samba AD 文档有备份操作示例,SeaweedFS/zot 文档也明确独立异机备份缺口;不能直接标记为已保护。
|
||||
|
||||
备份监控至少记录最近成功时间、结果、目标可达性和保留副本;恢复演练成功时间单独记录,
|
||||
不能由“备份任务退出码 0”推断可恢复。定义实际备份流程后再定告警阈值。
|
||||
|
||||
### 监控自身和规则语义
|
||||
|
||||
- vmalert 的 AlertmanagerErrors 只覆盖 vmalert → Alertmanager,不覆盖 Alertmanager → Telegram;后者的失败计数已经有指标但没有对应规则。
|
||||
- 当前 ServiceDown 只匹配部分 VictoriaMetrics job,缺通用 target down 与 expected-target absent 检查。
|
||||
`up == 0` 无法发现目标被移出发现集合;必须先定义关键目标清单,再做缺失检测。
|
||||
- 没有 blackbox/VMProbe、probe_* 当前指标或 HTTP/DNS/TCP/TLS 外部探测。
|
||||
集群内指标正常不证明用户端入口、DNS、证书链与身份登录可用。
|
||||
- 没有 Watchdog/集群外心跳接收。Alertmanager 或整个站点断电/断网时,内部告警不能保证通知到达。
|
||||
- RecordingRulesError/RecordingRulesNoData、SeriesLimitHour/DayReached、StreamAggr* 等规则查不到依赖 series;
|
||||
当前没有 recording rules,部分可选功能可能未启用,不能把所有空结果判为坏规则。
|
||||
`vmagent_relabel_config_last_reload_successful` 当前也无样本,需逐条做功能/版本匹配。
|
||||
- 主机 :9100 被 node-exporter 和 docker-hosts 两个 job 重复采集。后续统一所有权,清理前核对查询依赖,避免 sum 重复统计。
|
||||
- 缺面向节点/服务依赖的抑制、维护静默流程和预期维护范围。优先减少无行动价值的重复通知,不直接导入全套规则。
|
||||
|
||||
## 建议实施顺序与验收
|
||||
|
||||
| 批次 | 实施内容 | 验收条件 |
|
||||
|---|---|---|
|
||||
| 1:补平台基本覆盖 | GitOps 部署 kube-state-metrics;Node/Pod/Deployment/PVC/Job 规则;复用 node-exporter 补主机/ZFS;修 NATS 转换;补 Telegram 发送失败规则 | 新目标 up 且有当前样本;规则有依赖数据;测试触发/恢复消息送达;维护对象能明确静默 |
|
||||
| 2:保护关键依赖和数据 | CNPG、OpenBao、SeaweedFS、NATS 业务规则;cert-manager、ESO、Flux;备份方案与最后成功时间指标 | 每项有采集、针对性规则、runbook、凭据最小权限和故障演练结果;备份独立验收 |
|
||||
| 3:验证用户可用性 | LAN DNS、入口 HTTPS、Gitea/认证/S3/镜像等关键路径探测;集群外 Watchdog 接收 | 从独立位置发现站点/监控中断,探测不用暴露管理员凭据或制造业务写入 |
|
||||
| 4:扩展到其余基础设施和应用 | PVE/OCI/域控主机、Docker/Incus/libvirt/网络;按使用频率接入应用 | 按服务维护覆盖表,退役目标同步移除,采集开销和标签基数受控 |
|
||||
|
||||
第一批基础补齐已实施,验收边界见上方链接;下一步对齐第二批关键依赖与备份方案。开始具体实施前对齐各服务进行中的工作,
|
||||
尤其是共享 etcd、数据库迁移与身份平台;本次盘点不授权自动修改这些项目。
|
||||
@@ -0,0 +1,99 @@
|
||||
---
|
||||
title: 基础监控与告警运维
|
||||
last_reviewed: 2026-09-25
|
||||
---
|
||||
|
||||
# 基础监控与告警运维
|
||||
|
||||
第一批补齐 Kubernetes 状态、主机/ZFS 和通知链路;业务数据库、备份、外部探测等
|
||||
后续范围见 [覆盖计划](monitoring-coverage.md)。本页的规则检查不等于所有服务健康。
|
||||
|
||||
## 声明与归属
|
||||
|
||||
维护者于 2026-09-25 明确:新增监控配置优先使用 Prometheus Operator 的
|
||||
`ServiceMonitor`、`PodMonitor`、`PrometheusRule`。VictoriaMetrics Operator 负责转换为
|
||||
VMServiceScrape、VMPodScrape、VMRule,vmagent/vmalert 继续负责采集与规则执行。
|
||||
不要再为同一个新目标/规则手工维护一份 VM 对象;已有历史 VM 配置按需求单独迁移。
|
||||
|
||||
- kube-state-metrics:Flux HelmRelease,chart `8.5.0` / app `2.20.0`,适配本集群 Kubernetes 1.36。
|
||||
- KSM 的 ServiceMonitor 使用 `honorLabels: true`,保留被观测对象的 namespace/pod 等标签。
|
||||
:8080 提供对象指标,:8081 提供 exporter 自身指标;job 均为 `kube-state-metrics`。
|
||||
- collector/RBAC 限于本批需要的 nodes、pods、deployments、statefulsets、daemonsets、
|
||||
PVC/PV、jobs/cronjobs、namespaces,只读 list/watch,没有启用 secrets collector。
|
||||
- NATS 沿用其 Helm 管理的 PodMonitor,转换后的 `nats/nats` VMPodScrape 抓取 :7777,job 为 `nats/nats`。
|
||||
- Operator HelmRelease 依赖 `prometheus-operator-crds`;KSM 同时依赖两者。
|
||||
先确保 CRD Ready,再启动依赖 CRD 的转换器和消费者。
|
||||
- 源码:[基础补齐 PR #149](https://git.ddupan.top/panxiao81/homelab-infra/pulls/149)。
|
||||
三份新增规则位于 `platform/observability/metrics/rules/{kubernetes-health,host-health,monitoring-delivery}.yaml`。
|
||||
PrometheusRule 声明切换见 [PR #151](https://git.ddupan.top/panxiao81/homelab-infra/pulls/151),
|
||||
Flux 已应用 `e8e7bd4b203def4123658a4d02a1d92a854005fc`。
|
||||
|
||||
## 21 条规则的范围
|
||||
|
||||
| 组 | 规则与持续时间 | 严重性 |
|
||||
|---|---|---|
|
||||
| Kubernetes(11) | NodeNotReady 5m;Memory/Disk/PID Pressure 5m | 节点未就绪 critical,压力 warning |
|
||||
| Kubernetes(续) | CrashLoop 10m;15 分钟内重启 >3 次持续 5m;近期 OOM 重启 1m;Pod Pending 15m | warning |
|
||||
| Kubernetes(续) | Deployment/StatefulSet/DaemonSet 可用副本不足 10m;PVC Pending 15m;Job Failed condition 5m | warning |
|
||||
| 主机(5) | 可用内存 <10% 持续 10m;磁盘可用空间/inode <10% 持续 15m | warning |
|
||||
| 主机(续) | 文件系统只读 5m;ZFS 池非 online 的状态值为 1 持续 5m | critical |
|
||||
| 采集(3) | KSM、node-exporter、NATS target down 或整个 job 消失持续 5m | 前两项 critical,NATS warning |
|
||||
| 通知(2) | Telegram 失败计数最近 5 分钟增加并持续 1m;Alertmanager 配置加载失败 5m | critical |
|
||||
|
||||
主机规则只用 `job="node-exporter"`,避免旧 docker-hosts 重复样本。
|
||||
磁盘规则排除 tmpfs/devtmpfs/overlay/squashfs/nsfs/fuse 和临时挂载路径;inode 总数为零不报警。
|
||||
OOM 同时要求近期 restart counter 增加,避免历史终止原因持续报警。
|
||||
Deployment 以声明副本为准,缩容到零不触发。
|
||||
|
||||
本批没有增加主机 CPU/Swap/IO 告警、NATS JetStream 业务规则、数据库/备份或外部探测。
|
||||
job 完全消失使用 absent(up) 检查,但未建立每个预期主机/成员的独立清单,不能保证发现
|
||||
同一个 job 中少了一个成员;此类预期拓扑检测后续再补。
|
||||
|
||||
## 通知、静默与抑制
|
||||
|
||||
warning/critical 及恢复消息沿用 [Telegram 路由](../services/grafana.md#telegram-告警接入)。
|
||||
新规则 annotations 中包含本 runbook 链接。
|
||||
告警 Source 的指标查询入口与 Grafana 中的 Alertmanager 静默管理入口见
|
||||
[从告警进入 Grafana](../services/grafana.md#从告警进入-grafana)。
|
||||
同一 namespace/pod/container 的 `KubePodCrashLooping` 只抑制 `KubePodFrequentRestarts`,
|
||||
不抑制 OOM,也不静默整个 namespace。工作负载副本不足仍独立可见。
|
||||
|
||||
维护时在 Alertmanager 为明确标签创建有截止时间和原因的 silence;不要把维护中的
|
||||
etcd、SPIRE 或 Backstage 直接写成永久排除规则。结束维护后核对 silence 到期和目标健康。
|
||||
|
||||
Telegram 完全不可达时,发送失败告警也无法依靠同一渠道送达。该规则有助于留存和
|
||||
恢复后通知,不能替代集群外心跳或第二渠道。发送失败时直接检查 Alertmanager/Grafana。
|
||||
|
||||
## 接入或升级后如何验收
|
||||
|
||||
1. 确认 Flux HelmRelease Ready,原生 ServiceMonitor/PodMonitor/PrometheusRule 存在。
|
||||
2. 确认转换出的 VM 对象存在、内容同步;不要仅凭原生 CR 已创建判定成功。
|
||||
3. 在 vmagent `/api/v1/targets` 确认 up、最近采集时间和样本数;VictoriaMetrics 即时查询
|
||||
验证 `up{job="kube-state-metrics"}`、`up{job="nats/nats"}` 和所需指标当前有值。
|
||||
4. 在 vmalert `/api/v1/rules` 核对规则数量、lastError 和依赖样本。
|
||||
没有失败 Job 或 OOM 时条件指标可能不存在,不能把这种空结果直接当作采集失败。
|
||||
5. 变更规则时从源码运行 `bash platform/observability/metrics/tests/check-rules.sh`;
|
||||
依赖 Python 3、PyYAML、promtool(本次验证版本 3.5.0)。该脚本直接读取三份规则的 spec.groups,
|
||||
生成临时文件校验,不维护第二份规则。8 组测试覆盖阈值持续时间、缺失目标和常见噪声边界。
|
||||
6. 经维护者授权发送临时 canary,验证触发与恢复后删除测试规则,恢复正式规则总数。
|
||||
不通过制造真实 OOM、磁盘满或破坏 Telegram token 来做验收。
|
||||
|
||||
## NATS 转换故障经验
|
||||
|
||||
NATS 已有 exporter 和 PodMonitor,但 Operator 自 7 月启动,PodMonitor CRD 到 9 月才安装。
|
||||
本次滚动重启 Operator 后,日志记录启动 PodMonitor controller 并创建 `VMPodScrape=nats/nats`,
|
||||
之后 target up 且 nats_* 指标入库。NATS 本身没有重启。
|
||||
|
||||
遇到同类问题先检查原生 CR、转换对象、转换器日志、watch/RBAC 和 CRD 安装时间;
|
||||
不能直接另建同目标 VM scrape 来掩盖转换链路问题。必要重启只针对 Operator,
|
||||
先确认当前无升级/恢复操作,重启后验证对象生成和采集。
|
||||
|
||||
## 本次验证边界
|
||||
|
||||
2026-09-25,KSM 两个端点及 NATS 均 up,KSM 约 5,300 条对象样本和 75 条自身样本,
|
||||
可读到 27 个 workload namespace 的容器重启指标。NATS 有约 187 条采集样本。
|
||||
正式规则从 47 增为 68,当前规则评估无错误;8 组离线测试、Helm/Kustomize 渲染和服务端 dry-run 通过。
|
||||
canary 触发已由维护者确认收到;规则恢复后 Telegram 发送计数从 11 增至 12,
|
||||
失败计数仍为 0,Alertmanager 无残留 canary,测试 VMRule 已删除。恢复消息未单独取得收件端确认。
|
||||
三份 PrometheusRule 的转换内容一致(仅 VMRule 补默认空 record 字段),vmalert 最终仅有 68 条正式规则,未重复评估。
|
||||
这些数量是验收快照,不是容量承诺或持续健康结论。正在调整的 etcd 不在本批修复范围。
|
||||
@@ -1,6 +1,6 @@
|
||||
---
|
||||
title: 按任务查找文档
|
||||
last_reviewed: 2026-09-20
|
||||
last_reviewed: 2026-09-25
|
||||
---
|
||||
|
||||
# 按任务查找文档
|
||||
@@ -10,13 +10,16 @@ last_reviewed: 2026-09-20
|
||||
|
||||
| 要做什么 | 先读 | 需要时再读 |
|
||||
|---|---|---|
|
||||
| 评估独立 IAM 与 AI agent 身份 | [独立 IAM 草案](../architecture/independent-iam-draft.md) | [Hydra 人类登录 PoC](../services/hydra.md);完整 IAM 仍为草案 |
|
||||
| 设计或实现 Ayatori 控制面能力 | [Ayatori 控制面边界](../architecture/ayatori-control-plane.md) | Ayatori 仓库 ADR、对应领域 API 与 adapter 文档 |
|
||||
| 发布新的 LAN Web 服务 | [发布新服务](publish-service.md) | [DNS](../services/lan-dns.md)、[Authelia](../services/authelia.md) |
|
||||
| 写 CI 或选择 Pod/VM runner | [Gitea / Actions](../services/gitea.md) | [Dynamic Runner](../services/gitea-dynamic-runner.md)、[SPIFFE](../services/spire.md) |
|
||||
| 写 CI 或选择 Pod/VM runner | [Gitea / Actions](../services/gitea.md) | [Dynamic Runner](../services/gitea-dynamic-runner.md)、[SPIFFE](../services/spire.md)、[`ci-actions@v1`](https://git.ddupan.top/panxiao81/ci-actions/src/tag/v1) |
|
||||
| 为 CI 缓存 Ansible/Go 依赖 | [Nexus POC](../services/nexus.md) | [Dynamic Runner](../services/gitea-dynamic-runner.md)、[OpenBao](../services/openbao.md) |
|
||||
| 拉取或发布容器镜像 | [zot](../services/zot.md) | [SPIFFE](../services/spire.md);S3 后端维护才读 SeaweedFS |
|
||||
| 使用 S3 对象存储 | [SeaweedFS](../services/seaweedfs.md) | [OpenBao](../services/openbao.md) |
|
||||
| 给应用分配数据库 | [共享 PostgreSQL](../services/shared-postgresql.md) | [计划中的 DBaaS](../services/postgresql-tenant-operator.md) |
|
||||
| 给应用提供秘密或存储 | [External Secrets](../services/external-secrets.md)、[OpenEBS](../services/openebs.md) | [OpenBao](../services/openbao.md) |
|
||||
| 盘点或补齐监控与告警 | [监控覆盖与补齐计划](monitoring-coverage.md) | [基础监控运维](monitoring-foundation.md)、[Grafana](../services/grafana.md) |
|
||||
| 排查内存、日志或追踪 | [Grafana](../services/grafana.md) | 对应服务源码 runbook |
|
||||
| 排查域名解析 | [LAN DNS](../services/lan-dns.md)或[Pod DNS](../services/k3s-dns.md) | [Tailscale](../services/tailscale.md),如果请求来自远程客户端 |
|
||||
| 排查登录或域权限 | [Authelia](../services/authelia.md)、[Samba AD](../services/samba-ad.md) | 具体应用的权限说明 |
|
||||
|
||||
@@ -0,0 +1,228 @@
|
||||
---
|
||||
title: 2026-09-25 DRBD quorum 抖动与 sandbox 控制面中断
|
||||
last_reviewed: 2026-09-25
|
||||
---
|
||||
|
||||
# 2026-09-25 DRBD quorum 抖动与 sandbox 控制面中断
|
||||
|
||||
状态:服务已恢复;事故机制已确认,资源争用的具体瓶颈与预防性整改仍待验证。
|
||||
时间统一使用 UTC。报告依据当日 PVE/VyOS/guest 现场日志、相关操作会话和未提交 IaC;
|
||||
不是全量数据完整性审计,也不把短期恢复等同于根因消除。
|
||||
|
||||
## 结论
|
||||
|
||||
共享 PostgreSQL 的承载准备在 17:12 为 CT150、CT151 新建 16 GiB、32 GiB HDD DRBD
|
||||
数据卷,两卷初始同步重叠。随后多个既有 DRBD 资源出现 PingAck 超时和 quorum 丢失。
|
||||
sandbox1 根卷在 17:15:49 因 I/O 错误中止 ext4 journal、进入只读,PostgreSQL 主库和
|
||||
本机 K3s 退出;sandbox2 K3s 也失去数据库连接。VyOS HAProxy 摘除了不可连接的后端,
|
||||
从客户端看起来像 LB 故障。etcd CT150 的 SSD 根卷在 17:16:52 也发生同类故障。
|
||||
|
||||
**已确认的直接故障机制**是 DRBD 失去 quorum 后按 `on-no-quorum=io-error` 返回错误,
|
||||
引发 ext4 只读和上层服务中断。**最有证据支持的触发因素**是新 HDD 卷并发初始同步期间的
|
||||
共享资源压力;尚无故障时段的链路队列、丢包、磁盘延迟和 CPU 调度证据,不能定论为
|
||||
某条链路打满、某块磁盘损坏或唯一由 resync 流量造成。
|
||||
|
||||
这次更接近故障的操作是“创建数据卷并触发复制”,不是 15:30–15:32 已完成的 etcd
|
||||
rootfs 迁移。新 shared PostgreSQL 当时尚未启动,未迁移现有 CNPG 或 sandbox 数据库;
|
||||
影响经共享底层存储扩散到原有服务。
|
||||
|
||||
## 影响与恢复边界
|
||||
|
||||
| 对象 | 已观察到的影响 | 恢复证据 |
|
||||
| --- | --- | --- |
|
||||
| sandbox PostgreSQL,`10.60.0.1:5432` | 主库 `10.60.0.11` 停止监听,LB 无可用 backend | 原主库 crash recovery 完成;sandbox2 streaming/sync,采样 replay lag=0 |
|
||||
| sandbox K3s,`10.60.0.13:6443` | 两个 API 后端拒绝连接,控制面不可用 | 两个直连 API 与 VIP `/readyz=ok`;两节点和全部 Pod Ready |
|
||||
| OpenSandbox,`10.60.0.13:8080` | 健康入口仍可返回 200;依赖 K3s 的生命周期操作受控制面中断影响 | `/health` healthy;本轮未实际创建/销毁 sandbox,不能用 health 替代业务验收 |
|
||||
| shared etcd CT150 | SSD rootfs `emergency_ro`,成员无法正常服务,触发无 leader/频繁选举告警 | 另一会话完成离线修复,记录三成员 endpoint healthy、Raft term/index 一致 |
|
||||
| 其他 DRBD 资源 | pve1 在限定窗口记录 11 个资源共 43 次 quorum 丢失 | 尚未逐项完成 guest/应用层影响审计,不能说其他服务均未受影响 |
|
||||
|
||||
API 全后端不可用从 HAProxy 17:16:01 告警可确认;约 17:49 已有可用 API,
|
||||
约 17:51 完成双后端、节点与 Pod 验收。控制面中断约 33 分钟,完整恢复约 35 分钟。
|
||||
恢复后的复制和服务检查未发现新的异常,但不能据此证明中断期间全部业务请求成功或零数据丢失。
|
||||
数据库日志曾记录同步等待取消及“本地已提交、可能尚未复制”,未逐事务审计;未执行 WAL reset、
|
||||
standby 提升、数据库重建或恢复旧备份。
|
||||
|
||||
## 变更范围与存储映射
|
||||
|
||||
| 用途 | PVE/容器 | DRBD resource | 设备 | 存储池/大小 |
|
||||
| --- | --- | --- | --- | --- |
|
||||
| 既有 sandbox1 根盘,包含 K3s datastore 主库 | pve1 / CT148 | `pm-6d8bee62` | `drbd1007` | `pve-rg-hdd` / 32 GiB |
|
||||
| etcd-pve1 根盘 | pve1 / CT150 | `pm-d1d1f3ea` | `drbd1008` | `pve-rg` SSD / 8 GiB |
|
||||
| 新 PG standby 数据盘 | pve1 / CT150 mp0 | `pm-af21c43d` | `drbd1011` | `pve-rg-hdd` / 16 GiB |
|
||||
| 新 pgBackRest 仓库盘 | pve2 / CT151 mp0 | `pm-de86804d` | `drbd1012` | `pve-rg-hdd` / 32 GiB |
|
||||
|
||||
17:12:20,pve1 作为 SyncSource 向 pve3 同步 CT150 新盘;17:12:56,pve1 又作为
|
||||
SyncTarget 从 pve2 接收 CT151 新盘。容器操作串行不代表底层复制串行,也不代表不同
|
||||
SSD/HDD 池具有独立的网络、宿主调度或 I/O 故障域。
|
||||
|
||||
## 时间线
|
||||
|
||||
| UTC | 事件与证据 |
|
||||
| --- | --- |
|
||||
| 15:30:16–15:31:09 | CT150 `move_volume` 完成,PVE 任务 OK;`local-lvm` → `pve-rg` |
|
||||
| 15:31:32–15:32:11 | CT151 同类迁移完成;会话随后确认三 etcd 端点健康 |
|
||||
| 17:09:14 | PG 会话说明即将创建独立 HDD mp0、增加内存预算,不启动 PG |
|
||||
| 17:11:46 | 执行 `ansible-playbook pve-storage.yml` |
|
||||
| 17:12:20 / 17:12:56 | 两个新 HDD 资源分别开始 DRBD 初始同步,发生重叠 |
|
||||
| 17:14:00 | 本报告 17:10–17:55 pve1 内核窗口内首条 `quorum( yes -> no )`;对象为既有 `pm-59a94edd` |
|
||||
| 17:14:09 | PG 会话报告承载准备完成、etcd 健康;未包含 DRBD 同步完成和跨服务检查 |
|
||||
| 17:15:47–17:15:48 | sandbox1 根卷先后丢失 pve3、pve2 连接,quorum yes→no |
|
||||
| 17:15:49 | `drbd1007` 写入错误、MMP 写失败、journal abort、只读;PG 启动控制命令报 I/O error,K3s SIGBUS |
|
||||
| 17:15:54 | HAProxy 报 sandbox1 API 和 PostgreSQL 后端 DOWN |
|
||||
| 17:16:01 | sandbox2 API 后端也 DOWN,K3s backend 无可用服务器 |
|
||||
| 17:16:52 | CT150 `drbd1008` 失去 quorum,ext4 进入只读 |
|
||||
| 17:18:53 | PG 会话发现 CT150 只读,暂停后续部署;另两个 etcd 成员健康 |
|
||||
| 17:20:27 | 维护者在 PG 会话提供 `SharedEtcdNoLeader` 实际通知 |
|
||||
| 17:20–17:25 | 准备限速;先遇到 playbook 路径错误,随后遇到 YAML 条件表达式类型错误,修正后重跑 |
|
||||
| 17:23:39 | 该内核窗口内最后一条 quorum 丢失;之后仍有 PingAck 超时,不能写成“限速后才停止 quorum 丢失” |
|
||||
| 17:24:37 | Alertmanager 会话获知 etcd 正在另一路调整,结束该会话对 etcd 的排查 |
|
||||
| 17:25:58 | 会话收到限速成功结果,两主机各 changed=1;新卷 `c-max-rate=10240` |
|
||||
| 17:25:59–17:28:11 | CT150 停机、离线修复、重新启动;约 17:30 报告三成员健康 |
|
||||
| 17:31:21 / 17:33:38 | CT151 / CT150 新数据卷分别完成 DRBD 同步,内核标记 resync-finished |
|
||||
| 17:42 起 | 维护者报告 sandbox LB 异常,本会话开始排查 |
|
||||
| 17:43–17:46 | 确认 HAProxy 正常、后端故障;定位 sandbox1 根盘 emergency_ro 和原始 quorum/I/O 日志 |
|
||||
| 17:46:41–17:46:49 | CT148 正常关机完成 |
|
||||
| 17:47–17:48 | `pct fsck 148 --device rootfs --force 1` 恢复 journal、清理 orphan inode;只读 `e2fsck -fn` 五阶段通过、返回 0 |
|
||||
| 17:48:40–17:48:44 | CT148 启动;根盘恢复 rw 且无 emergency_ro |
|
||||
| 17:49:04 / 17:49:08 | 原 PG 主库恢复接收连接;sandbox2 恢复同步 standby |
|
||||
| 17:50:40 左右 | sandbox2 K3s 在重启服务后恢复 API;此前旧进程卡在故障期间的启动/关闭状态 |
|
||||
| 约 17:51 | 两个 API 和 VIP readyz 通过、两节点及全部 Pod Ready、复制 lag=0 |
|
||||
| 17:53:49 | 两个新卷现场复核均 Established/UpToDate,限速属性和运行配置仍为 10240 |
|
||||
|
||||
宿主默认 journal 展示曾为 UTC+9,guest/VyOS 使用 UTC。初次用 UTC 字面时间过滤宿主
|
||||
本地日志没有找到错误;后来用 `journalctl --utc` 和明确 UTC 时间窗口纠正。上表不使用
|
||||
未经转换的 `Sep 26 02:xx` 作为独立事故时间。
|
||||
|
||||
## 故障机制与变更保护缺口
|
||||
|
||||
```mermaid
|
||||
flowchart TD
|
||||
A[新增两个 HDD 数据卷] --> B[初始同步重叠]
|
||||
B -. 资源压力为待证实触发因素 .-> C[多个 DRBD 对端 PingAck 超时]
|
||||
C --> D[既有卷失去 majority quorum]
|
||||
D --> E[on-no-quorum=io-error]
|
||||
E --> F[ext4 journal abort / emergency_ro]
|
||||
F --> G[sandbox PostgreSQL 与本机 K3s 退出]
|
||||
G --> H[另一 K3s 失去 datastore / API 中断]
|
||||
H --> I[HAProxy 后端均 DOWN]
|
||||
F --> J[shared etcd 单成员异常]
|
||||
```
|
||||
|
||||
1. **变更验收停在容器/etcd 层。** `serial: 1` 和 endpoint health 只限制 Ansible 的
|
||||
容器操作顺序;未等待前一 DRBD 新卷完全同步,所以后台复制仍重叠。
|
||||
2. **未把新卷创建视为共享基础设施变更。** 新数据库尚未运行、卷内没有业务数据,
|
||||
仍会发生全卷复制并影响现有资源。仅检查新服务健康不能限制影响范围。
|
||||
3. **恢复检查范围过窄。** 首轮识别并恢复 CT150 后,未沿同批 quorum/I/O 日志
|
||||
核查 CT148 等既有消费者;sandbox 控制面继续故障,直至维护者再次报告。
|
||||
4. **监控缺少依赖链覆盖。** Alertmanager 通知当天已打通,etcd 实际告警送达;
|
||||
不能归因于“没有通知”。另一会话的盘点发现告警主要覆盖监控自身及 shared etcd,
|
||||
尚缺可证明有效的跨资源 DRBD、文件系统异常、sandbox API 外部可用性覆盖。
|
||||
`/health=200` 与单节点 Ready 也不足以证明两个 API 后端健康。
|
||||
5. **紧急缓解执行有延迟。** 限速 playbook 首次工作目录错误、随后条件被 YAML
|
||||
解析成非字符串,两次均在配置变更前失败;直到 17:25:58 才有成功回执。
|
||||
|
||||
限速后短期稳定且最终同步完成支持资源压力假设,但缺少控制变量;本次最后一次 quorum
|
||||
丢失早于成功限速,不能把时间相关性写成严格因果证明。现有 `pve-storage.yml` 已补入
|
||||
限速任务,但位于 `pct set --mp0` **之后**;初始同步在创建卷时已经开始,仍存在未限速
|
||||
窗口,并且仍缺 DRBD 同步完成屏障。此报告没有擅自更改这些并行工作中的实现。
|
||||
|
||||
## 已完成处置与验收
|
||||
|
||||
- PG/etcd 会话:仅为两个新卷设置资源级 `DrbdOptions/PeerDevice/c-max-rate=10240`
|
||||
(配置的自适应同步上限 10 MiB/s),记录幂等复跑无变更;CT150 离线修复后恢复三端点健康。
|
||||
- 本会话:确认 CT148 stopped、卷身份/未挂载、副本 UpToDate/quorum 后,使用 PVE 安全自动
|
||||
fsck;返回 1 表示已修复,随后独立只读完整检查返回 0,再启动原容器。
|
||||
- PostgreSQL 自行回放 WAL 并恢复原角色;未切主。sandbox2 K3s 在数据库恢复后仍卡住,
|
||||
仅重启该 K3s 服务,未重启或提升它的 PostgreSQL。
|
||||
- 两个直连 API 与 VyOS VIP `/readyz` 均为 ok;全部 Pod Ready;所有相关 HAProxy
|
||||
后端 UP/L4OK;OpenSandbox `/health` healthy;目标根卷恢复正常 rw。
|
||||
- 未修改 VyOS LB、全局 DRBD 协议/quorum/超时或集群网络。VyOS 最新提交及生成配置仍为
|
||||
9 月 18 日,最近两次 LB 变更仅新增 OpenSandbox 入口并调整其超时。
|
||||
|
||||
## 后续整改与关闭标准
|
||||
|
||||
下列项目是待办,不代表已获执行或发布授权;责任人/issue 由维护者分配。
|
||||
|
||||
| 优先级 | 项目 | 验收条件 |
|
||||
| --- | --- | --- |
|
||||
| P0 | 审计同批受影响 DRBD 资源对应 guest/应用 | 11 个资源逐一映射并记录文件系统、服务和数据层状态,不能只看 DRBD UpToDate |
|
||||
| P0 | 新卷创建前实施同步预算,新增 DRBD 同步屏障 | 第一字节同步前限额已生效;全部所需副本 UpToDate/Established 才允许下一卷;超时/异常停止推进 |
|
||||
| P0 | 扩大存储变更前后健康检查 | 验证已有 sandbox API、datastore、etcd 等消费者;新增 quorum loss、I/O 错误或只读即中止变更 |
|
||||
| P1 | 采集并定位实际瓶颈 | 对齐三宿主网络丢包/队列、吞吐、磁盘 await、CPU/PSI、DRBD 状态;无证据不直接扩大 ping timeout |
|
||||
| P1 | 补齐可操作告警 | DRBD quorum/peer、ext4 emergency_ro、数据库与 API 外部探测、LB 零后端,并演练真实通知链路 |
|
||||
| P1 | 恢复后业务验收与数据检查 | 对现有 sandbox 生命周期操作做受控验收,核对 PG 数据/备份和应用影响,单独报告不能验证的 RPO |
|
||||
| P1 | 复核共享故障域与同步总预算 | 同时覆盖多个 resource/peer;区分 SSD/HDD 池和物理网络/宿主故障域;设计限速或隔离方案后再测试 |
|
||||
| P2 | 标准化取证与并行变更交接 | 时间统一 UTC;事故期间共享受影响资源表、执行日志和完成边界;先 syntax/check,再执行缓解 playbook |
|
||||
|
||||
关闭本次根因整改需完成:跨资源影响审计、同步前预算与屏障验证、消费者健康保护、
|
||||
足够覆盖复制全过程的稳定性观察。当前只可宣称 **sandbox 服务恢复**。
|
||||
|
||||
## 证据与来源
|
||||
|
||||
### 现场关键摘录
|
||||
|
||||
```text
|
||||
17:12:20 drbd pm-af21c43d/0 drbd1011 pve3: Began resync as SyncSource
|
||||
17:12:56 drbd pm-de86804d/0 drbd1012 pve2: Began resync as SyncTarget
|
||||
17:15:47 drbd pm-6d8bee62 pve3: PingAck did not arrive in time.
|
||||
17:15:48 drbd pm-6d8bee62 pve2: PingAck did not arrive in time.
|
||||
17:15:48 drbd pm-6d8bee62/0 drbd1007: quorum( yes -> no )
|
||||
17:15:49 EXT4-fs error (device drbd1007): kmmpd:181: Error writing to MMP block
|
||||
17:15:49 Aborting journal on device drbd1007-8.
|
||||
17:15:49 EXT4-fs (drbd1007): Remounting filesystem read-only
|
||||
17:16:52 drbd pm-d1d1f3ea/0 drbd1008: quorum( yes -> no )
|
||||
17:16:52 EXT4-fs (drbd1008): Remounting filesystem read-only
|
||||
17:31:21 drbd pm-de86804d/0 drbd1012 pve2: repl( SyncTarget -> Established ) [resync-finished]
|
||||
17:33:38 drbd pm-af21c43d/0 drbd1011 pve3: pdsk( Inconsistent -> UpToDate ) repl( SyncSource -> Established ) [resync-finished]
|
||||
```
|
||||
|
||||
上述为 pve1 内核摘录,已省略重复前缀。43 次 quorum 丢失统计范围为 pve1 的
|
||||
`2026-09-25 17:10:00 UTC` 至 `17:55:00 UTC`,不是三节点全集群事件数。
|
||||
资源为 `pm-1f83b001`、`pm-57eb0cd7`、`pm-59a94edd`、`pm-6d8bee62`、
|
||||
`pm-7ad1a714`、`pm-a58b5f08`、`pm-cbba8c9d`、`pm-d1d1f3ea`、
|
||||
`pm-d4c12a89`、`pm-f21d1da3`、`vm-101-cloudinit`。
|
||||
|
||||
可复核入口:宿主 `journalctl --utc -k --since '2026-09-25 17:10:00 UTC'
|
||||
--until '2026-09-25 17:55:00 UTC'`、`pvenode task list`、目标 `drbdsetup status`;
|
||||
VyOS `journalctl -u haproxy` 和只读 stats socket;guest PostgreSQL/K3s journal。
|
||||
日志有保留期限,后续审计应保存经过秘密审查的所需片段。
|
||||
|
||||
### 操作会话
|
||||
|
||||
按维护者指向的 spaces1、spaces3 线索,读取了本地以下实际会话;以会话 ID/标题定位,
|
||||
不把 UI 的位置编号当作长期标识。不复制完整会话或凭据。
|
||||
|
||||
- `01a0d8c1-c4ad-7360-b52e-2a11c34dc13e`,**规划共享 PostgreSQL 数据库**:
|
||||
17:11:46 工具调用 `ansible-playbook pve-storage.yml`;17:20:27 输出显示默认
|
||||
`c-max-rate=102400k`,这只是配置上限,不是已测吞吐;17:25:58 两卷限速成功;
|
||||
17:30–17:31 报告 CT150 恢复;对应 rollout 的关键记录在行 1916、2019、2068 附近。
|
||||
- `01a0d972-e6e5-7432-ad4b-4fd7ca7b3956`,**配置 Alertmanager 通知**:
|
||||
17:13 用户确认测试通知送达;17:20 后观察到 etcd 新故障;17:24:37 用户确认
|
||||
另一路正在调整 etcd;约 17:28–17:30 记录监控覆盖缺口。该会话的监控盘点不等于
|
||||
对 sandbox 集群做过完整事故验收。
|
||||
- `01a0d9a9-7ef0-7992-a313-54668bb3b4e4`,**检查 VyOS 上的 LB 配置**:
|
||||
本次 sandbox 诊断、CT148 离线恢复和最终链路验收。
|
||||
|
||||
本地原记录位于 `/home/panxiao81/.codex/sessions/2026/09/25/`。
|
||||
会话说明只能证明当时的判断;时间线中执行结果以工具回执、PVE 任务和内核日志交叉核对。
|
||||
|
||||
### 相关源码与运行手册
|
||||
|
||||
- etcd rootfs 迁移:`infrastructure/etcd/ansible/move-storage.yml`
|
||||
- PG 数据卷准备:`infrastructure/shared-postgresql/ansible/pve-storage.yml`
|
||||
- 新卷限速任务:`infrastructure/shared-postgresql/ansible/tasks/limit-resync.yml`
|
||||
- etcd 故障恢复记录:`infrastructure/etcd/README.md`
|
||||
- shared PostgreSQL 当前部署边界:`infrastructure/shared-postgresql/README.md`
|
||||
- sandbox 架构与数据库依赖:`infrastructure/sandbox-cluster/README.md`
|
||||
|
||||
上述源码路径相对于 homelab-infra;etcd/shared-postgresql 文件在取证时仍未提交,
|
||||
当前文件已包含事故后的限速补丁,不能倒推事故前已经有同样保护。
|
||||
本报告以 wiki 为唯一维护位置,长期操作流程见[Proxmox 恢复手册](../services/proxmox.md#sandbox-lb-与根文件系统恢复)。
|
||||
源码合并后再补其固定版本链接。
|
||||
|
||||
### 取证过程中的敏感输出问题
|
||||
|
||||
首次 VyOS 查询误认为 `cli-shell-api showConfig` 尾随 `load-balancing` 会限制子树,
|
||||
实际返回完整配置,包含 WireGuard 私钥及登录密码哈希,进入了本会话工具输出。
|
||||
后续已改为设备端提取所需段,并在 `CLAUDE.md` 记录陷阱;未把敏感值写入报告或仓库。
|
||||
既有会话记录并未因此消除,应限制其分享;相关凭据轮换需另行安排,不能称为已处理完毕。
|
||||
@@ -2,7 +2,7 @@
|
||||
title: Authelia
|
||||
lifecycle: active
|
||||
evidence: documented
|
||||
last_reviewed: 2026-09-16
|
||||
last_reviewed: 2026-09-25
|
||||
last_verified: null
|
||||
sources:
|
||||
- 维护者于 2026-09-16 确认当前状态
|
||||
@@ -10,8 +10,10 @@ sources:
|
||||
|
||||
# Authelia
|
||||
|
||||
**Authelia 已作为 homelab 唯一的主 OIDC broker 工作,当前状态为 active。**
|
||||
此状态由维护者于 2026-09-16 明确,本轮未查询运行环境。
|
||||
**Authelia 继续作为 homelab 的主 OIDC 入口与人类认证后端工作,状态为 active。**
|
||||
基础状态由维护者于 2026-09-16 明确。2026-09-25 新增 [Hydra 人类登录 PoC](hydra.md),
|
||||
以标准 OIDC client 复用 Authelia;其原有应用客户端、Samba AD 后端及 MFA 策略保留。
|
||||
该次仅验证新增配置有效和 Pod 就绪,未更新本页原有功能的整体验收日期。
|
||||
|
||||
## 用途与入口
|
||||
|
||||
|
||||
@@ -2,10 +2,12 @@
|
||||
title: Gitea Dynamic Runner
|
||||
lifecycle: experimental
|
||||
evidence: documented
|
||||
last_reviewed: 2026-09-16
|
||||
last_reviewed: 2026-09-21
|
||||
last_verified: null
|
||||
sources:
|
||||
- https://git.ddupan.top/panxiao81/gitea-dynamic-runner/src/branch/main/README.md
|
||||
- https://git.ddupan.top/panxiao81/homelab-infra/src/branch/main/platform/dynamic-runner/README.md
|
||||
- https://git.ddupan.top/panxiao81/ci-actions/src/tag/v1
|
||||
---
|
||||
|
||||
# Gitea Dynamic Runner
|
||||
@@ -48,13 +50,23 @@ runs-on: [self-hosted, vm]
|
||||
|
||||
| 接口 | 执行方式 | 使用时需要理解的边界 |
|
||||
|---|---|---|
|
||||
| `pod` | 动态 Kubernetes privileged Pod;workflow 使用 host executor | Docker、BuildKit、kind 等工具由 pipeline 按需 setup;这里的 host executor 指 Pod 内执行环境 |
|
||||
| `pod` | 动态 Kubernetes privileged Pod;workflow 使用 host executor | 旧 README 要求 pipeline 按需 setup Docker;Docker 的新约定见下文。host executor 指 Pod 内执行环境 |
|
||||
| `vm` | 动态 Cloud Hypervisor microVM | 每个任务创建独立 COW disk、seed 和 TAP,guest runner 执行一个 job 后关机并清理 |
|
||||
|
||||
两种接口不能仅凭“环境一次性”就认定具有相同的隔离边界。
|
||||
接入前需要结合项目设计约束和实际部署确认任务的信任范围。
|
||||
旧 homelab-infra 文档中的 `kind-microvm` 是早期记录,不作为本项目当前 workflow 接口。
|
||||
|
||||
### Docker 可用性约定更新
|
||||
|
||||
维护者于 2026-09-21 明确:CI 后端正在修复,后续由 runner 保证 dockerd 默认可用。
|
||||
这取代旧说明中要求业务 workflow 自行启动 Docker daemon 的部分;不能据此推断 BuildKit、
|
||||
kind 等其他工具也默认就绪。数据库集成测试不因使用 Docker 而要求 VM。
|
||||
消费方 workflow 应检查 Docker 是否可用,而不重复启动 daemon、强制 storage driver 或
|
||||
覆盖 runner 提供的 endpoint。[Ayatori #6](https://git.ddupan.top/panxiao81/ayatori/pulls/6)
|
||||
正在按此约定调整。此处依据维护者说明,不表示后端修复已经部署或远端集成已经通过,
|
||||
`last_verified` 保持不变。
|
||||
|
||||
## 组件如何协作
|
||||
|
||||
当前 README 描述的 bootstrap 路径为:
|
||||
@@ -94,6 +106,16 @@ workflow 决定如何消费身份:登录哪个服务、请求哪个 audience
|
||||
不属于 runner 内置的业务流程。向其他服务请求 token 也遵循同一边界;
|
||||
runner 不应替 workflow 选择下游 role/policy,或统一代理其业务凭据交换。
|
||||
|
||||
通用实现已发布为 [`panxiao81/ci-actions@v1`](https://git.ddupan.top/panxiao81/ci-actions/src/tag/v1):
|
||||
`spiffe-openbao-login` 负责获取 JWT-SVID、交换 Bao token 和退出吊销,`setup-nexus`
|
||||
负责匿名配置 Ansible Galaxy、Go module proxy 与 OCI endpoint。后者读取 Nexus public
|
||||
repository 时不需要 Bao 登录;发布制品应另建 repository service account 和最小权限
|
||||
policy。
|
||||
|
||||
这些 Action 不扩大 runner 权限。runner 只提供 Node.js 20、`spire-agent` 与 Workload
|
||||
API socket,workflow 明确声明 role、audience 和用途,目标服务 policy 做最终授权。
|
||||
由于短期 token 会进入 Actions job 临时文件,只能在一次性 Pod/VM executor 使用。
|
||||
|
||||
因此,身份相关的环境验收应关注 Pod/VM 能否取得各自身份和是否保持隔离;
|
||||
具体服务的登录与 token 使用由对应 workflow 验收。
|
||||
本段记录设计职责,不表示获取身份的能力已经在所有 backend 完成实现或现场验证。
|
||||
@@ -115,6 +137,7 @@ runner 不应替 workflow 选择下游 role/policy,或统一代理其业务凭
|
||||
- [设计原则](https://git.ddupan.top/panxiao81/gitea-dynamic-runner/src/branch/main/docs/design-principles.md):README 指向的完整设计约束,本轮未逐篇复核。
|
||||
- [Runner 协议路线](https://git.ddupan.top/panxiao81/gitea-dynamic-runner/src/branch/main/docs/runner-protocol-roadmap.md):README 指向的长期调度路线与迁移边界,本轮未逐篇复核。
|
||||
- [SPIFFE/SPIRE](spire.md):统一机器身份的设计定位与阶段依据。
|
||||
- [`ci-actions@v1`](https://git.ddupan.top/panxiao81/ci-actions/src/tag/v1):workflow 可复用的 SPIFFE/OpenBao 登录与 Nexus 配置 Action。
|
||||
|
||||
实际启用范围、workflow 验收、排障及消息队列约定在项目文档中维护。
|
||||
开发中的变化直接以项目文档为准,知识库不另列“启用范围待核实”任务。
|
||||
|
||||
+7
-1
@@ -2,7 +2,7 @@
|
||||
title: Gitea 与 Actions 使用指南
|
||||
lifecycle: active
|
||||
evidence: documented
|
||||
last_reviewed: 2026-09-16
|
||||
last_reviewed: 2026-09-25
|
||||
last_verified: null
|
||||
---
|
||||
|
||||
@@ -23,6 +23,12 @@ Gitea 托管 homelab 的代码、文档、issue 和 PR;Actions 执行仓库声
|
||||
登录成功但看不到仓库时,先确认当前账号与仓库权限;OIDC 登录本身不会赋予所有项目的管理权。
|
||||
已有账号应沿用原账号关联,遇到关联问题交由管理员处理,不另建同名账号规避。
|
||||
|
||||
## Hydra 实验性登录
|
||||
|
||||
2026-09-25 按维护者要求新增 [Hydra 人类登录 PoC](hydra.md),保留旧 Authelia 登录源。
|
||||
从 <https://git.ddupan.top/user/oauth2/hydra> 发起,需 LAN/Tailscale 连通 Hydra 内网入口。
|
||||
最终认证仍在 Authelia 完成;真实账号返回和权限验收结果见 Hydra 服务页。
|
||||
|
||||
## 创建与修改仓库
|
||||
|
||||
通过页面的 New Repository 创建仓库,选择所属用户或组织、名称及可见性。
|
||||
|
||||
+90
-3
@@ -2,7 +2,7 @@
|
||||
title: Grafana 与可观测性使用指南
|
||||
lifecycle: active
|
||||
evidence: documented
|
||||
last_reviewed: 2026-09-16
|
||||
last_reviewed: 2026-09-25
|
||||
last_verified: null
|
||||
---
|
||||
|
||||
@@ -12,7 +12,11 @@ last_verified: null
|
||||
使用 Authelia OIDC 登录;远程访问需要到 LAN 的路由及内网 DNS。
|
||||
|
||||
本页依据现有 observability README、Grafana 数据源配置、内存看板 JSON 和 exporter 说明整理,
|
||||
部分来源仍在源码工作区、尚未提交。本轮未打开网页或执行查询;以下结果描述是使用预期。
|
||||
部分来源仍在源码工作区、尚未提交。看板使用说明未逐项现场验证;
|
||||
2026-09-25 的通知链路与采集故障验证范围见下文。
|
||||
|
||||
整体接入范围、已确认盲点和补齐顺序见 [监控覆盖与补齐计划](../guides/monitoring-coverage.md)。
|
||||
第一批已接入的规则、阈值、静默和排障方法见 [基础监控与告警运维](../guides/monitoring-foundation.md)。
|
||||
|
||||
## 先看主机内存与 Swap
|
||||
|
||||
@@ -59,16 +63,99 @@ VictoriaLogs 使用 LogsQL。上述 limit 限制返回数量,不保证返回
|
||||
关键字没有结果时可以放宽时间范围并回到第一步,区分“没有该关键字”与“没有采集数据”。
|
||||
语法依据见 [VictoriaLogs 查询说明](https://docs.victoriametrics.com/victorialogs/querying/)。
|
||||
|
||||
## 三个数据源的分工
|
||||
## 数据源的分工
|
||||
|
||||
| 数据源 | 用途 |
|
||||
|---|---|
|
||||
| VictoriaMetrics | Prometheus 兼容指标查询,例如内存、CPU、采集健康 |
|
||||
| Alertmanager | 现有告警通知状态与静默管理;Prometheus 实现,UID 为 `alertmanager` |
|
||||
| VictoriaLogs | LogsQL 日志查询 |
|
||||
| VictoriaTraces | Jaeger 兼容追踪查询;应用需要先接入追踪,不能仅凭数据源存在认为所有服务都有 trace |
|
||||
|
||||
数据源名称来自 `platform/observability/grafana/values.yaml`。
|
||||
|
||||
## Telegram 告警接入
|
||||
|
||||
2026-09-25 已通过 [homelab-infra PR #147](https://git.ddupan.top/panxiao81/homelab-infra/pulls/147)
|
||||
合并并由 Flux 同步,替换原有全部 blackhole 的通知策略。配置来源为
|
||||
[VMAlertmanager](https://git.ddupan.top/panxiao81/homelab-infra/src/commit/c06c6f78572106586b9b55069dae654a35f4f6bf/platform/observability/metrics/vmalertmanager.yaml)
|
||||
及同目录的 `alertmanager-external-secret.yaml`、`kustomization.yaml`。
|
||||
已现场确认 Flux Ready、ExternalSecret SecretSynced、Alertmanager Pod Ready、
|
||||
配置加载成功。通过 Alertmanager API 注入的临时测试告警已触发 Telegram 发送,
|
||||
发送失败计数为 0,维护者已确认收到测试告警;测试在 60 秒后自动恢复。
|
||||
恢复通知按 5 分钟组内间隔发出,发送总计数从 2 增至 3,失败计数仍为 0。
|
||||
恢复消息的收件端确认未单独取得;总计数也包含一条既有 TooManyScrapeErrors 通知。
|
||||
本次验证限于通知链路,不刷新整个 Grafana 服务的 `last_verified`。
|
||||
|
||||
- 接收频道:<https://t.me/ddupan_alerting>,数字 chat ID 为 `-1003956377923`。
|
||||
- bot:`@ddupan_alerting_bot`。2026-09-25 通过 Telegram `getChat` / `getChatMember`
|
||||
确认频道 ID、管理员身份和发布消息权限;bot 直发的测试触发、恢复消息已由维护者确认收到。
|
||||
- OpenBao:KV v2 mount `kv`、路径 `k8s/alertmanager`、字段 `telegram_bot_token`。
|
||||
ExternalSecret 使用 `ClusterSecretStore/openbao`,每小时同步到
|
||||
`monitoring/alertmanager-telegram` Secret 的同名字段。
|
||||
- VMAlertmanager 挂载 Secret,使用 `bot_token_file` 读取,不在 Git 中保存 token。
|
||||
- critical 首次分组等待 10 秒,未恢复每小时提醒;warning 等待 1 分钟,
|
||||
未恢复每 4 小时提醒。分组键为 `alertname, cluster, job, severity`,
|
||||
组内变更通知间隔 5 分钟;两类均发送恢复通知。info、缺失或其他 severity 暂不推送。
|
||||
- 采用 Alertmanager 默认 Telegram 消息模板;同容器 CrashLoop 抑制重复重启通知,
|
||||
具体匹配范围见基础监控运维指南。
|
||||
|
||||
配置变更通过既有 Flux 流程发布,先确认 ExternalSecret Ready 和目标 Secret
|
||||
投射成功,再确认 Alertmanager 加载配置及到 Telegram API 的出站网络。
|
||||
首次启用可能推送当时已有的 warning/critical 告警;发送测试告警需要维护者同意,
|
||||
并在频道确认故障与恢复消息均收到。静态检查不能代替这一步。
|
||||
|
||||
收不到通知时依次检查 ExternalSecret 状态、Alertmanager 配置加载与发送错误、
|
||||
bot 的频道发布权限以及手机频道通知设置。轮换 token 后需等待或触发 ESO 同步,
|
||||
并验证 Alertmanager 使用新 token;必要时重载或重启,不打印 Secret 内容。
|
||||
|
||||
## 从告警进入 Grafana
|
||||
|
||||
Telegram 新通知的 Source 指向 Grafana `/explore`,使用 VictoriaMetrics 数据源,
|
||||
携带原始告警表达式,时间范围从该告警触发时刻到现在。首次访问需要登录 Grafana;
|
||||
原有 Telegram 消息中的旧 Pod 地址不会被追溯修改。
|
||||
Source 查询指标不依赖 Alertmanager 数据源。
|
||||
|
||||
Grafana 同时 provision `Alertmanager` 数据源,通过服务端代理连接
|
||||
`http://vmalertmanager-main.monitoring.svc:9093`,实现类型为 `prometheus`。
|
||||
进入 **Alerting**,在支持选择 Alertmanager 的页面切换到 **Alertmanager**,
|
||||
可查看通知策略、接收端并管理静默。Prometheus 实现的接收端、通知策略和模板为只读,
|
||||
持久修改仍通过 Git/Flux;告警规则继续优先使用 `PrometheusRule`,由 vmalert 执行。
|
||||
本数据源未启用转发 Grafana-managed alerts。
|
||||
|
||||
配置来源:[homelab-infra PR #152](https://git.ddupan.top/panxiao81/homelab-infra/pulls/152)。
|
||||
2026-09-25 现场确认 Flux 已应用 `dbf66590acea4a681e2e3bb6965f9a19ece4190e`,
|
||||
Grafana HelmRelease Ready、两个 Deployment 就绪;68 条规则无评估错误。
|
||||
实际 Alertmanager 告警的 generatorURL 已指向 Grafana,解码后的表达式与 vmalert 原表达式一致。
|
||||
Grafana API 已确认 provisioned 数据源,并通过其代理成功读取 `/api/v2/status`、
|
||||
`/api/v2/alerts` 和 `/api/v2/silences`。现场插件的 Save & test 使用前端代理请求 status;
|
||||
通用 `/api/datasources/uid/alertmanager/health` 不适用于这个前端插件,会返回 Plugin unavailable。
|
||||
本轮没有执行浏览器 OIDC 登录与手工创建静默,不将 API 验证写作浏览器端验收。
|
||||
|
||||
功能边界见 [Grafana Alertmanager 文档](https://grafana.com/docs/grafana/latest/datasources/alertmanager/)。
|
||||
|
||||
## 采集失败的定位与处理
|
||||
|
||||
`TooManyScrapeErrors` 使用 vmagent 的采集失败计数判断最近 5 分钟是否出现错误,
|
||||
持续 15 分钟后触发。告警中的 `instance` 是 vmagent 自己,并非失败目标地址;
|
||||
先检查 vmagent `/api/v1/targets` 中非 up 目标的 `scrapeUrl` 与 `lastError`。
|
||||
目标恢复后还要等待 5 分钟回看窗口消退,Telegram 恢复通知另受组内间隔影响。
|
||||
|
||||
- k3s 的 kubelet `/metrics` 还包含 apiserver/etcd 指标,实测约 16.1 MiB,
|
||||
超过 vmagent 默认 16 MiB 限制。`VMNodeScrape/kubelet` 单独设置
|
||||
`spec.max_scrape_size: "32MiB"`;其他采集任务保留默认值。
|
||||
再次超限时先统计指标族和响应大小,不直接无限增大全局限制。
|
||||
- 独立 Docker cAdvisor 尚未部署,旧 `192.168.10.127:8080/metrics` 实际返回 nginx 404,
|
||||
已从 `VMStaticScrape/docker-hosts` 移除。该配置仍保留已有 :9100 主机目标,
|
||||
Kubernetes 容器指标继续由 `VMNodeScrape/cadvisor` 的 `/metrics/cadvisor` 提供。
|
||||
后续需要 Docker 容器指标时,先部署 exporter 并验证端口,再增加采集目标。
|
||||
|
||||
配置依据:[homelab-infra PR #148](https://git.ddupan.top/panxiao81/homelab-infra/pulls/148),
|
||||
2026-09-25 已合并并由 Flux 应用 `a43b7d3c26f9724b9d5b2ad45058f2d1632741af`。
|
||||
现场确认 kubelet 恢复 up,旧 :8080 目标消失。此次验收期间另发现共享 etcd
|
||||
`10.60.0.20:2381` 拒绝连接,因此不能将本次两项修复等同于全部采集目标健康或
|
||||
`TooManyScrapeErrors` 已恢复;后续状态需重新检查 targets,etcd 的操作背景另行对齐。
|
||||
|
||||
## 出问题时与维护入口
|
||||
|
||||
- 域名打不开:先区分内网 DNS、到 LAN 的路由和浏览器证书错误。
|
||||
|
||||
@@ -0,0 +1,86 @@
|
||||
---
|
||||
title: Hydra 与 OIDC 上游适配器
|
||||
lifecycle: experimental
|
||||
evidence: live-verified
|
||||
last_reviewed: 2026-09-25
|
||||
last_verified: 2026-09-25
|
||||
sources:
|
||||
- https://git.ddupan.top/panxiao81/iam-login/pulls/2
|
||||
- https://git.ddupan.top/panxiao81/iam-login/commit/9cf2d235dff0cd33f98012b0a114f14a8f9bfcda
|
||||
- https://git.ddupan.top/panxiao81/homelab-infra/pulls/142
|
||||
- https://git.ddupan.top/panxiao81/homelab-infra/pulls/143
|
||||
- 2026-09-25 部署、discovery、重定向与网络隔离检查
|
||||
- 维护者于 2026-09-25 确认 Hydra 登录成功返回原 Gitea 账号且仓库权限正常
|
||||
---
|
||||
|
||||
# Hydra 与 OIDC 上游适配器
|
||||
|
||||
第一轮人类登录 PoC:Hydra 负责 OIDC 签发,薄的 Login/Consent 服务通过标准 OIDC
|
||||
验证上游身份。当前配置的上游是 Authelia,它继续连接 Samba AD 并执行人类 MFA。
|
||||
适配器没有直接连接 LDAP,也不与 Authelia 专有认证协议绑定。
|
||||
|
||||
本服务独立于 Ayatori。现役 PoC 代码仍作为 homelab-infra 中的独立 Go module 保存。
|
||||
下一阶段直接连接 AD 的 Java/Spring 登录服务已建立独立仓库
|
||||
[iam-login](https://git.ddupan.top/panxiao81/iam-login),已建立 Spring Native 构建验证基础,人类界面方向见
|
||||
[浏览器登录设计](../architecture/independent-iam-draft.md#人类浏览器登录界面),
|
||||
尚未替换现役 Go/Authelia 链路。应用代码、测试与 Native 构建发布归新仓库,环境部署归
|
||||
homelab-infra;首轮实现由 [issue #1](https://git.ddupan.top/panxiao81/iam-login/issues/1) 跟踪。
|
||||
完整的多主体 IAM 仍是[草案](../architecture/independent-iam-draft.md);
|
||||
本轮不实现 SPIFFE 登录、agent 专用认证、动态授权或统一组迁移。
|
||||
|
||||
## 入口与首次使用
|
||||
|
||||
| 入口 | 用途 |
|
||||
|---|---|
|
||||
| <https://hydra.ad.ddupan.top> | Hydra 公共 OAuth2/OIDC API |
|
||||
| <https://hydra-login.ad.ddupan.top> | Login/Consent 适配器,仅处理具体流程路径 |
|
||||
| <https://git.ddupan.top/user/oauth2/hydra> | 从 Gitea 发起 Hydra 人类登录 |
|
||||
|
||||
Hydra 两个域名仅通过 LAN/Tailscale 可达,无公网 tunnel。请从 Gitea 的 `hydra`
|
||||
登录源进入,在 Authelia 完成既有认证,然后返回 Gitea;旧 `authelia` 登录源保留。
|
||||
Gitea 继续按原有账号关联、仓库权限与 gitea-admins 组映射执行授权。
|
||||
|
||||
```text
|
||||
Gitea → Hydra → OIDC Login/Consent → Authelia → Samba AD
|
||||
← OIDC ← 已验证的人类身份 ← OIDC callback
|
||||
```
|
||||
|
||||
## 验证范围
|
||||
|
||||
2026-09-25 已现场验证:Hydra 数据库迁移成功、两个 Deployment 就绪、ESO SecretSynced、
|
||||
TLS discovery 的 issuer/endpoints 正确、Flux hydra Kustomization Ready/Healthy;
|
||||
HTTP 登录链路可从 Hydra 经适配器到达 Authelia 登录页。
|
||||
|
||||
无效 login、callback、consent 请求返回 403。Gitea Pod 能访问公共 discovery,不能
|
||||
直连 Hydra admin Service;公共 HTTPS 入口的 admin API 返回 404。
|
||||
|
||||
Gitea 的新增登录源经 PR #143 接入,Helm revision 19 UpgradeSucceeded、Pod Ready;
|
||||
登录页同时显示 hydra/authelia,从真实 Gitea 入口到达 Authelia 的整段跳转已验证。
|
||||
**第一轮人类登录 PoC 已通过验收。** 维护者于 2026-09-25 实际使用 Hydra 登录入口后
|
||||
确认:“已成功返回原账号,仓库权限正常”。这补齐了人类认证后的回调、原账号关联与
|
||||
仓库权限验收;依据为维护者实际操作反馈,而非 agent 代为输入人类凭据。
|
||||
`last_verified` 覆盖上述明确列出的检查及维护者登录反馈,不表示机器或 agent 路径已验证。
|
||||
|
||||
## 实现与维护
|
||||
|
||||
- Hydra 固定 `v26.2.0` 与镜像 digest,使用独立 hydra PostgreSQL database/role。
|
||||
- 源码 `apps/hydra/login-consent`:标准 OIDC 上游适配器。校验 ID token issuer、audience、
|
||||
签名、有效期和 nonce,使用 PKCE S256 与单次、cookie 绑定的 state。
|
||||
- 当前只允许 Gitea client 和 openid/profile/email/groups;按请求 scope 释放 claims,
|
||||
不签发 refresh token,不提供通用自动 consent。主体为上游 issuer/sub 的稳定哈希。
|
||||
- 单副本短期登录事务保存在内存;重启使正在进行的登录失效,用户重新发起即可。
|
||||
- Hydra admin 无 HTTPRoute,NetworkPolicy 仅允许适配器访问;维护时通过受控本地
|
||||
kubectl port-forward,不对外开放 admin。
|
||||
- 秘密保存在 OpenBao `kv/k8s/hydra`,ESO 投射给 Hydra/适配器和 Gitea。禁止重建
|
||||
system_secret 来处理普通启动问题。
|
||||
- Authelia 的新 hydra-login client 通过现有 Helm release 的增量 values 更新,保留全部
|
||||
已有客户端与 two_factor 策略;Authelia 暂未由 Flux 接管。
|
||||
|
||||
源码、构建、claims/client 配置和恢复说明见
|
||||
[Hydra README](https://git.ddupan.top/panxiao81/homelab-infra/src/branch/main/apps/hydra/README.md)。
|
||||
Hydra 部署见 [PR #142](https://git.ddupan.top/panxiao81/homelab-infra/pulls/142),
|
||||
Gitea 接入见 [PR #143](https://git.ddupan.top/panxiao81/homelab-infra/pulls/143)。
|
||||
|
||||
依赖共享 PostgreSQL、OpenBao/ESO、Authelia、Envoy、Samba DNS 与 zot。独立于 Ayatori
|
||||
不等于已完成共享基础设施之外的灾备;恢复需保留 Hydra 数据库和秘密。
|
||||
回退时先撤 Gitea 新登录源,沿用旧 Authelia 入口,不删除用户或原有认证配置。
|
||||
+5
-3
@@ -1,6 +1,6 @@
|
||||
# 服务总览
|
||||
|
||||
审阅日期:2026-09-16。以下覆盖源码工作区 apps/、platform/、infrastructure/ 的一级组件,以及集群入口。
|
||||
审阅日期:2026-09-18。以下覆盖源码工作区 apps/、platform/、infrastructure/ 的一级组件,以及集群入口。
|
||||
**除旧 VictoriaMetrics Compose 已获授权检查并清理外,其余条目未在本轮现场验证。**
|
||||
状态栏区分维护者说明、文档、ticket、配置与现场证据,不提供持续的实时健康判断。
|
||||
SPIFFE/SPIRE 已按维护者授权补读 #34;LAN DNS 与 Authelia 已按维护者说明更新,
|
||||
@@ -14,6 +14,7 @@ SPIFFE/SPIRE 已按维护者授权补读 #34;LAN DNS 与 Authelia 已按维护
|
||||
|
||||
| 组件 | 用途 | 记录入口 | 状态依据 | 来源 | 文档缺口 / 下一步 |
|
||||
|---|---|---|---|---|---|
|
||||
| [hydra](hydra.md) | OIDC 签发与通用上游适配器,人类登录 PoC | `hydra.ad.ddupan.top / hydra-login.ad.ddupan.top` | experimental;9 月 25 日基础设施验证及维护者真实人类登录验收通过 | `apps/hydra/`、PR #142/#143 | 第一轮人类 PoC 完成;机器与 agent 接入另行推进 |
|
||||
| [authelia](authelia.md) | 唯一主 OIDC broker、统一登录 | `auth.ddupan.top` | active;维护者于 2026-09-16 明确已在工作 | 维护者说明、`apps/authelia/` | 同步源码 README 中过时的 OIDC 阶段说明 |
|
||||
| [blocky](lan-dns.md) | LAN 主 DNS、广告过滤、分流 | `192.168.10.127:53` | 维护者说明已作为 DHCP 主 DNS,上游为路由器 | 维护者 2026-09-16 说明、`apps/blocky/README.md` | 无需逐台确认主机;旧源码说明待同步 |
|
||||
| [gitea](gitea.md) | 代码托管与 Actions | `git.ddupan.top` | 记录已部署 | `apps/gitea/README.md` | 已有登录、最小 CI 与 runner 选择指南 |
|
||||
@@ -22,6 +23,7 @@ SPIFFE/SPIRE 已按维护者授权补读 #34;LAN DNS 与 Authelia 已按维护
|
||||
| [marker](marker.md) | GPU 文档转换 API | `集群内端口 8001` | 配置与部署指南;未附上线记录 | `apps/marker/README.md` | 已有转换示例;部署镜像仍为占位符 |
|
||||
| netboot | PXE 与系统安装 | `192.168.10.127` | 有部署及使用记录 | `apps/netboot/README.md` | 已有客户端启动说明 |
|
||||
| [netbox](netbox.md) | 网络资产与地址管理评估 | `netbox.ad.ddupan.top` | 记录已部署;评估用途 | `apps/netbox/README.md` | 已有浏览与 Git 修改入口指南 |
|
||||
| [nexus](nexus.md) | CI 包代理与统一制品仓库 POC | `nexus.ad.ddupan.top` | 2026-09-20 已现场验证 Ansible、Go、OCI 与 BuildKit cache | `apps/nexus/README.md` | 补 publisher account、外部 PostgreSQL 与备份恢复测试 |
|
||||
| [openviking](openviking.md) | 上下文检索服务 | `记录端口 1933 / 8020` | 配置与部署指南;未附上线记录 | `apps/openviking/README.md` | 已有导入、任务查询、检索与原文读取指南 |
|
||||
| [ps3netsrv](ps3netsrv.md) | PS3 网络内容服务 | `宿主 TCP 38008;地址未记录` | Docker 运维文档记录运行 | `apps/ps3netsrv/docker-compose.yml` | 已有客户端与内容目录指南 |
|
||||
| [seaweedfs](seaweedfs.md) | S3 对象存储 | `s3.ad.ddupan.top` | zot 文档记录已使用 | `apps/seaweedfs/README.md` | 已有客户端读写指南与备份边界说明 |
|
||||
@@ -57,7 +59,7 @@ SPIFFE/SPIRE 已按维护者授权补读 #34;LAN DNS 与 Authelia 已按维护
|
||||
| microvm-runner(历史目录名) | 动态 runner 的 homelab 基础设施记录 | 当前项目接口见 [Dynamic Runner](gitea-dynamic-runner.md) | 独立项目已更名并扩展到 Pod/VM,正在积极开发 | `infrastructure/microvm-runner/README.md`、独立项目文档 | 具体启用范围和实现进度以独立项目文档为准 |
|
||||
| [oci](oci.md) | 云主机、网络与站点互联 | `OCI ap-osaka-1` | 有恢复、接管与网络实施记录 | `infrastructure/oci/README.md` | 已有登录、站点网络与维护入口 |
|
||||
| [openbao](openbao.md) | 秘密管理与内部 CA | `bao.ad.ddupan.top` | 有部署与接管记录 | `infrastructure/openbao/README.md` | 已有登录、取密与运维入口指南 |
|
||||
| [proxmox](proxmox.md) | PVE、虚拟化与主机基础设施 | `PVE 管理入口` | 已有基础设施 | `infrastructure/proxmox/ansible/` 与 `README-ha.md` | 已有管理入口;身份与 runner 设计见独立项目 |
|
||||
| [proxmox](proxmox.md) | PVE、虚拟化与主机基础设施 | `PVE 管理入口` | 已有基础设施 | `infrastructure/proxmox/ansible/` 与 `README-ha.md` | 已有管理入口;sandbox LB/根盘恢复流程见服务页;身份与 runner 设计见独立项目 |
|
||||
| [samba-ad](samba-ad.md) | AD 身份、域 DNS 与域成员管理 | `dc1 / 192.168.10.5` | 有部署记录;维护者说明 DNS 部分已完成 | `infrastructure/samba-ad/README.md`、[LAN DNS](lan-dns.md) | 已有入域、目录浏览与日常管理入口 |
|
||||
|
||||
## 集群
|
||||
@@ -74,7 +76,7 @@ SPIFFE/SPIRE 已按维护者授权补读 #34;LAN DNS 与 Authelia 已按维护
|
||||
|
||||
- [e5renew、research-auto](external-consumers.md):GitHub 上的外部消费者,不属于 homelab 基础设施;仅保留归属入口。
|
||||
- [Gitea Dynamic Runner](gitea-dynamic-runner.md):正在积极开发的动态 Pod/VM runner,原名 gitea-microvm-runner;具体启用范围、调度和队列约定以项目文档为准。
|
||||
- [PostgreSQL Tenant Operator](postgresql-tenant-operator.md):计划中的 DBaaS 中间层,管理共享实例中的数据库与账号;README 记录为 API 骨架阶段,不代表服务已上线。
|
||||
- [PostgreSQL Tenant Operator](postgresql-tenant-operator.md):计划中的 DBaaS 中间层,管理共享实例中的数据库与账号;现转入 Ayatori Database,采用独立 Database 资源与 Tenant 申请;设计修订不代表服务上线。
|
||||
- [workload-sts](../architecture/workload-sts-history.md):已归档的早期机器身份方案;停止开发、不部署 PoC,由 SPIFFE/SPIRE 替代。
|
||||
- Backstage:规划中的服务目录与文档入口;本轮未发现独立部署目录。
|
||||
- Keycloak、Casdoor:`archive/` 下有明确退役记录,替代入口为 Authelia。
|
||||
|
||||
+8
-1
@@ -2,7 +2,7 @@
|
||||
title: NATS
|
||||
lifecycle: active
|
||||
evidence: documented
|
||||
last_reviewed: 2026-09-16
|
||||
last_reviewed: 2026-09-25
|
||||
last_verified: null
|
||||
sources:
|
||||
- 维护者于 2026-09-16 提供的部署与消费者说明
|
||||
@@ -40,3 +40,10 @@ Dynamic Runner 的 stream、subject、durable 名称、worker 配置和具体启
|
||||
|
||||
知识库只保留[Dynamic Runner 的用途与职责边界](gitea-dynamic-runner.md)。
|
||||
涉及 runner 的实际配置和实现进度时,先按项目文档接续工作;需要扩大查询范围时再向维护者确认。
|
||||
|
||||
## 指标与告警
|
||||
|
||||
2026-09-25 已现场确认既有 :7777 prom-exporter 经 PodMonitor → VMPodScrape 接入中央采集,
|
||||
job 为 `nats/nats`,target up 且 nats_* 指标有当前样本。已有采集不可用/整个 job 消失告警;
|
||||
JetStream 容量、consumer 积压等业务规则仍待第二批。
|
||||
转换器故障处理与验证依据见 [基础监控运维](../guides/monitoring-foundation.md#nats-转换故障经验)。
|
||||
|
||||
@@ -0,0 +1,120 @@
|
||||
---
|
||||
title: Nexus Repository POC
|
||||
lifecycle: experimental
|
||||
evidence: live-verified
|
||||
last_reviewed: 2026-09-20
|
||||
last_verified: 2026-09-20
|
||||
sources: []
|
||||
---
|
||||
|
||||
# Nexus Repository POC
|
||||
|
||||
Nexus Repository Community Edition POC 为一次性 CI runner 提供共享的 Ansible Galaxy、
|
||||
Go Modules、OCI 与 BuildKit 缓存,减少每个 job 从公网重新下载依赖的时间。GitOps 已部署,
|
||||
上述代理与缓存链路均已完成现场验证;数据库和备份仍是 POC,现役 zot 保持不变。
|
||||
|
||||
## 从哪里使用
|
||||
|
||||
- 入口:`https://nexus.ad.ddupan.top`,仅 LAN。
|
||||
- 人类管理:当前使用本地管理员,凭据受管于 OpenBao `kv/infra/nexus`;尚未配置 LDAP。
|
||||
后续正式化优先使用 Samba AD LDAP。Community
|
||||
Edition 不提供原生 OIDC/SAML,因此不能把 Authelia OIDC 写成已支持入口。
|
||||
- CI 读取:`ansible-public`、Ansible 返回制品 URL 使用的成员 proxy 与 `go-public` 已开放
|
||||
LAN 匿名只读;`oci-public` 与其 `oci-proxy` 成员同样匿名只读,`oci-hosted` 不开放匿名。
|
||||
Terraform 明确收窄权限,未使用默认的全仓库匿名角色。
|
||||
- CI 发布:目标是少量按信任边界划分的本地 service account,凭据由 OpenBao 保存;
|
||||
当前 POC 尚未创建 publisher 或授予写权限。
|
||||
|
||||
不能在整个入口套用 Authelia browser forward-auth:`ansible-galaxy`、Go 和 OCI 客户端
|
||||
不会完成浏览器登录。若以后给 UI 单独加 RUT/forward-auth,必须使用与 package API 分离
|
||||
且不可绕过的入口,并先完成 Header 信任边界审计。
|
||||
|
||||
## 第一次使用
|
||||
|
||||
部署与 Terraform 初始化完成后,Ansible 客户端将 Galaxy server 指向:
|
||||
|
||||
```ini
|
||||
[galaxy]
|
||||
server_list = nexus
|
||||
|
||||
[galaxy_server.nexus]
|
||||
url = https://nexus.ad.ddupan.top/repository/ansible-public/
|
||||
```
|
||||
|
||||
然后在已有 `collections/requirements.yml` 的项目中运行:
|
||||
|
||||
```bash
|
||||
ansible-galaxy collection install -r collections/requirements.yml \
|
||||
-p .ansible/collections
|
||||
```
|
||||
|
||||
2026-09-20 使用两个全新客户端目录下载 `community.general:11.2.0`:冷缓存 8.49 秒、
|
||||
热缓存 1.89 秒,两份 tarball SHA-256 一致。Nexus Ansible format 返回的制品 URL 指向
|
||||
成员 proxy,因此匿名角色必须同时具备 group 与该 proxy 的只读权限。
|
||||
|
||||
Go POC 使用:
|
||||
|
||||
```bash
|
||||
GOPROXY=https://nexus.ad.ddupan.top/repository/go-public/ go mod download
|
||||
```
|
||||
|
||||
私有 module 的 `GOPRIVATE`、认证和 fallback 需由实际 workflow 明确配置,不能把内部 module
|
||||
路径意外发送到公共 proxy。
|
||||
|
||||
2026-09-20 使用两个全新 Go module cache 下载 `golang.org/x/[email protected]`:冷缓存
|
||||
2.92 秒、热缓存 1.51 秒,均通过 `go-public` 匿名入口完成。
|
||||
|
||||
OCI 使用 path-based routing。公共镜像从
|
||||
`nexus.ad.ddupan.top/oci-public/<namespace>/<image>:<tag>` 匿名拉取;写入使用
|
||||
`nexus.ad.ddupan.top/oci-hosted/<namespace>/<image>:<tag>` 并要求认证。2026-09-20 验证:
|
||||
|
||||
- Alpine 代理冷拉 4.75 秒、热拉 0.80 秒,digest 一致;
|
||||
- hosted push/pull 成功,匿名 pull 返回 401;
|
||||
- amd64/arm64 OCI image index 可 push 与 inspect;
|
||||
- Helm OCI chart push/pull digest 及本地 tarball SHA-256 一致;
|
||||
- Cosign 签名和公钥验证成功,OCI 1.1 referrers 返回一个 Sigstore bundle;
|
||||
- BuildKit `mode=max` registry cache 成功导出;销毁首个 builder 后,新 builder 从 Nexus
|
||||
导入缓存,两个 `RUN` step 均命中 `CACHED`。
|
||||
|
||||
## POC 限制
|
||||
|
||||
- 单副本、50 GiB OpenEBS RWO PVC,资源上限 2 CPU / 4 GiB。
|
||||
- 当前使用 embedded H2,仅用于 POC;正式保存唯一制品前迁移至外部 PostgreSQL。
|
||||
- 当前没有独立备份或恢复验收,PVC 不能被视为备份。
|
||||
- Terraform provider 管理 Ansible/Go、Realm 与权限;provider 1.17.0 尚未暴露 Nexus 3.94
|
||||
新增的原生 OCI repository resource,因此 OCI 仓库由实例 Swagger 固定 schema 的幂等 REST
|
||||
调和器管理,不通过 UI 留下非声明式配置。
|
||||
- 尚未创建正式 publisher service account;本轮写入测试临时使用受管管理员凭据。
|
||||
|
||||
## 出问题时
|
||||
|
||||
先检查 Flux、Pod、PVC、Route 与最近日志:
|
||||
|
||||
```bash
|
||||
kubectl -n flux-system get kustomization nexus
|
||||
kubectl -n nexus get pod,pvc,service,httproute
|
||||
kubectl -n nexus logs deployment/nexus --tail=100
|
||||
```
|
||||
|
||||
首次启动可能持续数分钟。PVC 未 Bound 时先查 OpenEBS;Route 未 Accepted/ResolvedRefs 时查
|
||||
Gateway parentRef 与 Service;公网依赖获取失败时区分 Nexus 本身、LAN DNS 和已知不稳定
|
||||
WAN,不以重建 PVC 作为排障手段。
|
||||
|
||||
## 运维入口
|
||||
|
||||
实现入口为 homelab-infra 已合并的 `apps/nexus/` 与
|
||||
`clusters/homelab/apps/nexus.yaml`。DNS 记录位于 `infrastructure/dns/records.yml`。
|
||||
源码 README 维护部署、初始化、Terraform、验收与恢复边界。
|
||||
|
||||
部署依赖 Envoy Gateway、OpenEBS 和 LAN DNS;Terraform 管理依赖 Nexus 初始化后的受限管理
|
||||
账号及 OpenBao 注入凭据。现阶段不依赖共享 PostgreSQL,正式化时才建立独立数据库与 role。
|
||||
|
||||
## 当前状态与证据
|
||||
|
||||
2026-09-20 现场确认 Flux Kustomization Ready、Nexus Pod Ready、50 GiB PVC Bound,HTTPRoute
|
||||
经 HTTPS 状态 API 返回 200;Samba DNS apply 后复查 `changed=0`。Terraform 已创建 Ansible、
|
||||
Go proxy/group、OCI Bearer Token Realm 和最小匿名只读角色,二次 plan 为 `No changes`;OCI
|
||||
REST 调和器复查三个仓库均为 `in sync`。Ansible、Go、OCI、Helm、Cosign/referrers 与
|
||||
BuildKit cache 的上述客户端测试均成功。实现来源为 homelab-infra PR #103、#108 与 #109。
|
||||
尚未验证备份恢复或外部 PostgreSQL,也未创建正式 publisher account、修改或迁移 zot,
|
||||
因此本页的 `live-verified` 仅覆盖已明确列出的 POC 范围。
|
||||
@@ -2,7 +2,7 @@
|
||||
title: PostgreSQL Tenant Operator(计划中的 DBaaS)
|
||||
lifecycle: planned
|
||||
evidence: documented
|
||||
last_reviewed: 2026-09-16
|
||||
last_reviewed: 2026-09-25
|
||||
last_verified: null
|
||||
sources:
|
||||
- https://git.ddupan.top/panxiao81/postgresql-tenant-operator
|
||||
@@ -26,16 +26,119 @@ homelab 资源有限,为每个应用维护一套数据库会浪费资源。绝
|
||||
|
||||
## 当前进度
|
||||
|
||||
2026-09-16 查阅[项目 README](https://git.ddupan.top/panxiao81/postgresql-tenant-operator/src/branch/main/README.md)
|
||||
与架构文档时,项目记录为 **API 骨架阶段,尚未对 PostgreSQL 或 OpenBao 执行写操作**。
|
||||
已批准的设计合同不等于已经实现的功能,本文不表示 DBaaS 已上线。
|
||||
项目首页还注明 `config/samples` 保留旧 API 骨架,不能将其直接当作最终使用接口。
|
||||
维护者于 2026-09-20 提供的阶段状态如下:
|
||||
|
||||
- 已合并 Instance 的 Endpoint、凭据引用、身份/版本、定义与观测目标等值对象;
|
||||
- 已合并扩展支持能力模型,以及 Instance 最小生命周期与状态 checkpoint;
|
||||
- CI PR #14 已合并:lint/test 使用 Pod runner,e2e 使用 VM runner;当前没有开放 PR;
|
||||
- 上述领域基础尚未接入实际运行链路,不能理解为新设计已经可用;
|
||||
- 仍缺完整 Ready 判定、Kubernetes Secret 管理凭据与连接刷新、应用层/数据库 adapter/controller
|
||||
接入、CRD 与批准规格对齐及集成验证;
|
||||
- Tenant 的完整创建、凭据交付和 Retain/Delete 生命周期仍未完成;
|
||||
- 旧运行链路仍包含直接读取 OpenBao 管理凭据的逻辑。
|
||||
|
||||
本地暂停在 `feature/instance-extension-observations`,有两个未提交文件,实现 Instance 接收扩展
|
||||
观测及其测试。该部分此前只通过领域包 lint,未运行本地测试、未提交、未推送;分支仍基于 #13,
|
||||
未包含刚合并的 CI 改动。该工作区必须原样保留,不能作为已合并能力或迁移来源。
|
||||
|
||||
已批准的设计合同不等于已经实现的功能,本文不表示 DBaaS 已上线。生成的 CRD/API 与 samples
|
||||
仍可能落后于批准规格,不能直接作为最终使用接口。
|
||||
|
||||
2026-09-20,维护者决定将该项目合并为 Ayatori 的 Database 领域模块。已批准的规格、领域模型、
|
||||
状态机和测试继续作为迁移合同;不会把独立仓库的 manager、生成文件和当前工作树整仓复制。
|
||||
首个迁移基线使用包含已合并 Instance 领域基础与 CI #14 的最新 main commit,再按领域层、API、
|
||||
adapter 和 controller 的纵向切片进入 Ayatori;暂停中的两个未提交文件不进入首个切片。旧仓库
|
||||
在迁移完成并验收前仍是现有设计与代码的来源,本决定不表示 DBaaS 已上线。
|
||||
|
||||
维护者同时确认目前没有可用版本,也没有 PostgreSQL 实例或 Tenant 被该 operator 托管。因此
|
||||
合并不承担旧运行链路、旧 CRD/status 或数据的兼容责任:直接读取 OpenBao 管理凭据的旧路径可以
|
||||
删除,未投入使用且落后于规范的 CRD/samples/实现结构不保留兼容层。
|
||||
|
||||
2026-09-20 的迁移决定原要求整体沿用源设计。2026-09-24,维护者明确批准下述资源/申请
|
||||
分离修订,替代 registry、自动所有权恢复与原 Retain 合同;管理凭据、TLS、OpenBao/ESO 和
|
||||
其他适用安全边界继续保留。这是显式设计修订,不是已完成运行验证。
|
||||
|
||||
原 `database.ddupan.top/v1alpha1` API group 也不保留。Ayatori 中的目标 API 使用
|
||||
`database.ayatori.ddupan.top/v1alpha1`,并纳入统一的 `api/database/v1alpha1` 与 Database 模块
|
||||
结构;由于不存在已部署消费者,不建立 alias 或 conversion 入口。
|
||||
|
||||
合并边界记录在 Ayatori PR
|
||||
[#3 的 ADR-0008](https://git.ddupan.top/panxiao81/ayatori/src/commit/33fb3ec9725dca8a10f2ad4bcd71cf83413932ee/docs/decisions/0008-merge-postgresql-tenant-operator.md);
|
||||
该决定已于 2026-09-21 合并 main,链接固定到合并版本;设计合并不表示 Database 实现已完成。
|
||||
|
||||
## 当前资源模型(2026-09-24 已确认)
|
||||
|
||||
参考 [Kubernetes 官方 PV/PVC](https://kubernetes.io/docs/concepts/storage/persistent-volumes/) 的
|
||||
资源/申请分离:Instance 是资源来源与管理入口;独立 Database 类似 PV;Tenant 是类似 PVC
|
||||
的用户申请。Instance 一对多 Database,每个 Database 同时最多绑定一个 Tenant。
|
||||
|
||||
Database 自带 instanceRef,手工登记不依赖 Tenant;动态申请由 Tenant 选择 Instance,
|
||||
引用已有 Database 时从资源获取 Instance,不重复声明另一份来源。
|
||||
|
||||
Retain 在申请删除后保留 Database 对象和外部数据,进入 Released,等待管理员处理数据、
|
||||
旧访问权限和凭据后显式授权重新绑定。已有数据库可由管理员显式登记导入,初始验证不改密、
|
||||
不改 owner;发现未知同名资源仍报 Conflict。回收策略位于资源侧,Database 不随 Tenant GC。
|
||||
|
||||
撤销 PostgreSQL ownership registry 和任意 status 丢失自动重建所有权的要求。CR 记录持久
|
||||
身份、绑定和进度;普通失败幂等重试,无法确认外部创建结果时报告足够人工诊断的冲突。
|
||||
不引入 CSI 协议、存储调度或通用 Claim。绑定字段和凭据重新交付协议仍需细化。
|
||||
|
||||
2026-09-25,维护者确认第一版 Database 的生命周期边界包含一个数据库、一个兼任 owner
|
||||
的登录账号及其应用凭据;Tenant 负责申请与交付。不预留多账号字段或新增 Role/Credential
|
||||
CRD;一库多账号若有实际需求,再通过后续 API 版本演进。此决定不扩大导入管理授权。
|
||||
同日确认 Instance 与 Database 为 cluster-scoped,Tenant 为 namespaced。Database 由平台
|
||||
管理员管理,不属于应用 namespace,也不需要资源专用 namespace。Tenant 按名称引用
|
||||
Database,资源侧绑定记录包含 Tenant namespace/name/UID;普通申请者不能自行修改回收
|
||||
策略或将 Released 资源重新开放。具体字段与 RBAC 规则仍待细化。
|
||||
|
||||
绑定采用资源侧先写:动态 Database 名称由 Tenant UID 确定;先写 Database 的 Tenant
|
||||
namespace/name/UID,再写 Tenant status 的 Database name/UID,双向一致后才供应或交付。
|
||||
API 版本冲突重新读取判断,已被其他 Tenant 占用则报冲突;资源侧成功、申请侧失败由
|
||||
reconcile 核对身份后补齐,不回滚资源侧绑定。绑定不等于 Ready;外部数据库创建结果
|
||||
不确定仍交给人工处理,不增加事务队列或 registry。该顺序由维护者于同日确认。
|
||||
|
||||
同日进一步明确:不增加允许绑定名单或逐 Tenant 审批,有权创建 Tenant 的申请者可显式
|
||||
申请未绑定且可用的 Database;Released 仍需管理员处理旧访问后重新开放。
|
||||
回收策略默认 Retain,资源管理者可在删除流程开始前修改;进入删除流程后固定,指定
|
||||
Delete 即为删除授权,不加第二次审批。动态凭据路径按 Database UID 确定,导入显式关联
|
||||
已有凭据位置;Released 不自动改密,重新开放前由管理员处理旧访问。
|
||||
对应 Ayatori `docs/database/specification.md`、`domain-model.md` 与 `api-reference.md`
|
||||
已推送为 [7e9e8e8](https://git.ddupan.top/panxiao81/ayatori/commit/7e9e8e828bfcbdc8d4e2fcb6bc3d13727712a82c),
|
||||
已随 [Ayatori PR #10](https://git.ddupan.top/panxiao81/ayatori/pulls/10) 通过三项 CI 并合并 main,
|
||||
合并版本为 [55b269c](https://git.ddupan.top/panxiao81/ayatori/commit/55b269ce2eb40f6b44c1afe838389093efdac98e)。
|
||||
|
||||
Ayatori main 已加入三资源 Go 类型、生成 CRD、Scheme 注册与 YAML 示例,尚未部署为业务服务。
|
||||
`make test` 使用真实 API server 验证作用域、默认值、声明
|
||||
校验、status 隔离、绑定写入版本冲突与示例。绑定 controller 已接入 manager:动态资源按
|
||||
Tenant UID 命名,先写资源侧绑定,再回读补齐 Tenant status;进入 Binding 后固定申请目标,
|
||||
拒绝 Released、旧 UID 和陈旧 Ready 观察。真实 API server 覆盖部分写入故障后新 reconciler
|
||||
补齐、双 Tenant 竞争及实际 manager 在生成 RBAC 角色下的 watch;绑定角色不能读取 Secret。
|
||||
Bound 仍为 Ready=False,尚无供应或凭据投射。已有 finalizer 保护,但删除清理未实现:
|
||||
Tenant 删除保持 DeletionPending,资源和申请的 finalizer 不自动移除,不能视为可用的
|
||||
Retain/Delete 生命周期或部署为业务 DBaaS。具体字段和未完成边界见
|
||||
源码 [API 合同](https://git.ddupan.top/panxiao81/ayatori/src/commit/7e9e8e828bfcbdc8d4e2fcb6bc3d13727712a82c/docs/database/api-reference.md)
|
||||
的“当前 API 切片”。
|
||||
|
||||
绑定代码按维护者要求分层:领域层负责纯规则,application service 协调绑定步骤和回读,
|
||||
Kubernetes adapter 负责 CR 映射、版本保护及 Conditions/status/finalizer 呈现,controller
|
||||
只连接事件、用例与重试。service 和领域层不依赖 Kubernetes 类型,不新增通用事务或
|
||||
Repository 框架;该重构不扩展上述运行能力。对应源码 `docs/database/domain-model.md`
|
||||
已随上述提交保存,见 [领域模型](https://git.ddupan.top/panxiao81/ayatori/src/commit/7e9e8e828bfcbdc8d4e2fcb6bc3d13727712a82c/docs/database/domain-model.md)。
|
||||
|
||||
本轮依据为维护者设计讨论和 Ayatori 已推送的
|
||||
[ADR-0009](https://git.ddupan.top/panxiao81/ayatori/src/commit/6db8a495fb9f8981d336c9e6288253628ab478b6/docs/decisions/0009-database-resource-and-claim.md)、
|
||||
[系统规格](https://git.ddupan.top/panxiao81/ayatori/src/commit/6db8a495fb9f8981d336c9e6288253628ab478b6/docs/database/specification.md)。
|
||||
registry 实现、迁移与 Instance 初始化依赖已在
|
||||
[23a2d81](https://git.ddupan.top/panxiao81/ayatori/commit/23a2d81b5041f8589baab1c234136cd2c701bb06)
|
||||
撤除;本地测试与真实 PostgreSQL/API server 集成验证通过,但新三资源链路尚未完成。
|
||||
上述设计与撤除已随 [PR #9](https://git.ddupan.top/panxiao81/ayatori/pulls/9) 合并 main,
|
||||
合并版本为 `347a667`;不表示三资源链路已实现或部署。见 [同步记录](../verification.md#ayatori-database-设计修订同步)。
|
||||
|
||||
## 计划中的使用方式
|
||||
|
||||
1. 平台管理员通过 `PostgreSQLInstance` 注册已有 PostgreSQL 实例及管理连接。
|
||||
2. 下游以 namespaced `PostgreSQLTenant` 声明所需 database、login owner 和扩展。
|
||||
3. controller 校验所有权与冲突,幂等创建凭据、role、database 和授权等资源。
|
||||
2. 下游以 namespaced `PostgreSQLTenant` 申请数据库,或显式引用管理员登记的 Database。
|
||||
3. controller 建立独立 Database 记录与排他绑定,供应或验证资源;未知同名及不确定创建报冲突。
|
||||
4. 应用凭据以 OpenBao KV 为事实来源,由 ESO 投射为 Kubernetes Secret。
|
||||
非 Kubernetes 消费者使用提供的 OpenBao API URL,并通过自身授权获取凭据。
|
||||
5. ESO 投射成功且应用凭据实际登录成功后,Tenant 才能进入 Ready。
|
||||
@@ -45,9 +148,30 @@ GitOps、Terraform、kubectl 和未来 Backstage 计划共用这套 Kubernetes A
|
||||
|
||||
## 职责边界
|
||||
|
||||
2026-09-25 维护者确认第一版 PostgreSQL 管理账号使用原生非 superuser 方案,具有
|
||||
CREATEDB/CREATEROLE,不引入 SECURITY DEFINER 接口。扩展安装按实际权限逐请求验证,
|
||||
可用列表不等于任意扩展均可安装;基础管理能力不授予导入或接管他人资源的权限。
|
||||
这项决定沿用原安全文档的非 superuser 原则,并明确了此前未选定的实施方式。
|
||||
Instance 观测、Secret watch 与删除引用保护已在 CI 通过后,经维护者批准合并
|
||||
[PR #11](https://git.ddupan.top/panxiao81/ayatori/pulls/11),main 合并提交为
|
||||
[f4deb98](https://git.ddupan.top/panxiao81/ayatori/commit/f4deb98a7fcf61fb97ce52bbf190beb816d0141a)。
|
||||
权限矩阵、启用方式和测试边界以该提交的
|
||||
[模块说明](https://git.ddupan.top/panxiao81/ayatori/src/commit/f4deb98a7fcf61fb97ce52bbf190beb816d0141a/docs/database/README.md)
|
||||
与安全文档为准;合并不表示部署或完整供应链路已完成。
|
||||
|
||||
后续应用凭据存储切片已签名提交为
|
||||
[f6bb9e4](https://git.ddupan.top/panxiao81/ayatori/commit/f6bb9e4599afca49a9cdc3d40789e11d118db9c5),
|
||||
由 [PR #12](https://git.ddupan.top/panxiao81/ayatori/pulls/12) 跟踪,尚未合并。
|
||||
复用 OpenBao 官方 Go SDK 的 KV v2 CAS=0、回读七键与版本,禁止覆盖
|
||||
或自动认领;明确权限拒绝等待依赖恢复,写入结果不确定则停止并人工处理。本地真实
|
||||
OpenBao 测试已覆盖并发、软删除、固定前缀权限和响应丢失,尚未接入 manager、Kubernetes
|
||||
auth、Database 供应或 ESO。源码模块文档与 wiki 已关联,见
|
||||
[同步记录](../verification.md)。
|
||||
|
||||
- operator 管理实例内的租户资源,不运行 PostgreSQL/OpenBao,也不管理 VM、存储、备份或 OpenBao PKI。
|
||||
- 应用密码写入 OpenBao,不进入 CR、Event 或日志;ESO 负责向 Kubernetes 消费者投射。
|
||||
- 默认删除策略为 `Retain`,删除声明不会默认删除业务数据;显式 `Delete` 需重新校验所有权。
|
||||
- Database 默认 Retain;删除 Tenant 保留资源对象与数据,Released 不自动重新分配。
|
||||
- 资源侧 Delete 需明确授权、finalizer 与实际管理范围检查,导入不隐含删除或改密授权。
|
||||
- 遇到未知 database/role 等资源报告 Conflict,不能自动接管、覆盖或删除;现有数据库迁移需遵循迁移合同。
|
||||
- namespace 是 Kubernetes 身份与 RBAC 边界;database/role 名称在一个 PostgreSQL Instance 内仍全局唯一。
|
||||
|
||||
@@ -63,5 +187,6 @@ GitOps、Terraform、kubectl 和未来 Backstage 计划共用这套 Kubernetes A
|
||||
- [部署](https://git.ddupan.top/panxiao81/postgresql-tenant-operator/src/branch/main/docs/deployment.md)与[安全](https://git.ddupan.top/panxiao81/postgresql-tenant-operator/src/branch/main/docs/security.md):依赖和权限。
|
||||
- [迁移](https://git.ddupan.top/panxiao81/postgresql-tenant-operator/src/branch/main/docs/migration.md)与[运维](https://git.ddupan.top/panxiao81/postgresql-tenant-operator/src/branch/main/docs/operations.md):现有数据库、删除和恢复合同。
|
||||
|
||||
具体实现进度回到[项目仓库](https://git.ddupan.top/panxiao81/postgresql-tenant-operator)查询,
|
||||
后续查询前先向维护者对齐当前工作与 ticket。本页保留设计定位和带日期的阶段摘要。
|
||||
迁移前的具体实现进度仍回到[项目仓库](https://git.ddupan.top/panxiao81/postgresql-tenant-operator)
|
||||
查询;迁移后的实现与发布进度转到 Ayatori。后续查询前先向维护者对齐当前工作与 ticket。
|
||||
本页保留设计定位和带日期的阶段摘要。
|
||||
|
||||
+58
-3
@@ -2,15 +2,16 @@
|
||||
title: Proxmox 日常管理入口
|
||||
lifecycle: active
|
||||
evidence: documented
|
||||
last_reviewed: 2026-09-16
|
||||
last_verified: null
|
||||
last_reviewed: 2026-09-25
|
||||
last_verified: 2026-09-25
|
||||
---
|
||||
|
||||
# Proxmox
|
||||
|
||||
Proxmox 承载 VM/LXC 与相应主机、网络和存储资源。
|
||||
本页依据 homelab-infra 工作区 `infrastructure/proxmox/README.md`、`README-ha.md`
|
||||
及已有 DNS 名称整理使用入口,不检查集群成员、VM、HA 或存储现场状态。
|
||||
及已有 DNS 名称整理使用入口;初轮未检查集群成员、VM、HA 或存储现场状态。
|
||||
2026-09-25 的有限现场验证仅覆盖下文 sandbox 存储恢复与 LB 链路,不代表整套 PVE/HA 验收。
|
||||
源码 README 尚未跟踪,HA 文档有工作区修改;配置已进一步核对 `auth.yml`、`site.yml`、
|
||||
`ha.yml` 与对应 role defaults,不将文档中的历史阶段备注当作当前配置。
|
||||
|
||||
@@ -76,3 +77,57 @@ PVE 主机存储、DRBD 副本和 k3s 的 [OpenEBS](openebs.md) 是不同管理
|
||||
长期配置入口为 `infrastructure/proxmox/ansible/`,并按实际变更选择对应 playbook。
|
||||
|
||||
来源文件的固定版本与工作区差异见[来源追溯](../sources.md#proxmox)。
|
||||
|
||||
|
||||
## Sandbox LB 与根文件系统恢复
|
||||
|
||||
Sandbox 的 VyOS 入口为 PostgreSQL `10.60.0.1:5432`、K3s API
|
||||
`10.60.0.13:6443`、OpenSandbox `10.60.0.13:8080`。数据库只转发到
|
||||
sandbox1 `10.60.0.11:5432`;K3s 转发到两个节点的 `6443`;OpenSandbox
|
||||
转发到两个节点的 `30080`。OpenSandbox `/health` 返回 200 不代表 K3s 控制面可用。
|
||||
配置依据为源码 `infrastructure/sandbox-cluster/README.md`、
|
||||
`infrastructure/proxmox/ansible/roles/vyos_router/` 及本轮 VyOS 现场检查;
|
||||
OpenSandbox 的 LB 条目在现场存在,不能推断旧 Ansible 模板已经管理该条目。
|
||||
|
||||
排障先检查 HAProxy 监听和每个 backend 的状态,再直连后端。若后端拒绝连接,
|
||||
检查 PostgreSQL、K3s 与根文件系统,而不是仅重启 LB。
|
||||
`findmnt -no SOURCE,FSTYPE,OPTIONS /` 即使显示 `rw`,同时出现
|
||||
`emergency_ro` 也不能视为正常可写。
|
||||
|
||||
DRBD 对端失联导致 quorum 丢失时,`on-no-quorum=io-error` 会向文件系统返回
|
||||
I/O 错误;ext4 可能中止 journal 并进入只读。DRBD 后来恢复 UpToDate/quorum
|
||||
并不会自动解除文件系统的故障状态。检查宿主日志时用 `journalctl --utc`,
|
||||
不要直接把宿主本地时间与 guest 的 UTC 时间比较。
|
||||
|
||||
在已获停机恢复授权后,按以下顺序处理:
|
||||
|
||||
1. 用 `pct config <VMID>`、`pvesm path <rootfs-volume>` 和 `drbdsetup status <resource> --verbose`
|
||||
核对容器、卷和副本关系。确认链路稳定、quorum 正常、数据副本 UpToDate,且没有其他节点挂载该卷。
|
||||
2. 正常关闭故障容器,确认 stopped、卷未挂载且无遗留占用。禁止在运行中的根盘执行 fsck。
|
||||
3. 执行 `pct fsck <VMID> --device rootfs --force 1`。本机 PVE 使用 `fsck -a -l -f`;
|
||||
底层返回 1 表示已修复,PVE 仍可能把它显示为命令失败。必须核对完整输出,不能把其他错误码当成功。
|
||||
4. 对同一已停机、未挂载卷执行 `e2fsck -fn <verified-device>`;返回 0 后再启动容器。
|
||||
若自动安全修复未通过,暂停并评估数据恢复,不盲目加 `-y`、清空 WAL 或重建数据库。
|
||||
5. 等待 PostgreSQL 完成 crash recovery;验证主库 `pg_is_in_recovery()=false`、
|
||||
standby 保持 recovery、`pg_stat_replication` 为 streaming/sync,检查 replay lag。
|
||||
不把普通 TCP check 当成数据库可写性证明,也不自动提升 standby。
|
||||
6. 检查两个 K3s 服务、两个直连 API 和 VIP 的 `/readyz`、节点与 Pod Ready。
|
||||
数据库已恢复而某个 K3s 长期停在 activating 时,核对日志与进程;必要时只重启该 K3s 服务。
|
||||
7. 从 VyOS 再核对每个 backend 为 UP,并验证 OpenSandbox `/health`。
|
||||
|
||||
2026-09-25 现场验证范围:sandbox1 根盘离线修复和只读复检通过,重新挂载不再有
|
||||
`emergency_ro`;数据库恢复同步复制,采样 replay lag 为 0;两个 API 与 VIP 的
|
||||
`/readyz` 均为 ok,两个节点及全部 Pod Ready。故障证据为目标 DRBD 对端 PingAck
|
||||
超时、quorum 丢失及紧随其后的 ext4 写入错误;对端连接超时的上游原因尚未确定。
|
||||
本轮未修改 VyOS LB、DRBD quorum 策略或集群网络。此处保存恢复方法及有限验证边界,
|
||||
不代表已经消除存储网络复发风险。
|
||||
|
||||
|
||||
本次进一步复盘将触发线索收敛为:新 PG HDD 数据卷在 17:12 开始的初始同步发生重叠,
|
||||
随后多个既有 DRBD 资源失去 quorum;15:30–15:32 的 etcd rootfs 迁移与后来的新数据卷创建
|
||||
应分开记录。资源争用的具体瓶颈尚未实证。容器 `serial: 1` 和 etcd health 不等于 DRBD
|
||||
同步完成;新卷维护需在创建前建立同步预算,并在允许下一卷前等待所有必要副本同步。
|
||||
目前 PG 创建流程虽已在创建后加限速,仍存在初始未限速窗口,尚未补齐同步完成屏障。
|
||||
|
||||
事故报告由 wiki 统一维护:[2026-09-25 DRBD quorum 抖动与 sandbox 控制面中断](../incidents/2026-09-25-drbd-quorum-sandbox.md)。
|
||||
其中保存统一 UTC 时间线、跨资源影响边界、相关操作会话和后续验收条件;本页保留可复用恢复方法。
|
||||
|
||||
+12
-3
@@ -2,11 +2,12 @@
|
||||
title: SPIFFE/SPIRE 使用入口与阶段状态
|
||||
lifecycle: active
|
||||
evidence: documented
|
||||
last_reviewed: 2026-09-16
|
||||
last_reviewed: 2026-09-21
|
||||
last_verified: null
|
||||
sources:
|
||||
- https://git.ddupan.top/panxiao81/homelab-infra/issues/34
|
||||
- https://git.ddupan.top/panxiao81/homelab-infra/src/branch/main/platform/spire/RUNBOOK.md
|
||||
- https://git.ddupan.top/panxiao81/ci-actions/src/tag/v1/spiffe-openbao-login
|
||||
---
|
||||
|
||||
# SPIFFE/SPIRE
|
||||
@@ -55,7 +56,7 @@ SPIFFE/SPIRE 取代了原计划中由 **workload-sts 承担统一 IAM 平台**
|
||||
维护者指定以 [homelab-infra #34](https://git.ddupan.top/panxiao81/homelab-infra/issues/34)
|
||||
为主要状态依据。2026-09-16 查阅时 issue 为 open,最后更新时间为
|
||||
2026-09-14 12:43:54 UTC;本页是该次查阅的阶段摘要,不替代 ticket 的动态进度。
|
||||
本轮没有访问运行环境,以下完成结论均为 ticket 记录。
|
||||
基础设施阶段结论来自 ticket;2026-09-21 另对下表中的可复用 Action 做了现场验证。
|
||||
|
||||
| 已完成阶段 | 记录依据 |
|
||||
|---|---|
|
||||
@@ -63,6 +64,7 @@ SPIFFE/SPIRE 取代了原计划中由 **workload-sts 承担统一 IAM 平台**
|
||||
| OIDC HTTPS、DNS、TLS、discovery/JWKS 验证;OpenBao JWT backend/role/policy 创建 | [9 月 14 日端到端验收](https://git.ddupan.top/panxiao81/homelab-infra/issues/34#issuecomment-301),对应 #52、#53 |
|
||||
| 测试 Pod 获得 aud=openbao 的 JWT-SVID,交换为仅含 spire-poc policy、TTL 300 秒的 Bao token;lookup-self/revoke-self 验证完成 | 同上;临时 workload 与 registration entries 已清理,最终 Terraform plan 为 No changes |
|
||||
| 新 workload 接入、故障排查和恢复说明已合并 | [9 月 14 日文档记录](https://git.ddupan.top/panxiao81/homelab-infra/issues/34#issuecomment-308),对应 #54 |
|
||||
| `spiffe-openbao-login@v1` 使用本机 Workload API 获取 JWT-SVID、交换短期 token 并在 post 阶段 `revoke-self` | 2026-09-21 现场验证;Action 未向 stdout/stderr 输出 JWT-SVID 或 token |
|
||||
|
||||
## 如何使用
|
||||
|
||||
@@ -82,6 +84,13 @@ SPIFFE/SPIRE 取代了原计划中由 **workload-sts 承担统一 IAM 平台**
|
||||
[Dynamic Runner](gitea-dynamic-runner.md) 提供 Pod/VM 执行环境及获取自身 SPIFFE 身份的能力,
|
||||
不将 OpenBao 或其他服务的业务登录流程内置为 runner 职责。
|
||||
|
||||
Gitea workflow 可使用
|
||||
[`panxiao81/ci-actions/spiffe-openbao-login@v1`](https://git.ddupan.top/panxiao81/ci-actions/src/tag/v1/spiffe-openbao-login)
|
||||
完成 JWT-SVID 交换与退出吊销。Action 会按 Actions 协议把短期 token 写入
|
||||
`GITHUB_ENV`/`GITHUB_STATE` 临时文件,因此只允许用于 job 后销毁的一次性 Pod/VM
|
||||
runner;不能用于共享或持久 runner。runner 仍只提供 Node.js 20、`spire-agent` 和
|
||||
Workload API socket,role、audience 与调用时机必须由受审查的 workflow 声明。
|
||||
|
||||
可直接沿用的配置模板、交换示例和排障步骤见
|
||||
[权威 RUNBOOK](https://git.ddupan.top/panxiao81/homelab-infra/src/branch/main/platform/spire/RUNBOOK.md)
|
||||
的第 4–8 节。这里不复制第二份操作脚本。接入需要新增身份和授权配置,不是挂载 socket 后
|
||||
@@ -94,7 +103,7 @@ OIDC issuer 为 `https://spire-oidc.ad.ddupan.top`,其 discovery/JWKS 用于
|
||||
|
||||
## 仍在 ticket 中跟踪
|
||||
|
||||
截至本次查阅,后续范围包括真实 Gitea CI/AI Agent 的 OpenBao 接入、credential-exec、
|
||||
截至本次查阅,后续范围包括在真实 Gitea CI/AI Agent 中验收已发布的登录 Action、
|
||||
SeaweedFS Web Identity/STS、非 Kubernetes 主机与临时 VM 的证明和回收、
|
||||
Compute/DBaaS 消费身份,以及 HA、备份恢复和多 issuer 约定。
|
||||
这些是 #34 的开放范围;单个消费者已有其他 PoC,不等于整项已完成。
|
||||
|
||||
@@ -63,3 +63,64 @@ SPIFFE/SPIRE 按维护者指定,以 [#34](https://git.ddupan.top/panxiao81/hom
|
||||
- Backstage 为计划中的统一入口,不作为已部署服务记录。
|
||||
|
||||
后续出现新的状态问题时,先向维护者对齐,再按授权范围更新对应服务文档。
|
||||
|
||||
## Ayatori Database 设计修订同步
|
||||
|
||||
2026-09-24,维护者批准 Instance → Database → Tenant 资源/申请分离,替代原 PostgreSQL
|
||||
registry 与自动所有权恢复合同。源仓库设计和 wiki 已同步,Ayatori 设计与 registry 撤除
|
||||
已推送到 `feat/database-registry-inspection`;本记录随 wiki 来源同步提交发布。
|
||||
registry 撤除通过本地全量测试、lint 及真实 API server/PostgreSQL 集成测试;
|
||||
新资源 API 与三资源运行链路未完成,不属于部署或现场验证。
|
||||
|
||||
源设计:[6db8a49](https://git.ddupan.top/panxiao81/ayatori/commit/6db8a495fb9f8981d336c9e6288253628ab478b6);
|
||||
代码撤除:[23a2d81](https://git.ddupan.top/panxiao81/ayatori/commit/23a2d81b5041f8589baab1c234136cd2c701bb06);
|
||||
wiki 权威摘要:[DBaaS 设计](services/postgresql-tenant-operator.md#当前资源模型2026-09-24-已确认)。
|
||||
来源链接固定到实现提交;相关设计、registry 撤除与 CI 去重修复已随
|
||||
[PR #9](https://git.ddupan.top/panxiao81/ayatori/pulls/9) 合并为
|
||||
[347a667](https://git.ddupan.top/panxiao81/ayatori/commit/347a667c0c1737bc4e2703dec5f11358f0425e43)。
|
||||
最新 head 的 CI #781 已全部通过;无日志启动失败的 test 单项重试后通过。
|
||||
旧仓库固定基线及受保护工作树未修改。
|
||||
|
||||
2026-09-25 的单数据库、单登录 owner 与凭据生命周期边界,以及 Database 集群级作用域、
|
||||
引用与管理权限边界、资源侧先写的绑定顺序与部分写入重试规则,以及无绑定名单、
|
||||
删除前策略可改与 Database UID 凭据定位的决定已同步到
|
||||
[DBaaS 设计](services/postgresql-tenant-operator.md#当前资源模型2026-09-24-已确认)。
|
||||
依据维护者当日确认;Ayatori 已提交为 `7e9e8e828bfcbdc8d4e2fcb6bc3d13727712a82c`,
|
||||
源码已通过 [Ayatori PR #10](https://git.ddupan.top/panxiao81/ayatori/pulls/10) 的三项 CI,
|
||||
并于同日按维护者要求合并为
|
||||
[55b269c](https://git.ddupan.top/panxiao81/ayatori/commit/55b269ce2eb40f6b44c1afe838389093efdac98e)。
|
||||
wiki 按维护者要求直接合入 main,原 [wiki PR #3](https://git.ddupan.top/panxiao81/homelab-wiki/pulls/3)
|
||||
保留为历史讨论入口;后续纯文档变更不另开 PR。
|
||||
关联源码:[7e9e8e8](https://git.ddupan.top/panxiao81/ayatori/commit/7e9e8e828bfcbdc8d4e2fcb6bc3d13727712a82c)。
|
||||
这只是第一版 API 范围确认,不表示新资源链路已实现。
|
||||
|
||||
上述已合并实现包含三资源 schema 与真实 API server 校验,
|
||||
本地 `make test` 与远端 CI 均通过。已接入绑定
|
||||
controller、目标固定、finalizer 保留与生成 RBAC,真实 API server 验证并发、补写及 watch。
|
||||
尚未实现 finalizer 清理、供应与交付,不宣称完成三资源生命周期或现场验收。
|
||||
|
||||
同日确认原生非 superuser + CREATEDB/CREATEROLE 管理方案,已同步至
|
||||
[DBaaS 职责边界](services/postgresql-tenant-operator.md#职责边界)。Instance 观测链路的实现提交
|
||||
[bc227bf](https://git.ddupan.top/panxiao81/ayatori/commit/bc227bfdb4b2f5b027fe522b8dcf72db17b84d26) 本地已通过
|
||||
全量测试、三轮 controller/application race、真实 PostgreSQL/API server 集成测试及普通/integration lint。
|
||||
[PR #11](https://git.ddupan.top/panxiao81/ayatori/pulls/11) 的三项 CI 均通过,维护者批准后已合并为
|
||||
[f4deb98](https://git.ddupan.top/panxiao81/ayatori/commit/f4deb98a7fcf61fb97ce52bbf190beb816d0141a);
|
||||
未部署或进行现场验收。
|
||||
|
||||
后续凭据存储切片已签名提交并推送为
|
||||
[f6bb9e4](https://git.ddupan.top/panxiao81/ayatori/commit/f6bb9e4599afca49a9cdc3d40789e11d118db9c5),
|
||||
由 [PR #12](https://git.ddupan.top/panxiao81/ayatori/pulls/12) 跟踪 CI 与 review。
|
||||
全量测试、真实 PostgreSQL/API server/OpenBao 集成测试及两种 lint 本地通过;源码模块文档
|
||||
和 wiki 已同步实现边界与正式链接。尚未合并或接入供应流程,不把本地验证等同于远端 CI。
|
||||
|
||||
## 2026-09-25 sandbox 存储故障复盘的来源边界
|
||||
|
||||
维护者报告 VyOS 到 sandbox 的 LB 故障并授权恢复。现场确认 LB 配置未在故障当天更改,
|
||||
故障来自 DRBD quorum 丢失后 sandbox1 根卷进入只读;已离线修复并恢复数据库、双 API 与 Pod。
|
||||
后续按维护者给出的 PostgreSQL/Alertmanager 会话核对,发现新 HDD 数据卷初始同步重叠与
|
||||
多个既有资源故障的时间关联,尚未证明具体网络或磁盘瓶颈。长期恢复方法见
|
||||
[Proxmox](services/proxmox.md#sandbox-lb-与根文件系统恢复)。
|
||||
|
||||
事故报告与恢复手册在 wiki 统一维护,见[完整事故报告](incidents/2026-09-25-drbd-quorum-sandbox.md)。
|
||||
取证引用的 etcd/shared-postgresql 源码当时尚未提交,固定版本关联待源码合并后补齐;
|
||||
服务恢复不等于全部整改完成。
|
||||
|
||||
Reference in New Issue
Block a user