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

17 KiB
Raw Permalink Blame History

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. 初始化控制面配置

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 domain-api/deploy/multi-region/drive_ops_center.sh config

3. 在控制面本机生成发布包

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 domain-api/deploy/multi-region/drive_ops_center.sh doctor-export

5. 为新节点导出接管计划

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 用户混用
  • 可回滚

推荐目录形态:

/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 为正式母本。

  • 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 服务,比如:

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