709 lines
17 KiB
Markdown
709 lines
17 KiB
Markdown
# 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、人工复制日志、人工比对状态高效很多,也更符合你后续继续扩机器的目标。
|