跳转至

阶段十五:AgentMeshOS 多边缘、Tailnet 中继与网络态势韧性整改

阶段状态:已完成并归档

计划状态:已完成

当前工作包:无;P15-5 已完成并归档

📌 结论摘要

P15 在 P14 搜索试点完成后原地叠加,不创建平行计划体系。目标是让公网 Console 不再只依赖 MM 单台 Edge,同时把 Tailnet 的中继层从单一 region 900 扩展为 region 900 至 903,并把 Peer Relay 作为独立路径纳入网络态势。依据是 docs/plans/state.json、现有 DERP Map、Headscale policy、节点权威登记表、#topology 只读快照和 P15 已批准范围;影响是 Edge、DERP 与 Peer Relay 必须分权实现、分项验收,任何一项未取得现场证据都不能写成完成。

本计划的上线顺序为:先完成 P15-0 基线与门禁,再完成 P15-1 拓扑契约,随后建设 P15-2 多个 DERP/Peer Relay 和 P15-3 三台 Edge,最后执行 P15-4 DNS 控制器与 P15-5 总验收。公网切换必须等三台 Edge 全部通过,不以“进程 active”或“DNS 可解析”替代真实的 TLS、回源、浏览器和回退验收。

2026-10-03 实施回读(时点记录):P15-0 至 P15-3 已完成;MM、d02、DD、dog-public 的 Peer Relay 已统一为 UDP 40000 且无静态公网端点,Headscale relay grant 与节点登记表 SHA-256 一致;DERP region 900、901、902、903 均已真实建立连接。101 的 AliDNS 写凭据已就绪,ensure-records 当前幂等回读为 13 条候选、DERP 与 cloud-origin 记录;edge.yohan.fun 在该时点指向 MM。d02、DD、dog-public 的 Nginx、证书链、/verify 回源和核心域名回源均已从各自公网 IP 强制 SNI 回读通过。P15-4 的 101 控制器随后安装为 30 秒 systemd timer;该时点尚未执行真实切流,后续切流、自动切换和回切结果见下方复核记录。RR/MM 整机硬故障演练仍需维护窗口。

2026-10-03 自动切流复核:控制器在 09:37:53 CST 因 MM 的 101/RR 双视角连续三次一致失败,自动把活动候选从 edge-mm 切到 edge-d02,状态中的 last_reason=automatic_after_consistent_failure、last_known_good=edge-mm。自动切换后下一轮评估为 failures=0,未因递归 DNS 的旧 MM 缓存继续级联到 DD。演练结束后已执行 rollback,权威 A 恢复 MM 当前运行时地址。

2026-10-03 整机硬故障与 RR 冷启动修复:MM 内核 panic 后,101/RR 双视角连续三次一致失败,控制器真实切到 edge-d02;随后 rollback 回 MM。RR 内核 panic 后公网 SSH 约在 11:04:37 至 11:07:26 不可达,恢复时暴露出四个控制面冷启动根因:Tailnet 恢复使用依赖 RR 自身回源的 https://mesh.yohan.fun,形成登录循环依赖;私有回源 staged 配置缺失后符号链接悬空;Docker 早于 100.64.0.1 就绪,Console/Docs/Status/Runtime 因 Cannot assign requested address 退出;站点部署脚本从正在故障的 docs.yohan.fun 获取清理脚本且无条件拉取镜像,无法在冷启动时自愈。修复后 Tailnet 登录改用本机 http://127.0.0.1:39088,一次性 auth key 通过 0600 临时文件传入;私有回源有 /backup/agentmeshos/reboot-resilience/last-known-good 自动恢复;Docker 增加 Tailnet 就绪 ExecStartPre;站点部署优先使用本机清理脚本并在镜像已存在时跳过拉取。RR 恢复后公网 console/mesh/docs/status/cloud、systemd 失败单元和容器健康均已完成回读。

🧾 计划状态

