Files
getDomain/docs/21_domainCheck_海外主机集中运维与自动化方案.md
2026-04-18 23:52:51 +08:00

709 lines
17 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# 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、人工复制日志、人工比对状态高效很多也更符合你后续继续扩机器的目标。