feat: add ops center and node onboarding flow

This commit is contained in:
Your Name
2026-04-18 23:52:51 +08:00
parent 246838ae4c
commit b9c29481b5
142 changed files with 89727 additions and 186 deletions

View File

@@ -0,0 +1,708 @@
# 21 domainCheck 海外主机集中运维与自动化方案
如果当前你不是在做“为什么要这么设计”的方案评审,而是已经进入真实收口、准备上线阶段,建议先跳转:
- `docs/25_domainCheck_海外单脑控制面上线收口总表.md`
- `docs/23_domainCheck_终局运维架构设计_海外单脑控制面.md`
- `docs/24_domainCheck_NodeAgent协议与ReleaseHub设计.md`
## 一、为什么要升级成“集中运维”
这段时间的多机联调已经证明一个事实:
- 现在这套“人在海外主机上看后台,再去大陆机器上手工跑命令、复制日志、判断状态”的方式,能联调,但效率很低
- 一旦节点数从 `2` 台增加到 `3` 台、`5` 台、`10` 台,复杂度会快速失控
- 国内机器上又不能稳定部署 Codex因此不能指望每台机器都具备“本机智能调试能力”
- 检测日志很大,靠人工复制日志片段,不适合做持续诊断
所以后续不应该继续堆更多“检查脚本”,而应该把整个体系升级成:
> 海外主机作为唯一运维控制面,统一接管大陆机器的安装、更新、重启、巡检、日志回流和故障诊断。
一句话目标:
> 只在海外主机操作,大陆机器尽量不需要人工登录。
---
## 二、最终目标形态
### 1. 海外主机承担什么
海外主机作为唯一控制面,承担:
- Web 后台
- API 控制面
- 运维任务中心
- 发布包仓库
- 节点注册与权限中心
- 日志汇聚与诊断入口
- 远程命令编排
- 巡检结果展示
也就是说,后续所有动作都从海外主机发起:
- 新机器纳管
- 初始化安装
- 发布更新
- 配置下发
- 服务重启
- 健康检查
- 采集诊断包
- 远端日志查看
- 故障一键排查
### 2. 大陆机器承担什么
大陆机器不再承担复杂控制逻辑,只承担:
- `domaincheck worker/controller` 本体服务
- 一个轻量 Node Agent
- 本机 systemd / 日志 / 版本 / 健康信息暴露
- 接收控制面任务并执行
- 将执行结果、日志、诊断包回传到海外主机
这意味着大陆机器以后是“被管理对象”,而不是“人工登录操作对象”。
---
## 三、推荐方案
## 方案 A海外控制面 + 大陆 Node Agent
这是我建议的主方案,也是长期最优方案。
### 核心思想
不要把“SSH 到每台机器执行命令”作为主链路,而是让每台大陆机器常驻一个 Agent
- Agent 主动连海外控制面
- Agent 拉取待执行任务
- 本地执行 systemd / shell / 发布 / 巡检
- Agent 把 stdout / stderr / 状态 / 日志游标回传
这样做的好处是:
- 不要求海外机能直接入站打通到大陆机
- 不要求每次人工 SSH
- 不怕 SSH 权限、跳板机、端口变化导致整套流程断掉
- 天然适合 NAT、弱网络、多机扩容
### 交互方式
建议 Agent 使用下面其中一种方式主动连海外控制面:
#### 首选HTTPS 长轮询
- `agent -> overseas-api`
- 周期拉取任务
- 周期上报心跳、版本、服务状态、日志摘要
优点:
- 实现最简单
- 最容易兼容现有 Python / FastAPI 架构
- 容易先落 MVP
#### 可升级WebSocket 常连
- 建立长连接
- 海外控制面可实时下发任务
- Agent 实时回传执行日志
优点:
- 更实时
- 日志流式体验更好
缺点:
- 第一版复杂度更高
### 为什么 Agent 比 SSH 更优
SSH 适合作为:
- 首次 bootstrap
- 临时人工兜底
- 非常规应急
但不适合作为日常主运维链路,因为:
- 节点一多,权限和连通性管理会变得脆弱
- 脚本回显、超时、日志采集很难标准化
- 人工 SSH 本质上还是“远程手工运维”
所以最佳做法是:
- SSH 只用于首次纳管
- 日常统一走 Agent
## 三点五、当前已经落地的第一版操作闭环
这套方案现在已经不只是设计稿,仓库里已经有一批可以直接使用的统一入口:
- `domain-api/deploy/multi-region/init_ops_center_config.sh`
- `domain-api/deploy/multi-region/drive_ops_center.sh`
- `domain-api/deploy/multi-region/drive_release_hub.sh`
- `domain-api/deploy/multi-region/drive_ops_action.sh`
- `domain-api/deploy/multi-region/build_node_agent_bootstrap_plan.sh`
推荐从海外控制面按这个顺序使用:
### 1. 初始化控制面配置
```bash
cd /opt/domaincheck/domain-api
bash domain-api/deploy/multi-region/init_ops_center_config.sh \
/etc/default/domaincheck-ops-center \
http://121.204.244.188:8100 \
http://152.53.37.118:8100 \
https://api.example.com
```
### 2. 查看当前统一配置
```bash
bash domain-api/deploy/multi-region/drive_ops_center.sh config
```
### 3. 在控制面本机生成发布包
```bash
bash domain-api/deploy/multi-region/drive_ops_center.sh release-package
bash domain-api/deploy/multi-region/drive_ops_center.sh release-launchpad
bash domain-api/deploy/multi-region/drive_ops_center.sh release-preview
bash domain-api/deploy/multi-region/drive_ops_center.sh release-preview-smart worker
bash domain-api/deploy/multi-region/drive_ops_center.sh release-show
```
### 4. 导出一份联调/交接报告
```bash
bash domain-api/deploy/multi-region/drive_ops_center.sh doctor-export
```
### 5. 为新节点导出接管计划
```bash
bash domain-api/deploy/multi-region/drive_ops_center.sh agent-plan-export \
/opt/domaincheck/domain-api/runtime/ops-center-reports/agent-plans \
http://127.0.0.1:8100 \
mainland-worker-02 \
mainland \
worker \
https://api.example.com \
/opt/domaincheck
```
这五步对应的意义分别是:
- 先统一控制面默认地址和身份
- 再确认驾驶舱当前在看哪个环境
- 再把发布物、发布前预检和发版驾驶舱都收回统一入口,不再额外记根目录脚本
- 再把现场收敛成可以回看、可以交接的报告
- 最后为新增节点生成标准接管方案
这样后面无论是海外 Codex 自动驾驶、后台按钮,还是人工运维,都不再需要先去大陆机器手工拼命令。
## 三点六、现在发布驾驶舱已经进入统一数据口径
目前发布侧也已经不是零散接口拼出来的状态,而是收敛成了一套统一判断:
- `GET /api/v1/ops/releases/launchpad`
- `ops overview -> release_hub.launchpad`
- `check_release_hub.sh`
- `drive_release_hub.sh launchpad`
- 运维中枢页面里的“发布驾驶舱”
这几处现在复用的是同一套结论,都会统一告诉你:
- 当前是 `ready / attention / blocked`
- 最新发布包是否可用
- 最新 Release 是否已经建立
- Worker 智能灰度是否可发
- Control 发布是否可发
- 下一步推荐动作是什么
同时,`GET /api/v1/ops/runbook` 里的标准作业路径 `release_progression` 也已经切到同一套发布驾驶舱判断。
也就是说,海外控制面看到的“标准作业路径”和“发布驾驶舱”不会再出现一套说能发、一套说先补接管的分裂口径。
现在又往前推进了一步:
- `POST /api/v1/ops/runbook/sequences/{sequence_key}/execute`
后台上的标准作业路径按钮,后续都应该优先走这个入口,再由后端统一分发到 driver action / playbook / rollout 预案,而不是前端自己维护动作分支。
这样后续海外 Codex、后台按钮和命令行脚本拿到的就不再是三套不同口径而是同一套“发布驾驶判断”。
## 三点七、现在回执队列也已经进入统一治理入口
除了发布驾驶舱Node Agent 回执队列这一层现在也已经不再是“只能看、不能管”的状态。
当前已经统一收口成三类入口:
- 页面:
- OpsCenter 托管节点表可以直接打开“回执队列治理”抽屉
- 驾驶建议:
- `dead_letter / retrying` 会优先落到标准动作模板
- 海外单入口 CLI
- `drive_ops_center.sh queue-status`
- `drive_ops_center.sh queue-records`
- `drive_ops_center.sh queue-flush`
- `drive_ops_center.sh queue-replay`
- `drive_ops_center.sh queue-replay-record`
- `drive_ops_center.sh queue-discard-record`
这意味着海外主机已经可以统一处理:
- 哪台节点存在积压 / 死信
- 头部记录是什么
- 什么时候应该立即冲刷
- 什么时候应该重放
- 什么时候应该说明原因后丢弃
当前阶段仍然明确限制为:
- `record_visibility=head_only`
- 所有治理动作都落成正式 `ops job`
- 不直接 SSH 到节点改队列文件
这样以后即使把远端全量死信记录正式投影到控制面,也只是“扩可见范围”,而不是重新推翻当前模型。
---
## 四、这套方案要解决的具体问题
## 1. 安装部署自动化
目标:
- 海外控制面点一次“新增节点”
- 填一个节点模板
- 大陆机器自动初始化
建议流程:
1. 海外后台新增节点
2. 生成 `bootstrap token`
3. 大陆机器只执行一次极短安装命令
4. Node Agent 注册到海外控制面
5. 控制面向该节点下发:
- 拉取发布包
- 解压
- 生成 `/etc/default/...`
- 安装 systemd
- 启动服务
6. 回传安装结果
这样后续加机器时,不需要再重复人工对照文档逐条敲。
## 2. 更新发布自动化
目标:
- 海外主机统一推版本
- 大陆节点自动拉包、灰度更新、失败回滚
这里强烈建议:
> 后续不要让大陆机器自己跑 git 作为正式更新链路。
而是改成:
- 海外控制面构建发布包
- 版本号固定
- Agent 下载指定 release 包
- 校验 checksum
- 切换当前版本软链
- 重启服务
- 回传成功/失败
这样比远程 `git pull` 更稳,因为:
- 不依赖每台机器 git 权限
- 不怕工作区脏文件
- 不怕 root/www 用户混用
- 可回滚
推荐目录形态:
```text
/opt/domaincheck/releases/<version>/
/opt/domaincheck/current -> /opt/domaincheck/releases/<version>/
```
更新时:
- 下载新版本到 `releases`
- 校验
- 切换 `current`
- `systemctl restart ...`
失败就回滚软链。
## 3. 远程命令执行自动化
目标:
- 海外控制面能发“结构化任务”
- 不再让人手工复制命令
建议任务类型:
- `service.start`
- `service.stop`
- `service.restart`
- `service.status`
- `deploy.release`
- `config.render`
- `diagnostics.collect`
- `logs.tail`
- `script.run`
- `health.check`
每个任务统一回传:
- 任务 ID
- 节点编码
- 开始时间 / 结束时间
- exit code
- stdout
- stderr
- 结构化结果 JSON
这样后面后台才能真正做“操作中心”。
## 4. 日志集中回流
目标:
- 海外后台就能看到大陆机器日志
- 不再人工抄 `journalctl`
### 日志回流建议分三层
#### A. 关键事件流
只回传关键事件:
- 服务启动
- 服务重启
- 任务开始
- 任务完成
- 代理刷新失败
- Redis/DB 连接异常
- 第三方站点异常
适合默认长期开启。
#### B. 诊断模式日志流
像你现在提的“关闭 / 关键 / 全量回传”一样:
- `off`
- `key`
- `full`
这是正确方向,应该继续保留。
#### C. 诊断包
当出现疑难问题时,一键打包:
- 最近 N 分钟 `journalctl`
- `runtime/status`
- `runtime/cluster`
- `detect_worker.log tail`
- `/etc/default/*`
- 当前版本号
- 本机健康检查输出
然后上传海外主机。
这比全量实时传所有日志更经济,也更适合定位问题。
## 5. 健康巡检自动化
目标:
- 每台大陆机自动自检
- 海外后台只看结果
建议 Agent 每 30 秒到 60 秒上报:
- 节点在线状态
- 当前版本
- API / Worker / Sync Agent 运行态
- Redis / PostgreSQL / 磁盘 / 内存 / CPU
- 最近告警
- 当前任务负载
- 最近日志时间
并把现有脚本升级为 Agent 内部检查项:
- `check_mainland_controller.sh`
- `check_mainland_worker.sh`
- `check_temp_topology.sh`
- `check_worker_participation.sh`
后续不是人工执行这些脚本,而是 Agent 周期性执行并结构化上传结果。
---
## 五、建议的系统分层
## 1. 海外控制面
建议新增一个“运维控制模块”,逻辑上可放进 `domain-api`,后续再拆独立服务也可以。
### 需要的核心对象
#### `managed_nodes`
记录纳管节点:
- `node_code`
- `region`
- `role`
- `hostname`
- `ip`
- `agent_version`
- `current_release`
- `status`
- `ssh_enabled`
- `agent_last_seen_at`
- `tags`
#### `ops_jobs`
记录运维任务:
建议以后直接以 [ops_job_contract.md](/www/wwwroot/getDomain/docs/schemas/ops_job_contract.md:1) 为正式母本。
- `job_id`
- `job_type`
- `target_nodes`
- `payload`
- `created_by`
- `status`
- `started_at`
- `finished_at`
#### `ops_job_steps`
记录每个节点执行步骤:
- `node_code`
- `step_name`
- `status`
- `stdout`
- `stderr`
- `result_json`
#### `node_log_streams`
记录日志游标和日志回流状态:
- `node_code`
- `source`
- `mode`
- `cursor`
- `last_received_at`
## 2. Node Agent
建议单独做一个轻量 Python 服务,比如:
```text
domaincheck-node-agent
```
职责:
- 周期心跳
- 拉取任务
- 本地执行
- 采集日志
- 上报结果
- 生成诊断包
Agent 尽量独立于业务主程序,不要把它耦合进 `detect_worker.py`
原因:
- 运维系统不能依赖业务进程是否正常
- 即使 Worker 崩了Agent 还应该活着,才能帮你排障
---
## 六、对你当前项目最合适的落地路线
## 第一阶段:先做“控制面集中化”
目标:
- 海外后台统一看到所有大陆机器
- 一键拉诊断
- 一键执行已有检查脚本
- 一键切日志回传模式
这个阶段先不碰太多发布链路,优先把“看”和“查”统一。
### 交付物
- Node Agent MVP
- 海外后台“节点管理”页
- 海外后台“运维任务”页
- 海外后台“远端日志”页
- 海外后台“诊断包”页
## 第二阶段:再做“一键更新”
目标:
- 海外控制面选择版本
- 指定节点灰度发布
- 自动回滚
### 交付物
- 发布包生成器
- `release manifest`
- Agent 下载 / 校验 / 切换版本
- 回滚机制
## 第三阶段:再做“一键安装新节点”
目标:
- 新机器只执行一次 bootstrap
- 其余全部由海外控制面接管
### 交付物
- bootstrap token
- 安装向导
- 节点注册流程
- 环境模板生成器
---
## 七、比“SSH 全接管”更优的地方
你提的方向是:
> 海外主机配置好 SSH后续所有大陆机器都由代码内部接管
这个方向本身是对的但如果只做“SSH 全接管”,还不够优秀。
更优解是:
> SSH 只作为纳管和兜底方式;日常统一走 Agent 主动连接。
这样好处是:
- 架构更稳
- 不依赖每次远程入站打通
- 不怕某些网络环境 SSH 不稳定
- 更适合未来节点继续增加
- 更容易做权限分级、审计、结果留痕
所以我建议最终定成:
### 运维主链路
- `海外控制面 -> Agent 任务编排 -> 大陆节点执行 -> 回传结果`
### 运维兜底链路
- `海外控制面 -> SSH -> 大陆节点`
---
## 八、和现有代码如何衔接
当前项目已经有一些很好的基础,不需要推翻:
- 多机节点模型
- `runtime/status`
- `runtime/cluster`
- `sync-summary`
- 一批巡检脚本
- 日志回传开关雏形
- 运行中心
这些都应该保留,并演进成:
### 当前脚本的未来定位
- `bootstrap_*.sh`
- 保留为 bootstrap / 应急工具
- `check_*.sh`
- 演进成 Agent 内部的标准诊断动作
- `runtime/status`
- 继续作为统一运行态接口
- `runtime/cluster`
- 继续作为统一集群视图
- `detect_result_projection / runtime_projection`
- 继续作为跨地域观测基础
也就是说,现有代码不是废掉,而是从“人工脚本时代”升级成“控制面编排时代”。
---
## 九、我建议的最优落地决策
如果只选一个方向,我建议直接定成:
### 最优方案
- 海外主机为唯一控制面
- 大陆节点统一部署 `domaincheck-node-agent`
- Agent 主动访问海外控制面
- 日常安装、更新、巡检、日志回流全部走 Agent
- SSH 仅保留为 bootstrap 和应急手段
- 正式更新统一改为 release 包分发,不再把 `git pull` 作为正式更新链路
这是当前最值得投入的方向,因为它能同时解决:
- 调试效率低
- 多机管理复杂
- 权限混乱
- 日志分散
- 更新不稳定
- 新增节点成本高
---
## 十、建议的下一步执行顺序
不要再继续先补散点 bug而是先把运维骨架建起来。
建议顺序:
1. 固化这份方案
2. 新建 `node-agent` 设计草案
3. 先做 Agent MVP
4. 先接入:
- 心跳
- 远程任务
- 诊断包
- 日志 tail
5. 海外后台新增:
- 节点管理页
- 运维任务页
- 远端日志页
6. 再把现有检查脚本封成 Agent 动作
7. 最后再做发布链路自动化
---
## 十一、结论
当前最优策略不是“继续加脚本”,而是:
> 把 domainCheck 从“多机联调项目”升级成“海外控制面统一接管大陆节点的自动化运维系统”。
从长期看,这会比继续靠人工 SSH、人工复制日志、人工比对状态高效很多也更符合你后续继续扩机器的目标。