项目 当前值 依据
当前阶段 P15 docs/plans/state.json
阶段状态 已完成并归档 用户已批准并按 P15 实施完成
计划状态 已完成 工作包、契约、门禁和回退边界已冻结
当前工作包 无;P15-5 已完成并归档 真实切流、回切、观察者故障、自动切换、MM/RR 整机硬故障、RR 冷启动修复、AAAA 删除/恢复、IPv6 客户端复核和远端发布门禁均已通过
上一阶段 P14 已完成并归档 OmniRoute 搜索 MCP 双监听和三工具主链路可用
生产边界 RR 只保留控制面 RR 不承担公网 Edge、DERP 或 Peer Relay

🧱 技术栈与架构选型

Edge、DERP 和 Peer Relay 是三个正交能力。Edge 负责公网 DNS、TLS、Nginx 与回源;DERP 负责 Tailnet 在无法直连时的官方中继;Peer Relay 是普通 Tailnet 节点通过 --relay-server-port 提供的中继能力,由 Headscale 的 tailscale.com/cap/relay grant 精确授权。三者可以部署在同一公网节点上,但不能因为同机就合并健康结论。

候选 Edge DERP Peer Relay 结论
MM 当前主 Edge region 900 UDP 40000 保留并删除静态公网端点表达
d02 建设候选 region 902 UDP 40000 与 DD、dog-public 同步建设
DD 建设候选 region 901 UDP 40000 先做 Cloudreve 与端口冲突门禁
dog-public 建设候选 region 903 UDP 40000 保留宝塔、Nginx、Shadowsocks Rust 现状
RR 排除 排除 排除 只保留 Headscale、Runtime 和控制面

Headscale 继续是 Tailnet 控制面,但不是业务高可用替代品。RR 离线后,已有 Tailnet 会话和 DERP 路径可能继续工作,但新节点注册、ACL 更新和 DERP Map 下发仍依赖 RR。公网 Console 在 MM 或活动 Edge 故障时,恢复依赖 Edge DNS 切换,不依赖 Peer Relay。

🎯 目标、成果与验收契约

工作包 目标 验收依据
P15-0 完成 P14 收口、任务叠加和资格矩阵 已完成:state.json、归档清单、节点端口与资源只读登记一致
P15-1 修正网络态势字段、拖动、分道和能力徽标 已完成:采集器、Gateway、域名详情、浏览器契约和聚焦回归通过
P15-2 扩展 region 900 至 903 与 Peer Relay 已完成:四区 DERP 连接、Peer Relay 服务列表和精确 ACL 已验证;region 900 已改用 MM 专用 derp-mm.yohan.fun
P15-3 建设三台同源 Edge 已完成:证书链、核心域名回源、端口和重启持久性证据已建立
P15-4 101 控制 DNS,RR 只读监督 已完成:真实 MM → d02 切流、核心域名验证和回切均通过,执行锁与活动地址状态一致
P15-5 测试、发布、真实切换和回退 已完成并归档:观察者故障、自动切换、回退、stale-DNS、DERP 域名解耦、MM/RR 整机硬故障、RR 冷启动修复、AAAA 删除/恢复、IPv6 客户端复核和远端发布门禁均已通过

拓扑快照继续使用 agentmeshos.network-topology/v1。节点新增 display_alias、capabilities、relay_region_id、peer_relay_port、edge_domain 和 derp_domain;链路新增 peer_relay 路径类型。别名最多 4 个 ASCII 字符或 3 个中文字符,完整名称保留在节点下方和详情面板。节点详情固定展示 Edge 域名和 DERP 域名,避免把长域名塞进节点圆圈;浏览器布局仍只保存在 agentmeshos.topology.layout.v1,不把位置写入服务端。

