Compare commits
55
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
7e4da26f28
|
||
|
|
fc181ef8f6
|
||
|
|
da0d9fff01
|
||
|
|
6f5b813a89
|
||
|
|
d4114caca0 | ||
|
|
2113eac41f | ||
|
|
263a87d931 | ||
|
|
84eff66b00 | ||
|
|
6115c6b24e | ||
|
|
dcf66d33b6
|
||
|
|
44c967917c | ||
|
|
fee5bbccb3
|
||
|
|
7d397ec436 | ||
|
|
4d18efed37
|
||
|
|
217a56f683
|
||
|
|
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),简述问题、最终变化、依据与验证。
|
||||
直接提交也遵循相同的检查与证据规则,不为纯文案修改制造额外审批。
|
||||
按维护者最新约定,后续修改均新建分支并提交 PR,纯文档变更也适用;未经明确指示,
|
||||
不直接推送 main、不自行合并。此约定取代此前纯文档直接推 main 的规则。
|
||||
PR 使用 [.gitea/PULL_REQUEST_TEMPLATE.md](.gitea/PULL_REQUEST_TEMPLATE.md),
|
||||
简述问题、最终变化、依据与验证;不得跳过检查或覆盖其他工作区修改。
|
||||
|
||||
## 本地与 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,24 @@
|
||||
# 架构约束索引
|
||||
|
||||
审阅日期: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 明确、各服务使用指南 |
|
||||
| 新建 etcd 按全 homelab 共享基础设施设计,PostgreSQL 为首个消费者 | 替代 PostgreSQL 专属 DCS 定位,避免每个服务重复部署;三成员及消费者 RBAC 隔离已部署,不迁移现有 k3s datastore | [共享 etcd](../services/shared-etcd.md),维护者于 2026-09-25 明确 |
|
||||
| 服务独立部署,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 +32,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,254 @@
|
||||
---
|
||||
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、持久化及监控,实测资源成本;不能把编译成功等同完整验收。
|
||||
日常迭代以 JVM 测试为准,不再要求每轮 Native 编译;Native 留在阶段性验收时集中验证,
|
||||
新增路径未经过原生测试时须明确记录。
|
||||
|
||||
首轮保持 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 challenge,也不替换现役入口。
|
||||
原型启动、实现与验证见 [iam-login PR #3](https://git.ddupan.top/panxiao81/iam-login/pulls/3)
|
||||
及其浏览器流程文档;AD 接入见
|
||||
[iam-login AD 接入文档(开发分支)](https://git.ddupan.top/panxiao81/iam-login/src/branch/feat/ad-login/docs/ad-login.md)。
|
||||
后续机器 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,49 @@
|
||||
---
|
||||
title: 证书、秘密同步与 GitOps 监控
|
||||
last_reviewed: 2026-09-25
|
||||
---
|
||||
|
||||
# 证书、秘密同步与 GitOps 监控
|
||||
|
||||
采集与规则由 observability Flux Kustomization 管理,以 ServiceMonitor、PodMonitor 和
|
||||
PrometheusRule 声明;VM Operator 转换后交给 vmagent/vmalert。
|
||||
通知和静默入口见 [Grafana](../services/grafana.md#从告警进入-grafana)。
|
||||
|
||||
## 采集与阈值
|
||||
|
||||
| 对象 | 采集 | 告警 |
|
||||
|---|---|---|
|
||||
| cert-manager controller | ServiceMonitor,:9402,job=cert-manager | Certificate Ready=True 的值为 0 持续 15m;到期不足 7 天且至少 1 天 warning 15m;不足 1 天(含已过期)critical 5m |
|
||||
| ESO 三个组件 | PodMonitor,:8080,以各组件名称为 job | ExternalSecret Ready=True 值为 0 持续 10m;ClusterSecretStore 同条件 5m critical |
|
||||
| Flux 四个 controller | PodMonitor,:8080,以 controller 名称为 job | 八个已接入 controller job 各自 down 或整个 job 消失 5m warning |
|
||||
| Flux 六类对象 | KSM 自定义资源状态 gotk_resource_info | 非暂停对象未 Ready 持续 15m;根 Kustomization 状态指标消失 5m |
|
||||
|
||||
controller 存活规则共 8 条,状态与证书规则共 7 条。证书 warning 和 critical 范围互斥。
|
||||
采集使用 honorLabels,证书和 Secret 的 namespace/name 是被观测对象,不能覆盖为 exporter 命名空间。
|
||||
目前只采集 cert-manager controller;webhook/cainjector 继续依赖通用 workload 健康规则。
|
||||
|
||||
Flux 自定义指标覆盖 Kustomization、HelmRelease、GitRepository、HelmRepository、HelmChart、
|
||||
OCIRepository。KSM 只增加这些资源与 CRD 发现所需的 list/watch,保留 Kubernetes collectors。
|
||||
resource_namespace 保存对象命名空间。suspended=true 排除;默认省略 suspend 仍参与判断。
|
||||
OCI 类型 HelmRepository 正常没有 Ready 条件,repository_type=oci 排除;OCIRepository 本身仍检测。
|
||||
不以旧 gotk_reconcile_condition 指标编写规则,也不通过告警自动解除暂停或修改配置。
|
||||
|
||||
## 排障
|
||||
|
||||
- 证书:先查 Certificate conditions,再沿 CertificateRequest、Issuer、Order、Challenge 找原因。
|
||||
本规则只覆盖 cert-manager 管理的证书,不证明实际 HTTPS 入口已经加载新证书。
|
||||
- Secret 同步:查 ExternalSecret/ClusterSecretStore conditions 与 ESO 日志,核对 provider 网络、身份和授权;
|
||||
不输出 Secret 内容。旧的成功副本可能仍可用,但不能据此认为后续轮换可靠。
|
||||
- Flux:按 customresource_kind、resource_namespace、name 定位对象,查 conditions 与依赖。
|
||||
15m 用于容忍正常升级。主动维护使用暂停或有期限的静默,禁止永久屏蔽失败。
|
||||
- 指标缺失:依次看原生监控 CR、转换对象、targets、即时查询和 KSM 的 RBAC/配置日志。
|
||||
up==0 不能发现已移除目标,因此各预期 job 另用 absent 检测;同 job 单副本以外的拓扑缺失仍有盲点。
|
||||
|
||||
实现:[PR #160](https://git.ddupan.top/panxiao81/homelab-infra/pulls/160)、
|
||||
[OCI 例外 #161](https://git.ddupan.top/panxiao81/homelab-infra/pulls/161)。
|
||||
上游依据:[Flux 自定义指标](https://fluxcd.io/flux/monitoring/custom-metrics/)。
|
||||
19 个规则语义测试覆盖暂停、缺省 suspend、OCI 例外、证书级别切换及 ESO 状态零值等。
|
||||
2026-09-25 现场已确认这 8 个 controller target up,4 个证书到期样本、12 个 Ready Secret 状态样本,
|
||||
KSM 已输出 Flux 对象状态。未人为使生产证书过期或中断 Secret 同步;通知链路沿用此前端到端验收。
|
||||
|
||||
最终 Flux 应用版本为 `655ca567baa58767fcb6a0fd45c78c1044c2b95f`,KSM HelmRelease Ready。
|
||||
@@ -0,0 +1,140 @@
|
||||
---
|
||||
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)。
|
||||
|
||||
下面的规模、矩阵和盲点保留初轮盘点基线,不能再当作第一批实施后的现状。
|
||||
第二批已补 [证书、ESO 与 Flux](monitoring-controllers.md) 的 15 条规则,
|
||||
以及 [CNPG、NATS 与 SeaweedFS](monitoring-data-services.md) 的 14 条规则和 12 个新采集目标。
|
||||
OpenBao 已完成受鉴权 telemetry、ServiceMonitor 与采集不可用规则,维护者人工解封后验收通过;
|
||||
并修复快照续期、生成维护前快照及 VM 外副本;随后增加内部健康和独立 node_exporter
|
||||
快照失败/新鲜度/指标缺失告警,详见 [维护 runbook](openbao-monitoring-maintenance.md)。
|
||||
备份独立验收、NATS consumer 维度、外部探测和集群外心跳仍待补齐。
|
||||
|
||||
## 证据和范围
|
||||
|
||||
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,48 @@
|
||||
---
|
||||
title: CNPG、NATS 与 SeaweedFS 监控
|
||||
last_reviewed: 2026-09-25
|
||||
---
|
||||
|
||||
# CNPG、NATS 与 SeaweedFS 监控
|
||||
|
||||
本批仅增加指标采集与 14 条 PrometheusRule 告警,数据库范围按维护者要求限于 CNPG。
|
||||
共享 Patroni PostgreSQL 与 etcd 的变更由对应任务管理。
|
||||
|
||||
## 采集与规则
|
||||
|
||||
| 服务 | 采集与范围 | 告警 |
|
||||
|---|---|---|
|
||||
| CNPG shared-db/shared-postgresql | PodMonitor 抓取已有实例 :9187,job=cnpg | exporter/目标不可用 5m critical;PostgreSQL down 2m critical;SQL 采集错误 5m;连接使用率 >80% 10m;非 idle 事务超过 300s 持续 5m |
|
||||
| NATS | 沿用 job=nats/nats | JetStream 服务端文件或内存容量 >80% 10m;10m 内慢消费者计数增加并持续 5m |
|
||||
| SeaweedFS | ServiceMonitor 仅选择 master/filer/volume 三个服务的 :9327 | 各组件采集不可用 5m critical;volume 可用磁盘 <10% 10m;因磁盘不足限制写入 5m critical;5m 内写失败增加持续 2m |
|
||||
|
||||
CNPG 使用内置 exporter,不新增数据库账号、不改数据库实例配置、不执行业务写入。
|
||||
连接数按 Pod 汇总数据库与用户,再除以同实例 max_connections;长事务排除普通 idle 连接。
|
||||
当前单实例没有复制冗余,不添加必然无法满足的副本告警。本批没有建立或验证备份流程。
|
||||
|
||||
NATS 本批是服务端容量,不能代替 Account、stream 限额与 consumer pending/redelivery 监控。
|
||||
当前 exporter 未输出这些 consumer 维度,后续需明确 exporter 开关与业务阈值再补。
|
||||
慢消费者使用增量,历史累计值不持续触发。
|
||||
|
||||
SeaweedFS 排除 filer-client 的重复发现,组件分别使用 seaweedfs-master/filer/volume job。
|
||||
只把 isDiskSpaceLow 视为这条只读故障,避免满卷轮转或主动只读造成误报。
|
||||
这些指标不证明 S3 请求端到端成功,也不证明副本和异机备份可恢复。
|
||||
|
||||
## 使用与故障定位
|
||||
|
||||
在 [Grafana Explore](https://grafana.ad.ddupan.top/explore) 选择 VictoriaMetrics,可查询:
|
||||
|
||||
```promql
|
||||
cnpg_collector_up{job="cnpg"}
|
||||
```
|
||||
|
||||
预期 CNPG 实例值为 1。告警中的 pod/namespace 对应数据库实例;先看 CNPG Cluster conditions、
|
||||
Pod 日志及 PVC,再查连接池和事务。禁止仅为消除告警盲目提高连接上限或终止业务事务。
|
||||
NATS 先查服务端配额、保留策略和消费者处理能力;不同 Account 的队列必须分别解释。
|
||||
SeaweedFS 先查 volume 文件系统/ZFS 与日志,不能直接删除底层卷文件。
|
||||
通知和临时静默见 [Grafana](../services/grafana.md#从告警进入-grafana)。
|
||||
|
||||
实现:[PR #160](https://git.ddupan.top/panxiao81/homelab-infra/pulls/160)。
|
||||
2026-09-25 现场确认新增 CNPG 与 SeaweedFS 共 4 个 target up,CNPG collector_up=1,
|
||||
SeaweedFS 容量指标有当前样本;NATS 沿用已验证采集。新增规则无评估错误。
|
||||
测试覆盖连接数聚合、磁盘指标 type 标签匹配及慢消费者历史值;未制造生产数据库/磁盘故障。
|
||||
@@ -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 不在本批修复范围。
|
||||
@@ -0,0 +1,264 @@
|
||||
---
|
||||
title: OpenBao 监控接入维护 runbook
|
||||
last_reviewed: 2026-09-25
|
||||
---
|
||||
|
||||
# OpenBao 监控接入维护 runbook
|
||||
|
||||
用于本次 OpenBao 自身指标接入中央监控。2026-09-25 维护者要求现在开始准备维护,
|
||||
先完成顺序和 runbook;本文同时保留执行顺序与最终验收,实际完成范围见下方“本次执行状态”。
|
||||
建议从明确宣布开始计时预留 30 分钟,实际起止记录 UTC,并注明维护者当地时区。
|
||||
|
||||
维护者确认使用人工解封:解封材料保存在 Bao VM,经 GPG 加密,解密私钥由 YubiKey 持有。
|
||||
文件确切位置、封装格式以及是否另有残留明文未核实;agent 不搜索或读取这些材料。
|
||||
解密、PIN/触摸确认和提交 unseal share 由维护者在自己的终端完成。
|
||||
|
||||
## 本次执行状态(2026-09-25)
|
||||
|
||||
维护者已确认 YubiKey 解密可用并明确同意进入重启/人工解封交接。
|
||||
20:34:42 UTC 应用已校验 telemetry 配置并重启,随后维护者完成 unseal。
|
||||
现场确认 initialized=true、sealed=false、health=200、受鉴权 Prometheus metrics=200,
|
||||
cluster_id 与维护前一致,匿名 metrics 仍为 403。
|
||||
|
||||
停机前已更换失效的快照 token,修正每日续期命令为现场支持的 `bao token renew`(不带 -self)。
|
||||
新快照 `openbao-20260925-203149.snap` 为 183334 bytes,VM 外副本保存在管理工作站
|
||||
`/home/panxiao81/.local/state/openbao-maintenance/`,权限 0600,SHA-256 一致。
|
||||
这是配置维护前的备份核验,不等于完成异机灾难恢复演练。
|
||||
快照 service Result=success、timer active;文件只在写入成功后更名,失败不清理旧快照。
|
||||
|
||||
metrics policy/role 已按候选源配置应用:实际 vmagent-main SA 登录与 token 续期成功,
|
||||
无权读取业务 Secret,测试 token 已撤销。随后已将 `vault_policy.metrics` 与
|
||||
`vault_kubernetes_auth_backend_role.metrics` 导入现有 SeaweedFS S3 主远端 state,
|
||||
仅针对这两项的 plan 均为 no-op;这不代表整个 Terraform 配置已经全量 zero-diff。
|
||||
重启后 ClusterSecretStore 和 12 个 ExternalSecret Ready;monitoring/alertmanager-telegram
|
||||
已定向刷新,refreshTime 更新为 20:39:33 UTC,状态 SecretSynced。
|
||||
[PR #162](https://git.ddupan.top/panxiao81/homelab-infra/pulls/162) 已合并,Flux 应用
|
||||
`834f65494195ba5e139e1fc6ee0221fd705b9656`,vmagent 新 Pod 3/3 Ready。
|
||||
Bao Agent 日志确认自动登录成功、token 写入内存卷及首次自动续期成功;up{job="openbao"}=1,
|
||||
已观察连续三次 up=1,当前指标可查询,单次抓取约 636 个样本,OpenBaoMetricsUnavailable 规则已加载,无评估错误。
|
||||
本次未设置维护静默,无需清理 silence;没有撤销维护者自己的登录会话。
|
||||
真实长周期重新登录、快照未来定时运行和独立灾难恢复演练不包含在本次验收内。
|
||||
|
||||
以下保留操作顺序和回滚方法;其中“待执行”描述须结合本节判断,不能重复重启。
|
||||
|
||||
## 内部健康和快照日常监控
|
||||
|
||||
2026-09-25 后续部署未重启 Bao(启动时间仍为 20:34:43 UTC)。真实快照任务
|
||||
Result=success、退出码 0,新快照 194598 bytes;VM 指标报告 success=1、textfile scrape error=0。
|
||||
Flux 已应用 `7137426e8f5c99ca1514c508501e07c2066dd769`;API 和 VM exporter 两类 target 均为 up,
|
||||
快照结果与成功时间已进入 VictoriaMetrics。21:02:27 UTC 六条 OpenBao 规则均 inactive,
|
||||
部署初期缺数据 pending 已解除;全栈 108 条规则无评估错误。Ansible 部署后 check mode 零变更。
|
||||
本次通过 28 个告警语义场景及 4 个快照脚本测试,未通过制造真实故障验证 Telegram。
|
||||
|
||||
[PR #163](https://git.ddupan.top/panxiao81/homelab-infra/pulls/163) 补齐内部健康、健康 gauge 缺失、
|
||||
快照失败、快照超时/无成功记录和快照采集失联五条规则;原有受鉴权采集不可用规则保留。
|
||||
仍由 ServiceMonitor 和 PrometheusRule 声明。内部 active 判定面向当前单节点,扩容为多节点前需修改。
|
||||
|
||||
VM 使用 Ubuntu node_exporter,监听 `192.168.10.8:9100`;没有公共入口,当前 UFW 未启用,
|
||||
LAN 地址绑定不是逐来源 ACL。采集标签为 `job=node-exporter,node=bao1`,复用主机内存和文件系统规则。
|
||||
textfile 目录 `/var/lib/prometheus/node-exporter/` 只由 root 写入,指标不带 token 或快照内容。
|
||||
独立 exporter 在 Bao sealed 或快照 token 失效时仍能报告快照结果。
|
||||
|
||||
每日任务失败会记录 result=0,保留旧的最后成功时间;只有完整快照原子更名后才更新成功时间并清理旧文件。
|
||||
失败持续 5 分钟为 warning,距最后成功超过 36 小时或没有成功指标持续 15 分钟为 critical;
|
||||
exporter 失联、textfile 解析错误、结果指标缺失持续 5 分钟为 warning。
|
||||
本地快照成功不等于已复制到独立故障域,更不等于恢复演练通过。
|
||||
|
||||
部署和回滚使用独立的 `ansible/monitor-openbao.yml`,只处理 exporter、快照脚本和 timer;
|
||||
不改 Bao 服务配置,不轮换 token,不需要再次人工解封。首次部署必须执行一次真实快照建立基线。
|
||||
参数、验证命令与回滚边界见
|
||||
[源码监控运维说明](https://git.ddupan.top/panxiao81/homelab-infra/src/branch/main/infrastructure/openbao/MONITORING.md)。
|
||||
|
||||
|
||||
|
||||
## 目标、分工与影响
|
||||
|
||||
- 执行者:准备配置与采集声明、检查、备份核对、部署、观测和配置回滚。
|
||||
- 维护者:确认 GPG 文件与 YubiKey 可用、人工解封;整个重启及回滚期间保持在线。
|
||||
- 本次只涉及 telemetry、最小权限采集身份与必要采集/告警,不升级 Bao、不改 seal 类型、
|
||||
不重新初始化、不轮换解封密钥,也不恢复 Raft 数据。
|
||||
- 停机或 sealed 期间,秘密读取、动态凭据签发/续租、PKI/ACME 和 Bao 登录不可用。
|
||||
已投射的 Kubernetes Secret 不会因 Bao sealed 自动消失,但 ESO 刷新会失败;
|
||||
不能保证所有依赖应用都无影响,窗口内避免启动依赖新凭据的部署和轮换。
|
||||
- Telegram 使用现有挂载 token,预计仍可发通知;维护前核对,不能把“预计”当作保证。
|
||||
|
||||
## 顺序与交接点
|
||||
|
||||
| 顺序 | 负责方 | 操作和通过条件 |
|
||||
|---|---|---|
|
||||
| 1,停机前 | 执行者 | 核对版本、运行配置来源、seal 状态和受鉴权 metrics;判断是否真的需要重启 |
|
||||
| 2,停机前 | 执行者 | 准备并审查 IaC 差异、采集身份及续期方式、监控 CR 与回滚配置;离线校验通过 |
|
||||
| 3,停机前 | 维护者 | 在自己的终端确认 YubiKey 解密路径可用、所需 share 数量可满足,回复“人工解封已就绪” |
|
||||
| 4,停机前 | 执行者 | 确认独立 VM 登录/控制台、快照与配置备份、依赖基线;所有恢复材料不依赖运行中的 Bao |
|
||||
| 5,T+0 | 双方 | 明确宣布窗口开始,记录时间;只对预期告警设置 30 分钟到期的精确静默 |
|
||||
| 6,T+0~5m | 执行者 | 应用已审查配置;若确需重启,只重启一次,确认进程启动及 sealed 状态后立即交接 |
|
||||
| 7,T+5~10m | 维护者 | YubiKey 解密并人工 unseal,直到 initialized=true、sealed=false;不向 agent 发送 key |
|
||||
| 8,T+10~20m | 执行者 | 验证 Bao 和依赖恢复,再上线/验证受鉴权采集、规则及凭据自动续期/重新登录 |
|
||||
| 9,T+20~30m | 双方 | 满足验收则结束窗口;否则停止扩大变更,按下述回滚/故障分支处理 |
|
||||
|
||||
时间段是预算,不是自动执行信号。维护者没有完成解封准备时,不执行重启。
|
||||
若受鉴权检查表明现有 telemetry 已满足需求,直接完成无需停机的采集接入,不为走流程重启。
|
||||
|
||||
## 1. 停机前检查
|
||||
|
||||
从能够验证 TLS 的客户端检查,无需登录或解封材料:
|
||||
|
||||
```bash
|
||||
export BAO_ADDR=https://bao.ad.ddupan.top:8200
|
||||
bao status -format=json
|
||||
```
|
||||
|
||||
记录 initialized、sealed、seal 类型、threshold、版本和节点身份,不从旧初始化示例推断 threshold=1。
|
||||
`bao status` 在 sealed 时通常返回退出码 2;不能把这个预期状态当作进程崩溃。
|
||||
若已经异常 sealed 或 initialized=false,停止本次常规维护,先定位现有故障,绝不执行 init。
|
||||
|
||||
在 VM 上确认服务状态、实际二进制和配置路径,不输出配置中的秘密:
|
||||
|
||||
```bash
|
||||
sudo systemctl is-active openbao
|
||||
sudo systemctl show openbao -p MainPID -p ExecMainStatus
|
||||
/usr/local/bin/bao version
|
||||
```
|
||||
|
||||
仓库默认配置路径 `/etc/openbao/config.hcl`、数据路径 `/opt/openbao/data`;执行前核对现场。
|
||||
保持一条已建立的 VM 管理会话,并确认断开后仍能通过独立控制台或既有维护身份恢复访问。
|
||||
不要依赖 Bao 在停机期间签发新的 SSH 凭据。
|
||||
|
||||
受鉴权请求 `/v1/sys/metrics?format=prometheus`,只记录 HTTP 状态、格式和必要指标名。
|
||||
此前匿名请求返回 403,只证明访问受限;模板未显式写 telemetry 也不等于运行时禁用了它。
|
||||
鉴权材料只通过受控内存/文件引用传递,不放命令行、Git 或日志。
|
||||
|
||||
## 2. 配置与采集准备
|
||||
|
||||
如确需显式配置,候选最小变更为:
|
||||
|
||||
```hcl
|
||||
telemetry {
|
||||
prometheus_retention_time = "5m"
|
||||
disable_hostname = true
|
||||
}
|
||||
```
|
||||
|
||||
采集间隔规划为 30 秒。以上是待审查片段,需按现场版本校验;已有 telemetry 配置应合并,
|
||||
不要重复添加。保留 TLS、Raft、seal、认证与现有 listener 设置。
|
||||
指标标签和前缀以实际返回为准,不能预先假设所有指标都以 bao_ 开头。
|
||||
|
||||
采集身份限定 `sys/metrics` GET 所需 read 能力,先验证权限和实际请求;不要复用 root token,
|
||||
也不开放匿名 metrics。明确身份取得、自动续期/重新登录与重启恢复方式后,才认为采集准备完成。
|
||||
优先复用现有机器身份机制;若需 agent/proxy,应在窗口前写好最小配置并验证访问边界,
|
||||
不在停机后临时决定长期 token 或新增服务架构。
|
||||
|
||||
监控声明优先 ServiceMonitor/PodMonitor/PrometheusRule;外部 VM 的发现方式应与最终采集架构匹配。
|
||||
HTTPS 使用正确域名/CA,不关闭校验;metrics path 为 `/v1/sys/metrics`,`format=prometheus`
|
||||
放 query params,不能把问号串在 path 里。sealed 期间 metrics 不可用,因此还需独立 health/目标缺失检测,
|
||||
不能仅靠 Bao 内部指标证明 sealed 状态可被发现。
|
||||
|
||||
配置见 [PR #162](https://git.ddupan.top/panxiao81/homelab-infra/pulls/162),已合并部署,状态以本次执行记录为准。
|
||||
使用绑定 monitoring/vmagent-main 的 Kubernetes auth metrics role,由 Bao Agent sidecar 自动登录/续期,
|
||||
token 仅存 Pod 内存卷供 vmagent 只读消费。采集用 ServiceMonitor + 外部 Service/Endpoints;
|
||||
现有 converter 的 Endpoints 发现保留,EndpointSlice 迁移另行处理。
|
||||
role 权限、认证/首次续期与受鉴权 metrics 已验收;未来维护仍须重新核对现场,不只依靠历史记录。
|
||||
使用现场版本支持的配置校验方式,先检查对应命令 help;禁止启动第二个 server 验证同一 Raft 数据目录。
|
||||
现有 Ansible 写配置会通知 restart,不能把正式 apply 当作无停机预演。
|
||||
|
||||
## 3. 回滚材料与维护静默
|
||||
|
||||
- 以 root-only 权限备份实际配置,记录原权限/属主和 checksum;备份留在独立可访问的管理位置。
|
||||
不把完整配置贴到聊天或 wiki。
|
||||
- 使用已有快照流程核对最近成功快照;必要时在停机前生成一次并检查退出状态、文件大小、校验和和副本可访问性。
|
||||
现有来源为 `openbao-snapshot.service` / timer 与 `/usr/local/bin/bao-snapshot.sh`,先核对现场存在再运行。
|
||||
不打印 snapshot token;快照文件存在不等于恢复演练成功。
|
||||
- 记录 ESO ClusterSecretStore 与 ExternalSecret 当前状态、refreshTime,以及代表性认证/PKI 流程的基线。
|
||||
- 在 Grafana 选择外部 Alertmanager,仅对 `ClusterSecretStoreNotReady{name="openbao"}` 及已确认受影响的
|
||||
ExternalSecret 精确设置限时静默,记录 silence ID。不要静默全部 critical、Telegram 发送故障或无关服务。
|
||||
|
||||
## 4. 重启与人工解封
|
||||
|
||||
仅在前置条件全部满足且窗口已明确开始后,由执行者在 VM 执行:
|
||||
|
||||
```bash
|
||||
sudo systemctl restart openbao
|
||||
sudo systemctl is-active openbao
|
||||
```
|
||||
|
||||
随后检查 `bao status`。服务 active 而 sealed=true 是人工解封流程的预期交接点,
|
||||
此时停止自动操作,告诉维护者“Bao 已启动,等待人工 unseal”。
|
||||
|
||||
维护者在自己掌控、无录屏/日志采集的终端按既有 GPG 流程解密所需 share,随后使用隐藏输入提示:
|
||||
|
||||
```bash
|
||||
export BAO_ADDR=https://bao.ad.ddupan.top:8200
|
||||
bao operator unseal
|
||||
bao status
|
||||
```
|
||||
|
||||
按现场 threshold 提交足够的不同 share。不要使用 `xargs bao operator unseal`、命令替换或明文参数,
|
||||
也不要把解密结果交给 agent。仓库旧初始化示例中的 xargs 方式不用于本次维护。
|
||||
加密文件可能是 GPG 文件、base64 包装 share 或初始化 JSON;由维护者按真实格式处理,本文不猜文件路径或格式。
|
||||
完成后只回报 sealed=false 与非敏感状态;清理自己产生的临时解密副本/剪贴板,不删除原始加密备份。
|
||||
|
||||
## 5. 验收与结束
|
||||
|
||||
必须逐项记录结果,不以 systemd active 代替可用性:
|
||||
|
||||
1. initialized=true、sealed=false,节点/集群身份未变化,TLS 校验正常;预期 active 节点健康接口成功。
|
||||
2. 既有机器身份登录正常;代表性秘密消费/PKI 流程按既有权限验证,结果不输出秘密。
|
||||
3. ClusterSecretStore/openbao Ready;窗口前健康的 ExternalSecret 恢复 Ready,并观察一次新的实际刷新。
|
||||
需要加速时选择一个受影响对象触发 reconcile,不把所有 ESO 对象批量强制刷新。
|
||||
4. 受鉴权 metrics 返回有效 Prometheus 数据,匿名请求仍被拒绝;中央 target 连续至少三次 up,关键指标有当前样本。
|
||||
5. 采集身份续期/重新登录机制验证通过;规则已加载且无评估错误,目标消失/鉴权失败有可识别告警。
|
||||
6. 若做临时告警演练,标注维护测试并记录 firing/resolved;没有做真实故障演练时明确注明。
|
||||
7. 取消本次 silence,记录窗口实际结束时间、配置 commit/PR、验证与未完成项,更新来源文档。
|
||||
|
||||
## 6. 停止与回滚分支
|
||||
|
||||
- 新配置校验失败:不应用、不重启,修正候选配置。
|
||||
- 重启后进程无法启动:检查有限范围日志,恢复原配置及权限,再启动服务;维护者仍需准备 unseal。
|
||||
- 进程已启动但 YubiKey/解密/份额不可用:停止反复重启,维护者处理解封流程。
|
||||
恢复旧配置不会自动解封;若接近窗口截止则按故障处置,不能宣布回滚已恢复。
|
||||
- Bao 已恢复,仅采集鉴权/指标失败:优先撤回新增采集配置/身份变更,保持核心服务可用;
|
||||
不为修监控反复重启 Bao。记录监控尚未完成,安排后续修复。
|
||||
- 必须恢复原服务配置时:恢复备份、重启、再次人工解封,并重复核心与依赖验收。
|
||||
- 本次配置回滚不包含 Raft snapshot restore、清空数据目录、init、rekey 或 seal migration。
|
||||
|
||||
## 来源与证据边界
|
||||
|
||||
维护者 2026-09-25 确认 VM 保存 GPG 加密解封材料,YubiKey 解密且需人工 unseal。
|
||||
本轮已进行只读预检及候选文件准备;没有读取解封材料、替换运行配置、设置静默或执行重启。
|
||||
|
||||
### 2026-09-25 停机前预检
|
||||
|
||||
- Bao API 与 VM 二进制均为 2.6.1,Shamir threshold/shares 为 1/1,initialized=true、sealed=false。
|
||||
- 管理入口为 `ssh [email protected]`,sudo 可用。按维护者明确要求,将管理工作站
|
||||
panxiao81 的 authorized_keys 中两条受信任公钥追加到 VM 的 ansible 用户,保留原公钥,
|
||||
修改前已在该账号 `.ssh/` 备份 authorized_keys;此次是现场授权变更,尚未纳入 cloud-init/IaC。
|
||||
- 运行配置未显式设置 telemetry。原配置与候选文件分别保存为 VM root-only 目录
|
||||
`/etc/openbao/maintenance-monitoring-20260925/config.before.hcl`、`config.candidate.hcl`。
|
||||
候选文件通过现场 `bao operator validate-config -config=...`;原运行配置未变。
|
||||
若后续其他任务改动运行配置,必须重新比较后再使用,不能覆盖新改动。
|
||||
- 快照服务 9 月 23–25 日日志均为 403,9 月 25 日退出码 2;默认 `/var/backups/openbao`
|
||||
未发现 .snap。尚未证明存在其他有效副本,此项阻止进入重启。
|
||||
- 源码快照使用 periodic token,但没有续期步骤。候选补丁增加每日续期、显式 rotate 开关、
|
||||
私有 partial 文件及成功后原子更名;403 的精确原因仍需检查 token 状态,不能直接断言已过期。
|
||||
- 当前本地 Bao 管理员会话不可用;受鉴权 metrics、Terraform plan/apply、快照身份恢复待完成。
|
||||
- 候选通过 Kustomize、规则检查、server dry-run、Terraform fmt;Agent 只在关闭的本机端口验证
|
||||
解析/启动,未做真实登录。快照模拟测试验证续期失败与写失败不删旧备份,成功才清理保留数量。
|
||||
|
||||
源码:[OpenBao 部署与恢复入口](https://git.ddupan.top/panxiao81/homelab-infra/src/branch/main/infrastructure/openbao/README.md),
|
||||
配置模板与 restart handler 位于同目录 `ansible/roles/openbao/`。
|
||||
命令依据:[人工 unseal](https://openbao.org/docs/2.6.x/commands/operator/unseal/)、
|
||||
[telemetry 配置](https://openbao.org/docs/2.6.x/configuration/telemetry/)。
|
||||
|
||||
### 人工解封准备确认
|
||||
|
||||
维护者已在插有 YubiKey 的 working PC 成功验证解密。VM 的 `/home/ansible/unseal.txt`
|
||||
包含带 `Unseal Key 1:` 前缀的 base64 GPG 密文;正文不保存其内容。
|
||||
实际解封由维护者在 working PC 解密后通过 HTTPS 提交,不能将密文直接当作 unseal key。
|
||||
这次验证未执行解封或重启。
|
||||
|
||||
随后只读确认:快照 token 的 lookup-self 也返回 403,VM root 没有可用的 Bao CLI 会话。
|
||||
需要维护者先登录管理会话,恢复快照身份并完成受鉴权预检后才能进入停机。
|
||||
若在 VM 使用 OIDC CLI 登录,应从 working PC 建立
|
||||
`ssh -t -L 8250:127.0.0.1:8250 [email protected]`,再在 VM 的 root shell 设置
|
||||
`BAO_ADDR=https://bao.ad.ddupan.top:8200` 并运行 `bao login -method=oidc -no-print role=admin`。
|
||||
登录网址在 working PC 浏览器打开,账号需符合现有 vault-admins 组约束;不把 token 发给 agent。
|
||||
+10
-2
@@ -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) | 具体应用的权限说明 |
|
||||
@@ -55,3 +58,8 @@ Samba AD、OCI、Proxmox 已明确以 IaC 为准,可直接核对其代码;
|
||||
检索、转换或 AI 摘要用于定位原文;结论仍应关联到源码、维护者说明或 ticket。
|
||||
工作完成后,将持久使用方法写入服务页,将一次变化留在 commit/PR,动态进度回到原项目 ticket。
|
||||
原仓库 README 同步目前按维护者要求暂缓,不将其列为每次任务的前置条件。
|
||||
|
||||
- [证书、秘密同步与 GitOps 监控](monitoring-controllers.md):证书临期、ESO 同步与 Flux Ready 排障。
|
||||
- [CNPG、NATS 与 SeaweedFS 监控](monitoring-data-services.md):数据库连接、消息容量与存储故障。
|
||||
|
||||
- [OpenBao 监控接入维护](openbao-monitoring-maintenance.md):窗口准备、YubiKey 人工解封交接与回滚。
|
||||
|
||||
@@ -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,101 @@
|
||||
---
|
||||
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 入口,不删除用户或原有认证配置。
|
||||
|
||||
### 独立登录服务的 AD 接入
|
||||
|
||||
`iam-login` 的人类界面沿用内联上下文与原生表单,新增 AD 第一因素验收入口;
|
||||
以用户身份 LDAPS bind,读取 objectGUID 和直接 `memberOf`,组名保持原样。
|
||||
当前不展开嵌套组或主组,不能视为已完成与 Authelia 的有效组集合等价验证。
|
||||
密码成功只进入待 MFA 事务;Gitea 仍使用上面已验收的 Go/Authelia 路径。
|
||||
|
||||
本轮开发验证通过 JVM 测试,并从 JVM 通过 CA/域名验证读取真实 AD RootDSE。
|
||||
2026-09-25 维护者已在 HTTPS 开发入口完成真实密码验证,成功进入待 MFA 页面,
|
||||
并反馈目录标识、邮箱及六个直接所属组的查询结果。此人类验收只覆盖 AD 第一因素与
|
||||
属性读取,不包括 MFA 或 Hydra 登录。新增路径尚未跑 Native;日常迭代不要求每轮原生编译。开发入口使用受限 Tailscale HTTPS,属于临时验收实例,不是生产入口。
|
||||
实现见 [iam-login PR #4](https://git.ddupan.top/panxiao81/iam-login/pulls/4),
|
||||
配置、边界与使用方式见
|
||||
[iam-login AD 接入文档(开发分支)](https://git.ddupan.top/panxiao81/iam-login/src/branch/feat/ad-login/docs/ad-login.md)。
|
||||
+8
-5
@@ -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,10 +23,12 @@ 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` | 已有客户端读写指南与备份边界说明 |
|
||||
| [shared-postgresql](shared-postgresql.md) | 共享 PostgreSQL / CNPG | `shared-db namespace` | 历史迁移记录已完成 | `apps/shared-postgresql/migration.md` | 已有连接、应用接入与共享资源边界指南 |
|
||||
| [shared-etcd](shared-etcd.md) | homelab 共享协调与选主存储 | 三个 mTLS endpoints,见服务页 | 三成员已部署并现场验证,experimental | `infrastructure/etcd/README.md` | 原生指标与规则已接入;自动续签已启用;备份/证书年龄告警待补 |
|
||||
| [shared-postgresql](shared-postgresql.md) | CNPG 与新 k3s 外共享 PG | 旧 `shared-db`;新 `pg-prod` / `pg-dev.ad.ddupan.top` | 新生产主从与开发实例上线,旧应用未迁移 | `infrastructure/shared-postgresql/README.md`、旧 migration.md | 切换/备份恢复已验证;Ayatori 独立控制面仅备齐声明 |
|
||||
| [smtp-relay](smtp-relay.md) | 应用经 Microsoft 365 发信 | `smtp-relay.smtp-relay.svc.cluster.local:25` | 有配置与测试指南;未附上线记录 | `apps/smtp-relay/README.md` | 已有应用参数、测试邮件与投递边界指南 |
|
||||
| [tailscale](tailscale.md) | 远程网络与子网路由 | `Tailscale 网络` | 有配置;本轮未读敏感安装脚本 | `apps/tailscale/subnet-routes.sh` | 已有远程访问与路由边界指南 |
|
||||
| [vlmcsd](vlmcsd.md) | KMS 兼容服务,使用范围未记录 | `宿主 TCP 1688;地址未记录` | 仅发现配置 | `apps/vlmcsd/compose.yaml` | 已有协议入口与客户端指南;未查询现场 |
|
||||
@@ -56,8 +59,8 @@ SPIFFE/SPIRE 已按维护者授权补读 #34;LAN DNS 与 Authelia 已按维护
|
||||
| kata-lxc-lab | LXC 内 Kata worker 试验 | `pve2 / 记录地址 192.168.10.128` | 记录 PoC 验证;非正式生产服务 | `infrastructure/kata-lxc-lab/README.md` | 明确与 microVM runner 的职责 |
|
||||
| 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 设计见独立项目 |
|
||||
| [openbao](openbao.md) | 秘密管理与内部 CA | `bao.ad.ddupan.top` | 人工解封、中央采集与本地快照已验收 | `infrastructure/openbao/README.md` | 内部健康和快照新鲜度有告警;异地恢复演练待完成 |
|
||||
| [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 +77,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。
|
||||
|
||||
+9
-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,11 @@ 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-data-services.md)。
|
||||
转换器故障处理与验证依据见 [基础监控运维](../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 范围。
|
||||
+25
-4
@@ -1,9 +1,9 @@
|
||||
---
|
||||
title: OpenBao 使用指南
|
||||
lifecycle: active
|
||||
evidence: documented
|
||||
last_reviewed: 2026-09-16
|
||||
last_verified: null
|
||||
evidence: live-verified
|
||||
last_reviewed: 2026-09-25
|
||||
last_verified: 2026-09-25
|
||||
---
|
||||
|
||||
# OpenBao
|
||||
@@ -12,7 +12,8 @@ OpenBao 提供秘密管理与内部 CA,部署在 Kubernetes 之外的独立主
|
||||
日常使用是以自己的身份登录,按已有 policy 读取秘密或申请短期凭据。
|
||||
|
||||
本页依据 homelab-infra 工作区 `infrastructure/openbao/README.md` 整理,
|
||||
CLI 语法参考下列官方文档。本轮未登录服务、读取秘密或验证现场。
|
||||
CLI 语法参考下列官方文档。登录和取密指南仍以文档为据;2026-09-25 已现场验证
|
||||
服务解封、中央指标、ESO 秘密刷新及本地快照监控,范围见本文末节。
|
||||
|
||||
## 人的登录入口
|
||||
|
||||
@@ -86,3 +87,23 @@ Dynamic Runner 提供执行环境和 workload 身份,具体向 OpenBao 请求
|
||||
日常登录成功不等于已完成备份或灾难恢复验收。
|
||||
|
||||
来源文件的固定版本与工作区差异见[来源追溯](../sources.md#openbao)。
|
||||
|
||||
## 监控接入与维护窗口
|
||||
|
||||
2026-09-25 已启用受鉴权 Prometheus telemetry,ServiceMonitor 通过现有 vmagent 采集,
|
||||
job 为 `openbao`。同 Pod 的 Bao Agent 使用 Kubernetes SA 登录 metrics role,自动续期,
|
||||
token 仅保存于内存卷;指标身份不能读取业务秘密,匿名 metrics 仍被拒绝。
|
||||
已有目标 down/消失持续 3 分钟的 critical 告警,通知沿用 Telegram。
|
||||
内部健康规则另检查当前单节点的 active、unsealed、Raft autopilot node healthy,
|
||||
并单独告警健康 gauge 缺失。以后改为多节点时必须调整 active 判定;尚未覆盖全部 Raft 或 PKI 风险。
|
||||
|
||||
维护中已修复快照 token 失效及脚本缺少续期的问题,生成新快照并核对 VM 外副本。
|
||||
快照 timer 已启用;独立的 VM node_exporter 通过 textfile 上报最近结果、完成时间和最后成功时间,
|
||||
不依赖 Bao 解封或 API token。快照失败持续 5 分钟为 warning,超过 36 小时无成功快照
|
||||
或无成功记录持续 15 分钟为 critical;采集失联/损坏也有专用告警。
|
||||
标准主机指标复用现有主机规则。异地副本与恢复演练仍需独立验收。
|
||||
|
||||
维护者用 working PC 的 YubiKey 解密 VM 上保存的加密 unseal share,重启后人工解封。
|
||||
本次服务配置变更、采集上线与恢复验收已完成,详细操作与证据见
|
||||
[OpenBao 监控接入维护 runbook](../guides/openbao-monitoring-maintenance.md)。
|
||||
后续重启仍需同样的人在场解封流程;不能因本次恢复成功假定已经自动解封。
|
||||
|
||||
@@ -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,45 @@ 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)
|
||||
与安全文档为准;合并不表示部署或完整供应链路已完成。
|
||||
|
||||
应用凭据存储切片及测试准备修复已通过三项 CI,并经维护者批准合并
|
||||
[PR #12](https://git.ddupan.top/panxiao81/ayatori/pulls/12),合并提交为
|
||||
[22ab72e](https://git.ddupan.top/panxiao81/ayatori/commit/22ab72ec60dd5a0bf852e4563e107597dd56e81f)。
|
||||
复用 OpenBao 官方 Go SDK 的 KV v2 CAS=0、回读七键与版本,禁止覆盖
|
||||
或自动认领;明确权限拒绝等待依赖恢复,写入结果不确定则停止并人工处理。本地真实
|
||||
OpenBao 测试已覆盖并发、软删除、固定前缀权限和响应丢失,尚未接入 manager、
|
||||
Database 供应或 ESO。源码模块文档与 wiki 已关联,见
|
||||
[同步记录](../verification.md)。
|
||||
|
||||
Kubernetes 认证会话的后续实现位于
|
||||
[PR #13](https://git.ddupan.top/panxiao81/ayatori/pulls/13),提交
|
||||
[f0aa86f](https://git.ddupan.top/panxiao81/ayatori/commit/f0aa86f67673fbfb5f182f3ce35679c614be968d),尚未合并。
|
||||
维护者指出并纠正了首版的 Pod 文件假设:controller 可以是 systemd service;Kubernetes auth
|
||||
仍是正确路径,但应复用 manager 的标准 kubeconfig/in-cluster 配置,通过 RBAC 授权的指定
|
||||
ServiceAccount TokenRequest 申请短期 JWT。集群内外共用同一客户端路径,不另建机器身份。
|
||||
重新登录重新申请 JWT,申请失败不回退投射文件或静态 token;官方 SDK 负责 Bao 登录与
|
||||
LifetimeWatcher,续期失败及停止时清空本地 token。kubeconfig 的签发、更新与撤销属于部署管理。
|
||||
manager 已增加显式 HTTPS/CA、auth role、目标 SA/audience 配置、Runnable 与 readiness,
|
||||
默认停用;controller 不自动创建身份或授予权限。真实受限 kubeconfig 启动 manager 的测试
|
||||
验证 TokenRequest、续期、跨 namespace/其他 SA 拒绝、RBAC 撤回恢复与 Bao audience 校验,
|
||||
三轮 race、本地全量测试和两种 lint 通过。生产 auth 配置与 Database 供应尚未接入,不代表已部署。
|
||||
具体使用边界见该提交的
|
||||
[认证会话说明](https://git.ddupan.top/panxiao81/ayatori/src/commit/f0aa86f67673fbfb5f182f3ce35679c614be968d/docs/database/README.md#openbao-kubernetes-认证会话)。
|
||||
|
||||
- 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 +202,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 时间线、跨资源影响边界、相关操作会话和后续验收条件;本页保留可复用恢复方法。
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
title: SeaweedFS S3 使用指南
|
||||
lifecycle: active
|
||||
evidence: documented
|
||||
last_reviewed: 2026-09-16
|
||||
last_reviewed: 2026-09-25
|
||||
last_verified: null
|
||||
---
|
||||
|
||||
@@ -85,3 +85,8 @@ zot 的 S3 身份只允许相应 bucket 的 Read/Write/List/Tagging,不能访
|
||||
其他应用的数据保留与恢复策略应由各自用途明确,不能从“已接入 S3”推断已经完成备份。
|
||||
|
||||
来源文件的固定版本与工作区差异见[来源追溯](../sources.md#seaweedfs)。
|
||||
|
||||
## 中央监控
|
||||
|
||||
2026-09-25 已接入 master、filer、volume 指标与容量/写入故障规则;
|
||||
使用方式与验证边界见 [数据服务监控](../guides/monitoring-data-services.md)。
|
||||
|
||||
@@ -0,0 +1,71 @@
|
||||
---
|
||||
title: Homelab 共享 etcd
|
||||
lifecycle: experimental
|
||||
evidence: live-verified
|
||||
last_reviewed: 2026-09-25
|
||||
last_verified: 2026-09-25
|
||||
---
|
||||
|
||||
# Homelab 共享 etcd
|
||||
|
||||
为 homelab 服务提供共享的配置、协调与选主存储。维护者已接受共享定位;首个消费者是
|
||||
k3s 外 PostgreSQL 的 Patroni。三成员基础服务已部署,现有监控已接入,自动续签已启用;现有 k3s datastore 未迁移。
|
||||
|
||||
## 入口与第一次接入
|
||||
|
||||
部署拓扑为 laptop 原生 systemd、pve1/pve2 各一个无特权 LXC(150/151)。地址为
|
||||
192.168.10.127、10.60.0.20、10.60.0.21,客户端端口 2379,三端点健康检查已通过。两个 LXC 的 rootfs 位于 `pve-rg` SSD DRBD 池。
|
||||
实际接入前由管理流程交付三个 TLS endpoints、中央 CA、独立客户端证书和 Bao 秘密引用。
|
||||
使用分配身份在自己的 prefix 内 put/get/delete 验证,并确认跨 prefix 被拒绝;不要使用管理员证书接应用。
|
||||
|
||||
证书由 OpenBao 中央 CA 签发,成员间 peer CN 受限。管理员原生 etcdctl 使用 CN=root 证书;
|
||||
Patroni etcd3 gateway 使用无 CN 的 mTLS 证书加独立账号密码,不能复用管理员证书。
|
||||
密码首次随机生成并存入 Bao,重复部署复用,缺失、读取失败或漂移均不静默重置。
|
||||
首个消费者秘密路径为 `kv/infra/etcd/consumers/patroni-pg-prod`,授权 prefix 为
|
||||
`/homelab/patroni/pg-prod/`;账号和随机密码已创建,真实 gateway 登录已验证;Patroni 已部署并通过自动切换验证。
|
||||
|
||||
## 依赖、维护与恢复
|
||||
|
||||
依赖主机网络、磁盘、systemd;证书签发及配置收敛依赖 Bao。运行使用本地证书,不要求 Bao 在线。
|
||||
共享 etcd 的创建、维护和快照与数据库生命周期分离;删除 PostgreSQL 不删除 etcd。
|
||||
全集群快照恢复必须协调所有消费者,不能作为单个业务的回滚。
|
||||
|
||||
源码实现提供每日每成员本地快照、独立认证初始化、消费者收敛和逐成员更新入口。
|
||||
三个成员的原生指标已接入现有 VictoriaMetrics,不增加 exporter;内网 2381 listener 不提供 KV API。
|
||||
六条规则覆盖成员采集、采集可见成员不足、无 leader、容量、fsync 和选举,现场三目标 up=1、规则 health=ok。
|
||||
Alertmanager 已接入 [Telegram 通知](grafana.md#telegram-告警接入),warning/critical 可向外通知;备份年龄与证书到期告警尚待补齐。
|
||||
|
||||
自动续签已启用:维护者恢复 OIDC 管理会话后,独立 cert auth、受限 policy 与每日 timer 已部署。
|
||||
登录使用 laptop 现有 peer 证书,按 DNS SAN 限制身份;无 CN gateway 证书不能用于 Bao cert
|
||||
登录(identity alias 为空),不会改动 etcd gateway 的无 CN 要求。首次实际续签流程三成员均
|
||||
`changed=0`、service Result=success;程序固定副本由 root 管理,短期 token 用后撤销。
|
||||
运行仍只依赖本地证书;续签和恢复步骤见源码 README。
|
||||
业务负载下的存储延迟与完整灾难恢复演练仍待完成。
|
||||
故障时先查 `homelab-etcd` systemd 日志和三端点健康;成员替换不能通过删除数据目录、重跑初始化处理。
|
||||
详细操作与验收边界见 homelab-infra `infrastructure/etcd/README.md`。
|
||||
|
||||
存储故障处理:单成员 `NoLeader` 与频繁选举告警可能来自底层 I/O,不能直接认定整个集群失去 quorum。
|
||||
2026-09-25 CT150 的 DRBD 根卷短暂丢失 quorum,ext4 journal 写入失败后进入 `emergency_ro`;
|
||||
另外两成员仍健康。保存快照后停止 CT150,以 PVE 离线 fsck 修复、复查干净再启动,三成员健康及
|
||||
Raft term/index 一致已重新验证,两容器根卷与新增 mp0 均可写。不要在挂载中的卷上 fsck 或直接强制 remount。
|
||||
本项目两块新 HDD 数据卷后台同步上限已通过 IaC 限制为各 10 MiB/s;限速后短期未再见 PingAck 超时,
|
||||
但唯一根因和长期稳定性未确证。没有更改全局 DRBD quorum/协议。对应入口为
|
||||
`infrastructure/shared-postgresql/ansible/limit-resync.yml`,重复执行无变更;详细恢复过程见上述 runbook。
|
||||
频繁选举规则包含 15 分钟历史窗口,故障恢复后需结合当前健康及计数判断。
|
||||
|
||||
|
||||
## 证据与阶段边界
|
||||
|
||||
2026-09-25 维护者指定 laptop + 两台 PVE 各一个新 LXC,并明确复用 Bao 中央 CA;旧 Vault 迁移后置。
|
||||
现场部署已应用独立 Bao PKI roles/policies,创建 LXC 150/151 并启用三成员 mTLS、认证及消费者 RBAC。
|
||||
PVE 两个 LXC 已直接迁移底层 rootfs 到 `pve-rg`;逐成员停机迁卷、启动后检查 quorum,未重建容器或数据库。
|
||||
2026-09-25 现场核实两个 rootfs 的目标存储与运行状态,三个 endpoint 均成功提交健康探测。
|
||||
当前 PVE LXC `move-volume` 要求容器停止;操作入口为源码 `ansible/move-storage.yml`。
|
||||
|
||||
本地临时三节点 etcd 3.7.2 测试通过:mTLS、认证和消费者幂等、prefix 隔离、gateway 登录/写入、
|
||||
密码缺失/漂移失败关闭、快照离线恢复与停止一成员后的写入。假 Bao 测试不证明真实 PKI/policy 正确;
|
||||
测试进程 RSS 约 37–40 MiB 不是生产容量承诺。Terraform validate 与 Ansible lint 通过。
|
||||
证书签发、秘密创建、gateway 登录和机器身份续签均已在真实服务验证。
|
||||
|
||||
来源为维护者指令、只读前置核查及 homelab-infra `infrastructure/etcd/`;
|
||||
文档已直接发布 main([文档 acd4b55](https://git.ddupan.top/panxiao81/homelab-infra/commit/acd4b55)),实现见 [IaC PR #159](https://git.ddupan.top/panxiao81/homelab-infra/pulls/159),已合并。与数据库的关系见[共享 PostgreSQL](shared-postgresql.md#共享-etcd-设计边界)。
|
||||
@@ -2,7 +2,7 @@
|
||||
title: 共享 PostgreSQL 使用指南
|
||||
lifecycle: active
|
||||
evidence: documented
|
||||
last_reviewed: 2026-09-16
|
||||
last_reviewed: 2026-09-25
|
||||
last_verified: null
|
||||
---
|
||||
|
||||
@@ -80,3 +80,64 @@ AI 接续任务时先确认操作范围,再执行现场查询;不能因为
|
||||
服务依赖 Kubernetes、CNPG、集群 DNS 与持久存储;Tailscale 入口另依赖对应网络及授权。
|
||||
|
||||
来源文件的固定版本与工作区差异见[来源追溯](../sources.md#shared-postgresql)。
|
||||
|
||||
|
||||
## 共享 etcd 设计边界
|
||||
|
||||
2026-09-25 维护者确定:为计划中的 k3s 外 PostgreSQL 引入的 etcd,应作为全 homelab
|
||||
共享基础设施建设,PostgreSQL 是首个消费者。该共享定位已实现并完成首期部署验收;既有应用尚未迁移,
|
||||
不改变本页现有 CNPG 入口。原研究将 etcd 列入数据库部署角色,新边界将其生命周期独立,
|
||||
以便多个服务共用,减少重复部署与维护。
|
||||
|
||||
首期三成员已跨 laptop 与两台 PVE 部署,可与其他服务物理共置;
|
||||
独立 IaC 管成员、认证、维护和快照,消费者只取得自己的账号与 key prefix 权限。
|
||||
数据库卸载不能删除共享 etcd,全集群快照恢复也不能用作单个数据库的回滚。
|
||||
现有 k3s 内部 datastore 不包含在本次迁移范围;其他消费者按实际需要接入。
|
||||
|
||||
维护者同时确定 etcd mTLS 证书由 OpenBao 中央 CA 签发,复用现有信任根,不引入
|
||||
Pigsty 自建 CA。签发角色、peer 身份限制及消费者认证已部署;自动续签身份和 timer 已启用;
|
||||
证书本地保存,正常启动不要求实时访问 Bao,Bao 本身不依赖此共享 etcd。
|
||||
Patroni 的 etcd3 gateway 路径不支持证书 CN 对应的 RBAC 登录;维护者确定其独立随机密码
|
||||
存入 Bao,由 Ansible 执行时读取,重复部署复用,轮换显式执行。该 secret 已在共享 etcd 部署阶段创建并验证 gateway 登录;Patroni 已部署。
|
||||
PVE 改为裸机目前仅为后续倾向,没有迁移决定。
|
||||
|
||||
来源为本轮维护者设计指令及 homelab-infra
|
||||
`infrastructure/shared-postgresql/RESEARCH.md`;文档来源为 [文档 acd4b55](https://git.ddupan.top/panxiao81/homelab-infra/commit/acd4b55),实现由 [IaC PR #159](https://git.ddupan.top/panxiao81/homelab-infra/pulls/159) 跟踪。
|
||||
本节记录数据库设计边界;共享 etcd 的现场部署与验证见独立服务页,本页 CNPG 的 `last_verified` 不因此更新。
|
||||
|
||||
共享 etcd 的首轮 IaC、隔离验证与部署前置条件见[共享 etcd](shared-etcd.md)。
|
||||
|
||||
### k3s 外实例的实现与验收边界(2026-09-25)
|
||||
|
||||
新 PostgreSQL 18.6 生产主从与独立开发实例已上线,现有 CNPG 应用数据尚未迁移。
|
||||
生产稳定入口 `pg-prod.ad.ddupan.top:5432` 指向 VyOS `192.168.10.2` 上独立 HAProxy;
|
||||
正常 primary 为 laptop SSD ZFS,PVE LXC150 为 standby。开发入口为
|
||||
`pg-dev.ad.ddupan.top:5433`,同机独立用户/数据集。客户端要求中央 CA 与 verify-full TLS。
|
||||
|
||||
LXC151 的专属 HDD 卷存放 pgBackRest 仓库,真实 SSH/WAL 归档、首个 full 和每日 timer 已验收;
|
||||
保留 3 个 full、本地连续 WAL,尚无异地备份,开发实例当前不备份。
|
||||
真实备份已恢复到临时目录的隔离实例,SQL 可写与管理角色属性验证通过,未覆盖生产 PGDATA。
|
||||
低负载停止 laptop 主库服务后,完整通过的一次演练约 9.2 秒恢复经稳定入口写入;旧主重新作为
|
||||
replica 加入、计划回切 laptop 后复制与探针清理全部通过。这不是 SLA,也不覆盖冻结/网络分区等全部故障。
|
||||
|
||||
Bao PKI 与专用 `homelab-postgresql` SPIFFE 身份已通过 OIDC 管理会话首次创建;之后受限身份
|
||||
完成签发、KV 读取与独立管理凭据交付。原始实例秘密不交给 Ayatori,控制面只读
|
||||
`kv/infra/postgresql/ayatori/{prod,dev}` 中的 username/password。
|
||||
生产与开发管理账号实际 TLS 登录和非 superuser CREATEDB/CREATEROLE 属性已验证。
|
||||
配置、备份传输、代理与凭据重跑 `changed=0`;PG 每日续签已启用,实际 systemd 运行成功,
|
||||
证书窗口检查与 SQL 验收无变更。只在续签后重载证书,不重启实例;尚未强制演练临期轮换。
|
||||
数据库日常运行独立于 k3s;机器身份续签依赖现有 SPIRE 与 Bao,不等于运行时依赖。
|
||||
|
||||
生产 Patroni 原生指标已接入现有监控,两目标 up=1、五条 HA 规则 health=ok 且 inactive。
|
||||
SQL 级 exporter、开发实例、备份年龄和证书到期告警尚未补齐。存储事故与持续观察边界见
|
||||
[共享 etcd](shared-etcd.md#依赖维护与恢复),不以短期验收证明底层长期稳定。
|
||||
|
||||
维护者明确 Ayatori 沿用独立控制面规划:本轮只准备 Instance、ExternalSecret、公开 CA、
|
||||
Kustomize 与专用 ESO 只读 policy,没有向现有 k3s 安装 controller/CRD 或应用这些声明。
|
||||
独立控制面还需创建实际 SecretStore/认证绑定并验收 Instance Ready;完整 Database/Tenant
|
||||
供应能力以 Ayatori 自身实施为准。不能把现有 SQL 验证当作 Ayatori 已接管。
|
||||
|
||||
源码为 homelab-infra `infrastructure/shared-postgresql/README.md` 与
|
||||
`ayatori/README.md`;部署、切换、恢复、续签及凭据引用的具体入口在那里维护,文档已发布 main;IaC 见 [IaC PR #159](https://git.ddupan.top/panxiao81/homelab-infra/pulls/159),已合并;2026-09-25 核实 Flux observability 已应用 `f6d12d6`,四个监控对象均已进入 inventory。
|
||||
Terraform backend 已复用 `kv/k8s/seaweedfs-s3` 中受限 AK/SK;此前阻塞是 Bao 管理权限,已由
|
||||
维护者重新 OIDC 登录解决,不是 S3 凭据缺失。旧 Ansible Vault 迁移仍后置。
|
||||
|
||||
+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,87 @@ 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);
|
||||
未部署或进行现场验收。
|
||||
|
||||
凭据存储切片及冷缓存准备修复已通过 CI #815 的 test、lint、database-integration,
|
||||
维护者批准后合并 [PR #12](https://git.ddupan.top/panxiao81/ayatori/pulls/12),合并提交
|
||||
[22ab72e](https://git.ddupan.top/panxiao81/ayatori/commit/22ab72ec60dd5a0bf852e4563e107597dd56e81f)。
|
||||
后续 Kubernetes 认证与短期会话续期已提交为
|
||||
[f0aa86f](https://git.ddupan.top/panxiao81/ayatori/commit/f0aa86f67673fbfb5f182f3ce35679c614be968d),
|
||||
由 [PR #13](https://git.ddupan.top/panxiao81/ayatori/pulls/13) 跟踪 CI 与 review。
|
||||
首版依赖投射 SA 文件的假设已按维护者意见撤除:集群外 kubeconfig 与集群内配置共用 manager
|
||||
客户端,通过受限 TokenRequest 获取登录 JWT。manager 显式配置、Runnable 与 readiness 已装配;
|
||||
三轮真实 API/OpenBao race、本地全量测试与两种 lint 通过,覆盖 RBAC 撤回/恢复和越权拒绝。
|
||||
源码文档与 wiki 已同步边界和正式链接。认证尚未合并,不把本地验证等同于新 head 的远端 CI;
|
||||
未部署生产 auth/RBAC,也未接入 Database 供应或 ESO 交付。
|
||||
|
||||
## 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 源码当时尚未提交,固定版本现关联 [合并提交 f6d12d6](https://git.ddupan.top/panxiao81/homelab-infra/commit/f6d12d6);
|
||||
服务恢复不等于全部整改完成。
|
||||
|
||||
## 共享 etcd 与 PostgreSQL 来源同步
|
||||
|
||||
2026-09-25 shared etcd 三成员、新 PG 生产主从与开发实例、稳定入口、本地备份已部署,
|
||||
监控 CR 已现场应用。OIDC 恢复后,专用身份与 etcd/PG 每日续签均已启用;此前 Bao 权限阻塞已解除。
|
||||
真实 PG 自动切换、回切、SQL/TLS、备份恢复与配置幂等通过,边界见
|
||||
[共享 PostgreSQL](services/shared-postgresql.md#k3s-外实例的实现与验收边界2026-09-25)和
|
||||
[共享 etcd](services/shared-etcd.md)。
|
||||
|
||||
源码 `infrastructure/etcd/`、`infrastructure/shared-postgresql/`、DNS 和监控已提交至 [IaC PR #159](https://git.ddupan.top/panxiao81/homelab-infra/pulls/159),已合并。
|
||||
2026-09-25 合并后现场验证:Flux observability Ready,应用版本 `f6d12d6`;
|
||||
两份 VMRule 和两份 VMStaticScrape 均在 Flux inventory 中,状态 operational。
|
||||
三个 etcd 和两个 Patroni 目标均 up=1,相关 11 条规则 health=ok、inactive。
|
||||
监控声明已由 GitOps 接管。既有 CNPG 应用未迁移,异地备份后置;数据库细项告警仍待补齐。
|
||||
Ayatori 按维护者决定继续使用独立控制面,本轮只准备接入材料,尚未验收 controller/Instance Ready。
|
||||
两仓事实已同步,源码文档已直接推送 main:[文档 acd4b55](https://git.ddupan.top/panxiao81/homelab-infra/commit/acd4b55);IaC 固定版本为
|
||||
[3a2fe5f](https://git.ddupan.top/panxiao81/homelab-infra/commit/3a2fe5f)。
|
||||
|
||||
Reference in New Issue
Block a user