部署门禁与高可用边界
更新:2026-10-04
📌 结论摘要
当前部署结论是:无状态服务继续走版本化自动发布,Stateful 服务保持人工门禁;RR 仍是控制面写权威,P16 已完成 102 只读备用、Edge 回退和 RR 整机重启演练,可提供受控只读降级,但仍不宣称控制面写入高可用。Exit Node 已作为五台节点的独立可选能力完成基线,默认客户端不使用,不参与控制面高可用判定。
🚦 发布闸门
所有发布先通过 GitHub Actions 监控脚本,确认目标提交的最新工作流全部完成且成功;失败、取消或超时必须保留日志并修复后重跑。RR 发布入口使用生产并发锁、固定提交 SHA 镜像、版本化 release bundle 和 SHA-256 校验,部署失败执行镜像回滚并记录结构化结果。
🔒 Stateful 服务门禁
以下服务不得直接复用 Docs、Console、Status、API Gateway 的无状态发布事务:
| 服务 | 自动发布前置检查 | 回滚边界 |
|---|---|---|
| Auth Site | 认证数据库备份、完整性检查、凭据权限、新旧镜像兼容、登录/登出/重置/会话恢复 Smoke | 镜像可回滚,认证数据库不回滚 |
| AI Runtime | SQLite/WAL/SHM 一致性快照、quick_check、迁移前后结构和关键计数、历史任务/对话/成果读取、Runtime 与 OmniRoute/Nomad/Cloudreve 边界 Smoke |
镜像与数据库快照成对恢复,恢复后重新验证任务读取和公网入口 |
| CLI Agent Gateway | 凭据不进镜像和日志、三个 CLI 通道真实 Smoke、容器权限/只读根/网络边界、与 Runtime 兼容性 | 仅回滚 Gateway,不影响 Runtime 主链路 |
在对应门禁全部自动化并通过前,上述服务保持人工发布。
🧱 RR 生产边界
RR 当前是单节点生产,自动部署不等于高可用。P15 已完成多 Edge、DERP、Peer Relay 和 DNS 自动切换,但这些能力只覆盖公网入口与 Tailnet 中继,不复制 RR 上的 Console、Auth、API Gateway 和 Runtime。整机故障时,所有 Edge 仍会因 RR 回源失败而无法登录;这一事实必须显示为“控制面后端单点”,不能因为存在多台 Edge 就宣称控制台高可用。整机恢复仍需单独评估接管节点、公网 DNS/入口切换、Runtime 数据恢复、凭据恢复边界以及 Cloudreve 恢复顺序。第二生产节点和恢复演练全部完成前,文档和控制台必须继续显示“单节点生产、可恢复、非高可用”。
101 的独立备份盘固定为 /srv/codex-hub-backup,执行备份前必须确认来源为 /dev/sda1;RR 的 /backup 不得被当作独立备份盘。容量告警、归档和镜像清理由独立维护任务执行,不得删除运行中的镜像、回滚镜像、凭据或系统 Codex 数据。
P16 控制面只读备用门禁
P16 的目标是 RR 后端或整机故障时仍能看到只读控制台,而不是复制生产写入面。发布前必须满足以下门禁:
- RR Auth SQLite 使用一致性快照,记录
PRAGMA quick_check、Schema、账号数、Key 数和 SHA-256;102 只安装 last-known-good,不直接复制运行中的 WAL 文件。 - 备用 Auth 使用同一
AUTH_SESSION_SECRET,验证已有会话和登录读取,但拒绝密码、Key 和管理写操作;密钥错误时拒绝启动,不生成新会话密钥。 - 备用 Console/API 只开放 topology、node inventory、alerts 和 bridge status 等只读路径,不代理 Runtime、Nomad 管理、系统操作或写接口。
- Edge 只对
console/auth/api使用本地主备 upstream;连接失败、超时和500/502/503/504才回退,DNS、DERP 和 Peer Relay 不作为后端接管机制。 - 页面与 API 必须返回
deployment_mode=standby_readonly、read_only=true、source=rr-last-known-good和snapshot_age_seconds;拓扑超过 5 分钟标 stale,超过 30 分钟标 unavailable。 - 必须真实验证停止 RR 后端、关闭 RR 整机、损坏快照和恢复 RR 四类场景,不能以单元测试或路径注入替代。目标 RPO 不超过 5 分钟,目标 RTO 不超过 3 分钟。
- Exit Node 是独立于只读控制面的可选能力:只允许
rr、mm、dd、d02、dog-public宣告0.0.0.0/0与::/0,Headscale 明确批准后默认仍由客户端选择none;不得把 Exit Node 当作控制面高可用或自动默认出口。
备用控制面启用不改变 RR 的唯一写权威,也不把 102 升级为第二 Runtime、第二调度器或第二认证数据库主节点。任何写操作必须回到 RR;RR 不可写时系统保持只读降级,不能伪造成功。
主机范围判定门禁
所有主机级操作(备份、升级、回滚、容量处理、服务重启和恢复)必须在执行前按以下顺序建立并记录范围:
- 当前执行主机:在本地或 SSH 会话中读取
hostname、目标地址和必要的主机指纹;切换主机后不得沿用上一主机的未验证状态。 - 节点角色:依据
tools/node-registry/registry.json、docs/node-role-capability.md和架构原文确认主机角色(例如 101 为项目交付与发布协调,RR 为生产控制面)。primary_role、service_roles、capabilities、operational_state必须分开读取;旧的role/node_type仅作兼容展示,不得作为部署范围判断依据。 - 规则适用范围:回到规则原文确认该路径、设备、凭据或动作是否明确限定于当前角色;不得仅凭“生产”“备份盘”等关键词套用其他主机规则。
- 目标路径/设备:只在适用范围成立后检查
findmnt、设备、挂载、容量和服务状态;发现范围不匹配时记录为“不适用”,不得把缺失路径当作故障。
交接摘要、旧报告和模型记忆只能作为待核验线索,不能覆盖架构原文或现场证据。任何摘要中的主机、设备、路径或完成结论,在执行前都必须按上述四步重新核验;核验记录至少包含 hostname、节点角色、规则引用、目标路径/设备和结论。生产变更计划必须显式列出涉及主机及其备份边界,禁止把 101 的 /srv/codex-hub-backup 或 /dev/sda1 要求传播到 RR。
RR 备份与容量审计策略
- RR
/backup当前与根分区共用/dev/vda2,属于本地系统盘,不是独立备份盘;本地快照只用于短期恢复演练,不能替代 101 独立盘或异机副本。 - 生产备份默认保留 14 天;超过保留期的归档只能在确认已有独立/异机副本、校验和及恢复记录后清理。容量达到根分区 80% 时告警,达到 90% 时停止非必要构建、清理和发布动作,先归档或扩容。
scripts/maintenance/agentmeshos-rr-backup-capacity-audit.sh是只读审计入口,输出挂载来源、容量阈值、保留周期和禁止清理对象;它不删除文件、不清理镜像、不触碰卷、凭据、生产数据或 Codex 系统数据。- 101
/srv/codex-hub-backup仍是项目恢复材料的独立落点,执行写入前必须用findmnt确认来源为/dev/sda1。RR 本地系统盘发生容量告警时,不得静默把备份改写到其他未验证路径。
🧾 当前审计记录(2026-08-31)
- 101 现场确认
/srv/codex-hub-backup来源为/dev/sda1(独立备份盘);/backup来源为系统盘/dev/nvme0n1p2。 - RR 现场确认
/backup与/var/lib/agentmeshos均来源于系统盘/dev/vda2,当前根分区使用率约 57%;RR 尚未配置独立备份盘,因此 RR 本地备份不能替代异机或 101 独立备份。 - RR 当前保留四个当前组织无状态服务的运行镜像和 rollback alias;2026-09-24 02:25 CST 现场为 29 个唯一镜像 ID、34 个
repository:tag引用、12 个容器(11 个 running、1 个 Headplane 本地回退),其中当前组织 rollback alias 为 4 个;旧ghcr.io/michaellab7284/前缀还有 14 个受latest/rollback保护的引用,不能在没有逐项回滚路径结论时删除。docker system df显示 1.993 GBRECLAIMABLE,但v1.1.1清理脚本的最终只读 dry-run 为 0 个安全候选,因此该数字不能直接当作可删除空间;107 个旧 SHA 白名单已在上一维护轮完成核验和实际回收。 - 本地 rollback 不是完整历史归档,而是部署前把上一版 image ID 标记为本机
rollback。RR 本地只保留每个可回滚服务一个已经验证的 rollback;更早 SHA 交给 GHCR 版本历史保存,不能把 RR 根盘当作长期镜像仓库。 - 2026-09-24 GHCR 只读可见版本数为 Docs 252、Console 87、Status 69、API 93。仓库当前尚未配置和验证自动 package retention;在该策略落地前,保留这些远端历史版本,禁止以“本地已有 rollback”为理由删除远端版本,也不能承诺其永久可回抓。
- 2026-09-24 Linux 日志基线收敛到源脚本
v1.0.4:独立/etc/logrotate.d/agentmeshos-rsyslog-messages使用daily + maxsize 100M + rotate 7 + compress,/var/log/messages从通用 rsyslog 配置中移出;journald 固定SystemMaxUse=1G、SystemKeepFree=2G、MaxRetentionSec=14day。现场部署矩阵如下,均为实际apply后回读:
| 节点 | logrotate 身份 | 回读时间 | messages |
journald |
|---|---|---|---|---|
| 101 | su root syslog |
2026-09-24 02:41 CST | 活动约 8.2 KiB,首份归档压缩后约 68 MiB | 572.7 MiB |
| RR | su root syslog |
2026-09-24 02:25 CST | 活动约 617 KiB | 1002.0 MiB |
| mm | su root adm,安装 logrotate 3.18.0 |
2026-09-24 02:40 CST | 活动约 1.7 KiB,首份归档压缩后约 14 MiB | 320.0 MiB |
| dd | su root syslog |
2026-09-24 02:40 CST | 活动约 12 KiB,首份归档压缩后约 13 MiB | 40.0 MiB |
- 2026-09-24 RR Docker 清理已完成并在
v1.1.1做最终复核:修正后的脚本先以 103 个白名单候选把镜像条目从 138 降到 35;第二轮确认旧api-gateway、status-site停止回滚容器不在任何脚本、systemd 或 timer 回滚路径中后,删除 6 个历史容器并回收其独占旧 SHA,镜像条目降到 29。所有容器引用的 image ID 均存在,当前组织 rollback alias 与 Headplane 本地回退容器保留。根盘使用率从 77% 降到 68%,当前可用约 18 GB;本机 Docs、Console、Status、API 四个入口分别回读 HTTP 200。v1.1.1通过bash -s -- --dry-run在 RR 回读为 0 个安全候选,因此没有执行第二次 apply。 - 2026-09-24 02:25 CST RR 资源基线为物理内存 3.8 GiB、used 1.4 GiB、available 2.4 GiB,swap used 1.9 GiB;Bridge
codex-host-bridge-node.servicecgroup 约 30 MiB,OmniRouteagentmeshos-omniroute.servicecgroup 约 540 MiB、启动后峰值约 1.5 GiB、swap 约 992 MiB。03:15–03:38 CST 曾为gemini-web、出口切换和计划内服务恢复发生多次重启;期间一次 chunk 语法错误使/healthz=500,随后恢复。该时间窗的历史 PID 已被后续重启替代,2026-09-24 只读复核当前为官方3.8.50、PID3846136、NRestarts=0、/healthz=ok;本轮没有修改 OmniRoute 包、没有重新编译、没有再重启服务。Gemini Web 会话已通过官方 PATCH 恢复为 active,生成入口实测 HTTP 200 并返回 Google 图片 URL;但该 URL 在直连、MM 出口、Playwright 与curl_cffi变体中均返回 HTTP 403 HTML,不是可解码图片。b64_json生成返回 HTTP 502,原因是远程图片下载403;官方/v1/images/edits对gemini-web返回 HTTP 400。因此当前正确口径是“Cookie 和生成请求通过,端到端图片取回和编辑未通过”,不能写成图片生成/编辑均可用。 - 2026-09-24 Host Bridge 原项目完成
v0.4.41根因修复、发布与多节点对齐:源仓库main=fd8c2f7、tagv0.4.41→fa8115c,最终 CI run35910672755成功;修复 stale Gateway 只增不减、重复 retry、initialize 超时缺失和 scan 重入,node --test12/12,1000 轮 soak 中 FD 23–25 持平、RSS 预热后持平。101 与 RR 已实际部署;RR 自 01:48:48 起 02:11–03:22 的 60 分钟以上只读窗口内无重启,MemoryCurrent约 14–34 MB、峰值 38.4 MB、FD 22→23,增长与summer(100.64.0.12)上线及 03:07 重连一致,不是单调泄漏;旧100.64.0.16尝试为 0,connect/initialize timeout 为 0。Home 与 summer 已复核为 Windows Bridge0.4.41并分别监听4545/4546;officesummer 仍离线,由 101 的小时级 pending patrol 保留唯一待部署项;mm/dd 无 Host Bridge 安装,103 不可达。 - RR 现有定时器包含 Nomad 备份,但未发现统一的生产数据历史保留/归档定时器。该缺口不改变单节点生产边界,后续必须补充保留周期、异机副本和容量告警证据后才能宣称备份闭环完成。
- 2026-08-31 RR 只读复核:
/backup来源为/dev/vda2,根分区使用率 58%,可用约 23.9G;审计脚本和契约测试通过。当前仍只有本地系统盘快照,异机/101 副本与定时归档尚未宣称完成。 - 当前 Stateful 运行对象仍未达到不可变版本放行条件:AI Runtime 使用缩写标签
sha-c650a07,Auth Site 和 CLI Agent Gateway 使用latest。三者必须在各自业务门禁完成后切换到完整 40 位 SHA 标签,并分别验证回滚;在此之前不得纳入自动生产升级。
AgentRouter 自定义通道 Smoke(2026-08-31)
- RR CLI Agent Gateway 使用当前生产凭据执行了两次真实文本对话 Smoke:Claude CLI 与 Codex CLI 均使用
deepseek-v4-flash并返回status=passed。 - 两个结果分别登记为
managed=true、available=true的自定义通道;它们不进入静态系统后端目录,OmniRoute仍是唯一system_managed通道。 - 本证据只放行长期供应的
deepseek-v4-flash自定义通道,不代表claude-opus-4-8、claude-opus-5、glm-5.3或gpt-5.6-sol在限量供应波动期间持续可用;这些模型必须各自重新执行真实对话 Smoke 后再启用。 - 该 Smoke 不改变 CLI Gateway 尚未接入自动生产升级的结论;完整 SHA 镜像、独立回滚和 Runtime 主链路不受影响。
🔁 单节点故障恢复顺序
在第二生产节点和公网入口切换演练完成前,RR 只按“单节点生产、可恢复、非高可用”运行。整机故障时的正式恢复顺序固定为:
- 先从独立管理路径确认 RR 不可用,并冻结旧节点的发布、定时任务和写入动作;不得把 Tailnet 代理当作生产接管路径。
- 在接管节点恢复同版本的 Docker、Nomad、网络和 TLS 基础配置,校验固定提交 SHA 的镜像与 release bundle;不得从临时工作树构建。
- 先恢复 Runtime、Auth 和 CLI Gateway 的数据目录与 root-only 凭据边界,再按依赖顺序启动 Cloudreve 生产载荷、System Operations Bridge、Runtime、Auth、CLI Gateway 和四个无状态服务。
- 恢复公网 DNS/入口后,依次验证 Auth 会话、Runtime 旧任务/对话/成果读取、Nomad 调度、Cloudreve 数据面和四个无状态服务健康;任一项失败都停止放行并保留回滚证据。
- 最后核对 Console、Docs、Status、API 返回的版本、节点职责和实际运行镜像,并记录接管节点、DNS TTL、数据快照、凭据恢复范围和每一步时间戳。
该顺序目前是冻结的恢复规范,不代表已完成第二节点接管或 DNS 切换实测;在实测证据形成前,任何发布成功都不能被解释为高可用能力。
⚠️ 未决项 / 需要决策
| 事项 | 当前事实 | 下一步 |
|---|---|---|
| 102 只读备用 | P16 已完成认证快照、同会话密钥、只读写拒绝、Console/API 和 Edge 回退 | 已归档;后续漂移按新运维事件复核 |
| RR 重启演练 | 已完成真实整机重启、关键容器恢复和回读 | 已归档;不宣称控制面写入高可用 |
| P19 范围 | 后续阶段待新增需求评审 | 保持节点 2095/2096 Tailnet-only;用户提出新需求并完成验收设计后才允许进入实施 |
| Exit Node 默认策略 | 五台目标节点已可选,全部节点默认直连;网络态势分别显示出口能力和正在使用状态 | 后续由客户端显式选择,不自动切换全局默认出口 |