Dashboard 画布使用 1200x720 逻辑空间,节点拖动边界为 x=42..1158、y=42..650。普通连线使用 2px,选中线为 3px,流动层为 1px,可见线与流动层使用 vector-effect: non-scaling-stroke,点击热区继续 18px。浏览器契约同时断言可见线与透明热区的计算样式,防止路径颜色再次回写到点击热区。Console 的 CSS 引用使用构建内容哈希,防止生产继续缓存旧样式。同一节点对的链路必须使用稳定分道,DERP 与 Peer Relay 不得合并成同一类型。

🧩 分布式底座接入声明

  • 接入结论:接入。
  • 使用层:Network、Compute、Observability 和 docs-governance。
  • Scheduler:Nomad 仍是唯一任务调度器;DNS 控制器和巡检 timer 不是调度器。
  • Compute:RR、101、102 现有职责不变;d02、DD、dog-public 按 Edge 画像逐台门禁。
  • Storage:不迁移 Cloudreve 数据,不复制业务后端,不在仓库写入 DNS 凭据。
  • Credentials:AliDNS 写凭据只存在 101 的 root-only 0600 文件;RR 不保存写凭据。
  • Lifecycle:控制器和 timer 不是任务审批对象,任务状态不设置人为过期时间。
  • Evidence:端口、证书、DNS、健康、故障和 rollback 证据必须来自现场。

🛠️ 工作包与依赖

P15-0 已读取节点权威登记表、DNS、端口、Headscale policy、当前 DERP Map、证书和业务占用,形成机器可校验能力矩阵。资格不满足的节点保持 blocked 并记录原因,不为了凑齐三台 Edge 放宽端口或资源边界。2026-10-03 现场门禁为:MM 可用内存 614 MiB、根盘余量 6.3 GiB;d02 为 1429 MiB、22.5 GiB;DD 为 1325 MiB、884 GiB;dog-public 为 2619 MiB、19 GiB。四台候选的 443/tcp、39478/udp、40000/udp 均未发现冲突。

P15-1 已改仓库代码并以现有只读快照为唯一数据源。P15-2 在 MM、DD、d02、dog-public 上使用同源官方 derper;稳定域名使用 derp-mm、dd、d02、dog,443/TCP 由 Nginx 承接,39478/UDP 由官方 derper STUN 承接。region 900 至 903 均已通过 tailscale debug derp 建立真实连接。Peer Relay 使用 40000/UDP,MM、d02、DD、dog-public 的 RelayServerStaticEndpoints 均已清空;服务列表返回 100.64.0.3/5/6/9,无活动 session 时按“服务已发布、当前无连接需求”显示 healthy,而不是误报故障。

P15-3 建设 d02、DD、dog-public 的同源 Nginx、ACME、防火墙、SSH 双入口、健康端点和核心域名回源。核心域名为 mesh/cloud/auth/console/docs/status/api/omni/nomad/ai。三台节点 nginx -t 通过,443/tcp、39478/udp、40000/udp 在监听;Let's Encrypt 证书覆盖 10 个核心域名和本机 DERP 域名。以各自公网 IP 固定 SNI 回读时,mesh/auth/console/api/nomad 返回 302,cloud/docs/status/ai 返回 200,omni 返回 307。cloud-origin.yohan.fun 指向 DD,www.threedogs.vip 仍单独保留证书和跨厂商 DNS API 门禁。

P15-4 使用 edge-mm/edge-d02/edge-dd/edge-dog.yohan.fun 作为稳定候选,edge.yohan.fun 是唯一活动入口;10 个核心域名均为指向 edge.yohan.fun 的 CNAME。101 以本地和 RR 双视角检查,只有连续三次一致失败后才调用 AliDNS 基础 OpenAPI。健康探测使用 mesh.yohan.fun 作为稳定 TLS/HTTP 身份,并强制连接到候选 IP,避免把未签发 edge-*.yohan.fun SAN 误判为候选故障。账号拒绝 60 秒 TTL,活动记录和候选记录统一使用 600 秒。控制器已修正候选短名解析、TLS SNI、RR stdin、首次状态身份、权威活动地址回读和执行锁竞争。真实切流后 10 个核心域名在 d02 回读通过;随后 rollback 回 MM,旧 TTL 退净后权威记录和核心域名恢复 MM 当前运行时地址。切流前回退包为 /root/.codex/backups/p15-4-cutover-20261003T010701Z。控制器现已把 A/AAAA 作为同一活动记录集处理,切换 d02/DD 时删除 AAAA,切换 MM/dog 时恢复或更新 AAAA。

