跳转至

阶段十六:控制面后端冗余与断网只读控制台

状态:已完成并归档

P16 已完成 102 只读备用控制面、Auth 一致性快照与会话连续性、Console/API Gateway 只读备用、Edge 本地主备回退、101 单观察者安全路径、RR 整机重启与故障恢复演练。当前生产仍由 RR 保持唯一控制面写权威,102 只提供明确标识的只读降级服务;P17 已切换为“后续阶段待新增需求评审”占位。

📌 结论摘要

  • P16 的真实目标不是把 RR 做成双活,而是在 RR 后端不可用或整机短时不可达时,让活动 Edge 仍能把只读请求送到 102,用户至少能够登录验证、查看网络态势、节点状态、告警和最近一次权威快照。
  • 102 的 Auth 使用 RR Auth SQLite 的一致性快照,快照包含 PRAGMA quick_check、Schema、账号/API Key 计数和 SHA-256 校验;服务使用同一 AUTH_SESSION_SECRET,但写操作统一返回 503 standby_readonly_write_rejected。
  • 102 的 Console、API Gateway 和回源网关均健康;活动 Edge 的 console/auth/api 主 upstream 仍为 RR,102 作为 backup,只对连接错误、超时及 HTTP 500/502/503/504 回退。
  • 101 继续承担 DNS 控制器主观察者;RR 不可达时允许单观察者路径,但必须同时具备活动 Edge 连续失败证据和 101 本地管理路径正常证据;证据冲突、凭据缺失或 API 错误继续 fail closed。
  • RR 已执行一次真实整机重启演练。重启前后 boot_id 发生变化,Tailnet、Docker、Console、Auth、API Gateway、私有回源和关键业务容器均完成恢复回读。
  • 本阶段不把 102 变成第二 Runtime、第二调度器或第二写控制面;Nomad 仍是唯一任务调度器,Runtime、Nomad、Cloudreve 和 OmniRoute 写事务仍由既有生产权威负责。

🧾 状态变化

项目 归档时状态 证据
P16 阶段状态 已完成并归档 生产部署、管理员会话回读、Edge 回退、RR 重启和故障恢复均已完成
P16-0 已完成 冻结只读备用边界、RPO/RTO、回退层级和故障事实
P16-0A 已完成 RR、MM、DD、d02、dog-public 的 Exit Node 能力基线、Headscale 路由和重启持久性通过;默认均不使用
P16-0B 已完成 MM 核心域名 IPv6 vhost、证书、SNI 与 Home 经 MM Exit Node 的回归修复完成
P16-1 已完成 Auth 快照、同一会话密钥、102 备用 Auth、只读写拒绝与 RR 会话跨节点验证通过
P16-2 已完成 102 Console、API Gateway、回源网关、只读拓扑快照和健康检查通过
P16-3 已完成 Edge 主备 upstream、HTTP 500/502/503/504 回退、故障恢复和回退验证通过
P16-4 已完成 101 单观察者安全路径、DNS 状态、非法候选、凭据缺失和回退测试通过
P16-5 已完成 RR 整机重启、损坏快照负向回归、生产容器恢复和最终发布门禁完成

🧱 生产边界

层 生产事实 明确边界
Network MM、d02、DD、dog-public 已承担 Edge 候选;RR 不承担 Edge Edge 只负责入口与回源,不能替代后端控制面
Compute 102 运行只读备用容器和现有 OmniRoute;RR 运行权威 Runtime 与 Bridge 102 不提交 Nomad Job,不复制 Runtime 写库
Storage RR Auth SQLite 单向快照;102 保存只读副本和 last-known-good 不反向覆盖 RR,不直接复制正在写入的 WAL 数据库
Observability 备用页面与 API 返回 standby_readonly、read_only、快照年龄和来源 超过新鲜窗口必须显示 stale 或 unavailable,不伪装实时
Credentials 会话密钥、快照和 Edge 回源配置保存在 root-only 0600 边界 密钥、Token 和私钥不进入仓库、日志、前端或普通回复
Lifecycle 快照、last-known-good、Edge upstream 和 DNS 状态均可回退 回退不删除 RR 主库,不改变 Runtime、OmniRoute 或 Cloudreve 数据

