baa-conductor

git clone 

baa-conductor / coordination / tasks / done
im_wower  ·  2026-03-22

T-025-failover-rehearsal.md

  1---
  2task_id: T-025
  3title: Failover rehearsal 与 Runbook
  4status: done
  5branch: feat/T-025-failover-rehearsal
  6repo: /Users/george/code/baa-conductor
  7base_ref: main@6505a31
  8depends_on:
  9  - T-019
 10  - T-021
 11  - T-022
 12write_scope:
 13  - docs/ops/**
 14  - scripts/failover/**
 15updated_at: 2026-03-22T02:16:15+0800
 16---
 17
 18# T-025 Failover rehearsal 与 Runbook
 19
 20## 目标
 21
 22把当前主备设计推进到“有可执行 rehearsal 步骤和清晰运维 runbook”的程度。
 23
 24## 本任务包含
 25
 26-`scripts/failover/**` 下补 failover rehearsal 辅助脚本
 27-`docs/ops/**` 下补 planned failover / emergency failover / switchback runbook
 28- 把 Tailscale `100.x`、公网域名、launchd、Nginx 的配合关系写清楚
 29
 30## 本任务不包含
 31
 32- 修改 app 业务代码
 33- 真实执行线上 failover
 34- 修改 `baa-firefox`
 35
 36## 建议起始文件
 37
 38- `docs/ops/README.md`
 39- `scripts/failover/`
 40
 41## 交付物
 42
 43- 可执行或半自动的 rehearsal 辅助脚本
 44- 清晰的 failover 运维手册
 45
 46## 验收
 47
 48- 如果新增 shell 脚本:`bash -n scripts/failover/*.sh`
 49- `git diff --check`
 50- 文档里明确 planned / emergency / switchback 三种路径
 51
 52## 更新要求
 53
 54完成时更新 frontmatter 的:
 55
 56- `status`
 57- `base_ref`
 58- `updated_at`
 59
 60并补充下面这些内容:
 61
 62## files_changed
 63
 64- `coordination/tasks/T-025-failover-rehearsal.md`
 65- `docs/ops/README.md`
 66- `docs/ops/failover-topology.md`
 67- `docs/ops/planned-failover.md`
 68- `docs/ops/emergency-failover.md`
 69- `docs/ops/switchback.md`
 70- `scripts/failover/common.sh`
 71- `scripts/failover/print-topology.sh`
 72- `scripts/failover/rehearsal-check.sh`
 73- `scripts/failover/print-checklist.sh`
 74
 75## commands_run
 76
 77- `npx --yes pnpm install`
 78- `chmod +x scripts/failover/*.sh`
 79- `bash -n scripts/failover/*.sh`
 80- `./scripts/failover/print-topology.sh --env scripts/ops/baa-conductor.env.example`
 81- `./scripts/failover/print-checklist.sh --scenario planned --env scripts/ops/baa-conductor.env.example`
 82- `./scripts/failover/rehearsal-check.sh --env scripts/ops/baa-conductor.env.example --skip-public --skip-control-api`
 83- `git diff --check`
 84
 85## result
 86
 87- 新增 `scripts/failover` 只读辅助脚本,用于输出主备拓扑、生成场景化 checklist,并对 public/direct/control-api 做 rehearsal 校验。
 88-`docs/ops` 下补齐 failover topology、planned failover、emergency failover、switchback 四份文档。
 89- runbook 明确写清 Cloudflare DNS 固定到 VPS、VPS Nginx 回源 Tailscale `100.x`、节点 `launchd` 控制本地 conductor 存活,以及当前 Nginx 只按连通性而非 lease 感知切换。
 90
 91## risks
 92
 93- 当前 `GET /v1/system/state` 仍只返回扁平 `holder_id/mode/term/lease_expires_at`,脚本只能通过 `holder_id` 前缀推断 leader 节点。
 94- 当前没有真正的 `promote/demote` 维护接口;planned failover 和 switchback 仍依赖 `pause/drain` 加本机 `launchctl bootout/reload` 95- 如果 mini 仍可达但逻辑上不该接流量,公网入口可能仍命中 mini;emergency runbook 已记录这种情况下需要 VPS Nginx 热修。
 96
 97## next_handoff
 98
 99- 在真实节点或 staging 上按 runbook 做一次 dry-run / rehearsal,确认 `mini`、`mac`、VPS 三侧命令、权限和路径与文档一致。
100- 后续可补 `system.state` 的 leader host 字段,以及真正的 maintenance `promote/demote` API,减少对人工 `launchctl` 与 Nginx 热修的依赖。