2026-10-03 额外修复:mesh.yohan.fun 原先只在 IPv4 监听,IPv6 被默认站点接管后返回错误证书,导致 MM 和 dog 的 Tailscale 登录失败。MM 已追加 IPv6 80/443/quic 监听并 reload,MM、dog 恢复为 BackendState=Running;仓库新增 agentmeshos-mm-edge-ipv6-guard.sh 和负向回归,防止 Nginx 模板重建后再次丢站。

2026-10-03 DERP 准入修复:d02、DD、dog-public 的 Nginx 首版只代理 /derp,遗漏了 derper 的 -verify-client-url 所请求的 /verify。现场表现为本机 127.0.0.1:39479/verify 返回 200,但公网 DERP 域名 /verify 返回 404,agentmeshos-derp-edge 持续记录 admission controller: 404 Not Found,RR 对 d02 region 902 报健康告警。现在 DERP vhost 显式把 POST /verify 回源到主节点私有网关 100.64.0.1:39200,固定 Host: mesh.yohan.fun;部署脚本增加真实 /verify 探测门禁,缺少该路径时直接阻止 apply。修复后四个 region 的 tailscale debug derp 均建立连接,RR Health=[],拓扑恢复 33 healthy / 0 unknown。

2026-10-03 拓扑线宽与域名回读:用户看到的粗线根因是 18px 透明点击热区也被路径颜色类命中,后面的 .topology-link--* 规则覆盖了 transparent,因此 .375px 可见线并未成为用户实际看到的粗线。修复后路径颜色只作用于 .topology-link,浏览器契约要求热区 stroke=rgba(0,0,0,0);节点详情继续显示 Edge 域名、DERP 域名、DERP Region 和 Peer Relay 端口。生产 Console sha-e253297 的 styles.css SHA-256 为 0f6f5a5c1c5002d1bf0c00e57aafc268178575118f032f3cc2d4b3e8913e4117。

2026-10-03 DNS 控制器锁修复:此前 systemd 使用外部 flock,而手工执行的 show/check/switch/rollback 不共享同一排他锁,存在定时评估与手工切换并发覆盖状态的窗口。控制器现在自行持有 root-only /run/agentmeshos-edge-dns-controller.lock,所有子命令进入前均做非阻塞排他锁;状态新增 active_address,回退同时恢复候选和实际地址。101 已安装与仓库一致的 SHA-256 471f9f330337b2e37faa29e20a049fdc0c137f9b850747c286ec4a26c126d804,事件 30 秒 timer 已恢复 enabled/active,最近多轮评估均为 failures=0。

2026-10-03 定时锁竞争防复发:真实运行发现健康探测单轮约 14 秒,旧的 OnUnitActiveSec=30s 会与手工 show/check/switch 争抢执行锁,使 timer 当轮以 lock_busy 失败。systemd service 现使用 evaluate --defer-lock-busy,锁被手工操作占用时明确输出 edge_dns=deferred reason=lock_busy 并以成功状态让出本轮;timer 改为 OnUnitInactiveSec=30s,只在前一轮完成后重新计时。安装测试同时门禁 service 和 timer 两处配置,真实锁竞争回归证明自动评估退出码为 0,手工操作仍返回 lock_busy 并拒绝并发写。