🔌 故障路径

正常路径为:

浏览器
-> 活动 Edge Nginx
-> RR Console/Auth/API
-> RR 权威数据

RR 后端不可用但 Edge 可达时,console/auth/api 按受控策略变为:

浏览器
-> 活动 Edge Nginx
-> 102 只读 Console/Auth/API
-> RR last-known-good 快照

该回退只保护只读控制面。已有 Tailnet 直连可以在短时间内继续工作,但新注册、ACL 变更、Headscale 管理和所有生产写入仍依赖 RR;DERP 和 Peer Relay 不能替代 Console/Auth/API 后端高可用。

🧪 生产验收证据

验收项 结果
101 控制面备用同步 timer agentmeshos-control-plane-standby-sync.timer 为 active,最近触发时间已回读
101 安装版与仓库哈希 同步脚本安装版与仓库 SHA-256 一致
102 容器 agentmeshos-auth-site-standby、agentmeshos-console-site-standby、agentmeshos-api-gateway-standby、agentmeshos-standby-origin-gateway 均 healthy
备用服务端口 Auth 39150、Console 39110、API 39120、备用回源网关 39210 均返回 HTTP 200
只读写拒绝 密码、API Key 和告警生命周期写请求均返回 503 standby_readonly_write_rejected
合法会话读取 合法 standby 会话可读取 /__agentmeshos/session、Console 首页、app.js 和拓扑 API
会话密钥 RR 与 102 的 AUTH_SESSION_SECRET SHA-256 一致
Edge 回源 MM、d02、DD、dog-public 的主 upstream 为 RR,备用 upstream 为 102,回退判据包含 HTTP 500
RR 重启 RR boot_id 从旧值切换到新值,关键容器恢复 healthy,公网和私有路径回读通过
损坏快照 负向回归返回非零且 last-known-good 保持不变
DNS 控制器 当前活动 MM、dry-run、缺凭据、非法候选和单观察者路径均有现场回读
本地门禁 Runtime、Auth、Gateway、Console、拓扑、DNS、standby、计划状态、文档清单和严格 MkDocs 构建通过

⚠️ 残余风险

风险 当前事实 后续处理
RR 仍是写权威 102 只提供只读降级,不能创建任务、修改密码、撤销 Key 或管理 Nomad 保持双活写边界不开放;写能力恢复仍以 RR 为准
快照存在时间窗 RPO 目标为不超过 5 分钟,实际取决于 timer、SSH 和发布状态 继续监控 timer、快照年龄、last-known-good 和失败隔离
Edge 回退不是全站高可用 只覆盖 Console、Auth、API;其他域名继续 fail closed 新增需回退的域名必须单独评审,不扩大盲目回退
RR 稳定性 RR 经历真实 panic 和整机重启,仍需持续观察内存、Swap、OOM 和失败单元 异常作为新的运维事件处理,不重新打开 P16
外部漂移 DNS、Edge、证书、Tailnet 路径和凭据均可能变化 任一触发条件变化后重新执行 Edge、DNS、会话和回读验收

🔁 回退点

  • Edge 模板恢复单 RR upstream,并重新执行 nginx -t 与 reload。
  • 停止 102 的备用 Console、Auth 和 API Gateway 容器。
  • Auth 与拓扑快照恢复上一版 last-known-good。
  • DNS 控制器恢复只读双视角模式或最新 last-known-good 状态。
  • RR 主库、Cloudreve、Runtime、OmniRoute 和 Nomad 生产数据不得被备用节点覆盖。

P16 的归档依据是 P16 计划、生产命令回读、scripts/ci/run-local-tests.sh 和提交后的 post-push-verify。只有远端提交、Actions、101 Runner 和 RR 生产回读全部通过,P16 才在发布门禁中正式关闭。