2026-10-03 活动地址探测修复:控制器改为先读取 AliDNS 权威 A 记录或状态中的 active_address,再强制探测该候选 IP;旧版本通过公共 DNS 主机名探测,解析缓存可能仍返回切换前的 MM,导致已切换后的健康判断失真。回归测试覆盖“当前活动 d02 时必须探测 1.0.0.1 而不是再次使用无地址主机名”,并保留未知活动地址的直接探测路径。

2026-10-03 拓扑候选对等修复:生产快照中 dog-public 有 public-three-dogs 公网 HTTPS 和 public-ssh-dog-public 公网 SSH,而 d02 没有到 GW/edge 的边,根因是采集器缺少 d02 的公网 HTTPS 端点与 SSH 别名。现在 PUBLIC_HTTPS_ENDPOINTS 使用真实的 https://d02.yohan.fun/__edge/health 探测 d02,SSH_PATH_ALIASES 增加 d02,并在浏览器契约中固定候选 Edge 必须按真实能力显示公网 HTTPS、公网 SSH 和独立分道。MM 同样补入真实的 https://derp-mm.yohan.fun/__edge/health,与 public-ssh-mm 形成两路径;Three Dogs 的 www.threedogs.vip 业务探测继续保留,不把不存在的业务链路补到 d02。

2026-10-03 域名语义复核:网络态势新增可展开的域名与中继说明,分别列示活动 Edge、四个候选 Edge、十个核心公网入口、DERP region 900 至 903 和 cloud-origin 的用途。复核发现 mesh.yohan.fun 曾同时是核心公网 CNAME 和 region 900 DERP 域名,自动切换后会跟随 edge.yohan.fun 改变物理落点。该耦合现已通过 MM 专用 DERP 域名整改消除,历史状态不再作为当前风险描述。

2026-10-03 专用 DERP 域名解耦:新增 derp-mm.yohan.fun,AliDNS 权威 A/AAAA 均只指向 MM;MM 使用现有 acme.sh 3.1.6 以 HTTP-01 webroot 签发单域名证书并安装到宝塔证书目录,续期 cron 已执行 --cron 空跑且确认下一次续期为 2026-12-01T18:03:38Z。/__edge/health 返回 derp-mm,POST /verify 回源 Headscale;RR 的 /etc/headscale/derp-mm.yaml 已将 region 900 hostname 改为新域名,文件 SHA-256 从 31a2975b...e2e0 变为 3df32942...1f6f,headscale configtest 和受控重启通过。101、RR 的 tailscale debug derp 900 均成功建立 DERP connection 并返回 IPv4 STUN 响应;mesh.yohan.fun 继续只承担核心公网入口和 Headscale 身份,不再决定 region 900 的物理落点。

2026-10-03 AAAA 双栈切换收口:控制器已实现“候选缺少公网 IPv6 时删除 edge AAAA、目标候选具备 IPv6 时更新或补建 AAAA、回切恢复 last-known-good IPv6”的确定性路径,并在 API 失败时自动回滚 A 与 AAAA。edge-dns-controller-test.py 已用假客户端覆盖 d02 删除 AAAA、DD 无 IPv6、切换 dog 补建 AAAA、回切 d02 删除 AAAA、稳定回切 MM 恢复 AAAA、A 或 AAAA 更新失败后双栈恢复,以及非法 IPv6 拒绝;101 实装脚本与仓库源码 SHA-256 均为 7f954523c9c966d4f30c326d9b9ce7e4a30f08f97eb4e4b191f469ebc57fd5bb。真实 MM → d02 切换后 show 回读 active_ipv6_address=null,rollback 后恢复 MM A/AAAA;递归 DNS 的旧 AAAA 仍会按既有 600 秒 TTL 自然退净,不能把缓存未过期误报为控制器失败。

2026-10-03 IPv6 客户端最终复核:受控切到 d02 后,223.5.5.5 的公共递归答案在第 29 轮等待时退净旧 MM AAAA;此时 curl -4 访问 console.yohan.fun 返回 302 且落点为 d02 运行时公网 IPv4,严格 curl -6 以退出码 7 失败,证明客户端不再命中已失效的 MM IPv6。随后 rollback,223.5.5.5 与 1.1.1.1 均恢复为 MM 当前运行时 A/AAAA,timer 恢复 enabled/active。公网地址属于运行时数据,不写入仓库。

P15 已完成并归档。MM/RR 整机硬故障已经真实执行,RR 恢复后暴露的四个冷启动根因已完成代码修复、提交 7125931、Actions/101 Runner/RR 生产部署和现场回读;P15-5 的发布门禁已经闭环。多 Edge、DERP 和 Peer Relay 只提高入口与中继冗余,不复制 RR 上的 Console、Auth、API 和 Runtime 后端,因此 RR 后端整机不可用时,完整控制台登录仍会中断;该缺口不在归档范围内追补,已经转入 P16 控制面后端冗余。

🧪 测试与回退

拓扑测试必须覆盖别名长度、完整标签、Edge/DERP 域名说明、画布边界、刷新恢复、自动布局、可见线与热区分层、多线分道、Peer Relay 筛选和敏感字段泄漏负向回归。采集器与 Gateway 要拒绝非法别名、非法域名、未知能力、非法 region、伪 Peer Relay 和敏感字段。

DERP 要分别验证 region 900、901、902、903 的 debug derp 和客户端连接;region 900 还必须验证独立域名、独立证书、续期、Headscale 重启和 DERP map 回读。Peer Relay 要验证服务列表、活动会话、精确 ACL、无静态公网端点、单节点失效和重启恢复。DNS 控制器要验证正常、缺凭据、API 401、非法 IPv4/IPv6、连续失败、证据冲突、A/AAAA 切换、回切、回滚和部分写入后的双栈恢复。三台 Edge 要分别验证 SSH 双路径、Nginx -t、证书链、核心域名回源、浏览器登录和重启恢复。

回退分为四层:Edge 配置返回 last-known-good;DNS 控制器使用 last-known-good 和 rollback;DERP/Peer Relay 按区域独立停用,不关闭其他 region;发布回退使用提交、Action、101 Runner 和 RR 镜像的上一次成功点。任何回退都不得删除凭据、业务数据或历史归档。

⚠️ 未决项 / 需要用户决策

事项 当前事实 下一步
AliDNS 写凭据 凭据、ensure-records、真实切流、自动切流和回切均已完成;当前权威 A/AAAA 为 MM 保持 30 秒评估、stale-DNS 回归和 rollback 路径
三台 Edge 资格 资源、磁盘、Nginx、证书链和核心域名回源通过 保持重启与长期健康证据,不通过时继续自动排除
DERP region 900 至 903 region 900 已改用 derp-mm.yohan.fun,四区均真实连接,Headscale 已下发四区 保持逐区故障隔离、证书续期和重启恢复证据
Edge IPv6 切换 控制器已通过单测、真实切流/回切和公共递归 TTL 退净后的 IPv4/IPv6 客户端复核;回滚后 MM A/AAAA 已恢复 保持双栈状态回读;若要缩短 600 秒切换窗口,需另行评估全候选 IPv6 或更低 TTL 的 DNS 产品
RR/MM 整机硬故障演练 MM panic 后 Edge 自动切换与回滚通过;RR panic 后公网入口真实中断并恢复,四个冷启动根因已修复和回读 已归档;后续控制面备用在 P16 中原地叠加,不重新打开 P15
Console 后端冗余 Edge、DERP、Peer Relay 均不复制 RR 上的 Console、Auth、API 和 Runtime 后端;RR 主机不可用时完整登录仍中断 已转入 P16;不要用继续增加 Edge 的方式冒充控制面后端高可用
www.threedogs.vip 跨厂商 DNS 与证书自动续签未闭环 单独门禁;未通过不纳入 Edge 高可用