Skip to content

Latest commit

 

History

History
430 lines (302 loc) · 16.1 KB

File metadata and controls

430 lines (302 loc) · 16.1 KB

Remote Runtime v1 部署指南

本指南记录最终的 Remote Runtime v1 模型:远程执行统一走 websocket,SSH 固定在 helper 通道,运维在 direct-connect listener 和 reverse-connect machine-agent daemon 两种拓扑之间做选择。内容涵盖支持拓扑、旧机器记录迁移、验证策略、可观测性、守护进程安装、升级与回滚,以及分阶段 rollout 检查清单。

本指南中的术语:

  • direct_connect:控制面可以主动拨到机器。
  • reverse_connect:机器守护进程可以反向拨回控制面。
  • websocket:目标远程执行路径。
  • SSH 仅保留为引导、诊断和紧急修复 helper。

架构摘要

Remote Runtime v1 将远程机器行为拆成三个独立关注点:

  • 拓扑:direct_connectreverse_connect
  • runtime 平面:统一 websocket
  • helper 通道:可选的 SSH bootstrap 与 diagnostics

它们与机器存储字段和运行入口的映射如下:

拓扑 机器存储状态 运行入口 说明
Direct-connect listener reachability_mode=direct_connectexecution_mode=websocket 控制面直接拨号到保存的 advertised_endpoint 适用于 OpenASE 可以直接到达机器
Reverse-connect daemon reachability_mode=reverse_connectexecution_mode=websocket 远端主机运行 openase machine-agent run 并保持 machine-channel 会话 适用于机器可以向外拨号但不应暴露入站 listener

自动化验证矩阵

从仓库根目录运行聚焦的传输矩阵:

scripts/ci/remote_transport_matrix.sh

当前快速矩阵覆盖:

场景 覆盖
监听与反向拓扑共享的统一 WebSocket runtime 契约 TestUnifiedWebsocketRuntimeContractSuite
SSH 引导 + 反向 WebSocket 机器会话 TestMachineConnectWebsocketPublishesActivityAndMetrics
反向 WebSocket runtime 正常路径(含 hook 与产物同步) TestRuntimeLauncherLaunchesWebsocketReverseRuntimeWithHooksAndArtifactSync
SSH 引导 helper 行为 TestRunMachineSSHBootstrapUploadsBinaryEnvAndService
SSH 诊断 helper 行为 TestRunMachineSSHDiagnosticsReportsBootstrapAndRegistrationIssues
SSH 引导 + 监听 WebSocket 运行时 TestRuntimeLauncherLaunchesWebsocketListenerRuntimeWithHooksAndArtifactSync
直接 SSH runtime 拒绝 TestRuntimeLauncherRunTickRejectsSSHRuntimeExecution
无反向会话时反向 WebSocket 启动不回退到 SSH TestRuntimeLauncherDoesNotFallBackToSSHWhenWebsocketReverseTransportUnavailable
远程二进制/预检失败 TestRuntimeLauncherRecordsWebsocketPreflightFailureStageInActivityAndMetrics
守护进程认证失败 TestMachineConnectWebsocketAuthFailurePublishesActivityAndMetric

每个正常路径运行时用例验证:

  • 机器注册或可达性
  • 工作空间准备
  • Agent 进程启动
  • 输出流或命令握手
  • 清理或断开连接记账

CI 与本地验证策略

按以下顺序使用验证层:

  1. scripts/ci/remote_transport_matrix.sh
  2. 对于具备 Linux + Docker Compose 的机器,运行 make remote-runtime-containerscripts/ci/remote_runtime_container_harness.sh ...
  3. rollout 过程中结合 openase machine test <machine-uuid>openase machine ssh-diagnostics <machine-uuid> 做定向运维检查

设计意图是:

  • 快速矩阵进入普通仓库和 PR 验证
  • 容器 harness 负责本地专用或手动 / nightly 的 rollout 级检查
  • 运维命令负责部署后的单机诊断

本地容器 Harness

当你需要验证真实的守护进程启动、容器网络、远端文件系统权限、SSH 传输和进程执行,而不是只依赖进程内 fake 时,使用慢速的本地容器 harness:

make remote-runtime-container

只跑指定 case 时可以直接执行:

scripts/ci/remote_runtime_container_harness.sh listener
scripts/ci/remote_runtime_container_harness.sh reverse ssh

这套容器 harness:

  • 不会进入普通 pull request CI
  • 会把 case 日志和 compose 服务日志写到 .artifacts/remote-runtime-container/
  • 需要 Linux 和 Docker Compose
  • 使用 scripts/ci/remote_runtime_container.compose.yml
  • 提供独立的手动 / nightly workflow:.github/workflows/remote-runtime-container.yml

当前容器 case:

场景 覆盖
通过真实 listener 容器验证 direct-connect websocket runtime TestWebsocketListenerRuntimeContainerE2E
通过真实 machine-agent 容器验证 reverse-connect websocket runtime TestWebsocketReverseRuntimeContainerE2E
通过真实 SSH 容器验证 SSH bootstrap + diagnostics helper TestMachineSSHHelperContainerE2E

runtime 契约本身现在由两种 WebSocket 拓扑共同验证:

  • 监听 WebSocket 通过直接 listener 端点验证契约
  • 反向 WebSocket 通过 machine-channel runtime 消息验证同一份契约

关于消息模型、版本兼容规则与错误分类,请参见 docs/zh/websocket-runtime-contract.md

可观测性契约

指标

OpenASE 现在发出以下传输相关指标:

  • openase.machine_channel.active_sessions
    • 标签:transport_mode
  • openase.machine_channel.websocket_reconnect_total
    • 标签:transport_mode
  • openase.machine_channel.events_total
    • 标签:eventtransport_mode
  • openase.runtime.launch_failures_total
    • 标签:failure_stagetransport_mode

推荐告警:

  • openase.machine_channel.websocket_reconnect_total 的重连速率飙升
  • openase.runtime.launch_failures_totalfailure_stage in {workspace_transport, openase_preflight, agent_cli_preflight, process_start} 持续非零
  • openase.machine_channel.active_sessions 意外下降或波动

结构化日志

传输相关日志在已知时应包含以下关联字段:

  • machine_id
  • session_id
  • transport_mode
  • workspace_root
  • failure_stage
  • ticket_id
  • run_id
  • agent_id

运行时启动器现在在启动失败时记录 failure-stage 元数据,WebSocket 守护进程注册日志携带机器和会话标识符。

活动事件

项目活动现在记录:

  • machine.connected
  • machine.reconnected
  • machine.disconnected
  • machine.daemon_auth_failed
  • agent.failed
    • 在启动期间失败时包含 failure_stagetransport_modemachine_idworkspace_root

结合项目活动和日志来回答:

  • 哪台机器丢失或替换了 WebSocket 会话?
  • 守护进程是认证失败还是仅重连?
  • 运行时在传输设置、工作空间准备、二进制预检还是进程启动时失败?

部署前提

控制面板 URL、TLS 和 DNS

  • 机器守护进程通过 --control-plane-url 接受控制面板基础 URL、API 基础 URL 或直接 WebSocket 端点。
  • 生产环境中,优先使用具有有效 DNS 和 TLS 的稳定 HTTPS 源,然后将该源传递给守护进程。
  • 反向 WebSocket 需要从远程机器到控制面板的出站可达性。
  • 监听 WebSocket 需要从控制面板到机器公布的 WebSocket 端点的入站可达性。
  • 如果 TLS 终止在 OpenASE 前面,确保公布的主机名与监听证书匹配,且 WebSocket 升级头能通过代理。

可达性与兼容前提

反向 WebSocket:

  • 最适合机器可以向外拨号但无法暴露入站监听器的场景
  • 需要机器通道令牌
  • 仅当运维需要 helper 引导或诊断时才需要在机器记录上保留 SSH 凭证

监听 WebSocket:

  • 最适合控制面板可以直接到达机器的场景
  • 需要机器公布的 WebSocket 端点
  • 如需直接修复入口,可保留 SSH 凭证用于 helper 引导或诊断

SSH 兼容路径:

  • 不再是受支持的 runtime 回退路径
  • 应被视为遗留记录状态加 helper 基础设施,而不是远程执行模型

迁移现有机器记录

盘点当前状态

先列出机器,识别缺少 websocket 拓扑必填字段的记录:

openase machine list

迁移 direct-connect 机器

当控制面可以直接拨号到机器时使用此路径:

  1. 保存 reachability_mode=direct_connect
  2. 保存 execution_mode=websocket
  3. 保存有效的 advertised_endpoint
  4. 重新保存机器,并确认 direct-connect listener endpoint 仍然存在。
  5. 运行:
openase machine test <machine-uuid>

只有在仍需 helper 引导或诊断时才保留 SSH 凭证。

迁移 reverse-connect 机器

当机器应主动回拨控制面时使用此路径:

  1. 保存 reachability_mode=reverse_connect
  2. 保存 execution_mode=websocket
  3. 保存有效的 workspace_root
  4. 签发专用 machine channel token:
openase machine issue-channel-token \
  --machine-id <machine-uuid> \
  --ttl 24h \
  --format shell
  1. 在远端主机粘贴导出的 OPENASE_MACHINE_* 变量,并启动:
openase machine-agent run
  1. 确认守护进程会话和机器检查:
openase machine test <machine-uuid>
openase machine ssh-diagnostics <machine-uuid>

如果已经保留 SSH helper 访问,则应优先使用 openase machine ssh-bootstrap <machine-uuid> 上传当前二进制并安装或刷新与拓扑匹配的服务:

  • reverse_connect + websocket:安装或刷新反向 daemon 服务
  • direct_connect + websocket:安装或刷新远端 websocket listener 服务

运维工作流变化

迁移完成后,运维需要默认接受以下前提:

  • 两种远程拓扑的工单执行都固定在 websocket 上
  • direct-connect 故障首先按 listener 可达性问题排查,而不是去找 SSH fallback
  • reverse-connect 故障首先按 daemon 注册或会话健康问题排查
  • SSH 命令负责引导或修复远程访问,但不属于 runtime 执行平面

引导与守护进程安装

1. 构建或安装 OpenASE 二进制文件

从源码构建当前二进制文件:

make build-web

2. 创建或更新机器记录

在启动守护进程之前,确保机器记录有:

  • 预期的可达性与执行组合:
    • reverse_connect + websocket
    • direct_connect + websocket
  • 有效的 workspace_root
  • 只有在仍需引导、诊断或紧急修复时才保留 SSH helper 凭证
  • 远程 CLI 无法从 PATH 发现时的 agent_cli_path

3. 签发专用机器通道令牌

在控制面板主机上:

./bin/openase machine issue-channel-token \
  --machine-id <machine-uuid> \
  --ttl 24h \
  --format shell

这会打印以下 shell 导出:

  • OPENASE_MACHINE_ID
  • OPENASE_MACHINE_CHANNEL_TOKEN
  • OPENASE_MACHINE_CONTROL_PLANE_URL

4. 通过 SSH 或手工方式安装拓扑服务

如果控制面已经可以通过 SSH 到达机器,可以直接使用 helper 流而不必手工拷贝文件:

./bin/openase machine ssh-bootstrap <machine-uuid>

它会上传当前 openase 二进制、写入拓扑环境文件、安装用户级服务并重启。

对于 reverse_connect + websocket,helper 会安装 openase machine-agent run

对于 direct_connect + websocket,helper 会安装 openase machine-agent listen,并要求机器记录已经保存控制面要拨入的 advertised_endpoint

不使用 helper 的运维手工方式如下:

远程机器上的 reverse-connect 手工方式:

export OPENASE_MACHINE_ID=<machine-uuid>
export OPENASE_MACHINE_CHANNEL_TOKEN=<issued-token>
export OPENASE_MACHINE_CONTROL_PLANE_URL=https://openase.example.com

/usr/local/bin/openase machine-agent run \
  --agent-cli-path /usr/local/bin/codex \
  --openase-binary-path /usr/local/bin/openase

远程机器上的 remote-listener 手工方式:

export OPENASE_MACHINE_LISTENER_ADDRESS=0.0.0.0:19837
export OPENASE_MACHINE_LISTENER_PATH=/openase/runtime
export OPENASE_MACHINE_LISTENER_BEARER_TOKEN=<listener-token>

/usr/local/bin/openase machine-agent listen

推荐的 systemd --user 单元:

[Unit]
Description=OpenASE machine-agent
After=network-online.target
Wants=network-online.target

[Service]
ExecStart=/usr/local/bin/openase machine-agent run --agent-cli-path /usr/local/bin/codex --openase-binary-path /usr/local/bin/openase
Restart=always
RestartSec=5
Environment=OPENASE_MACHINE_ID=<machine-uuid>
Environment=OPENASE_MACHINE_CHANNEL_TOKEN=<issued-token>
Environment=OPENASE_MACHINE_CONTROL_PLANE_URL=https://openase.example.com

[Install]
WantedBy=default.target

对于监听 WebSocket 模式,先部署监听端点,然后在机器记录上保存公布的 WebSocket URL,并验证控制面板可以拨号到该端点。

升级与回滚

升级

  1. 构建目标 openase 二进制文件。
  2. 在远程机器上,将新二进制文件安装在当前二进制文件旁边。
  3. 重启 machine-agent 服务。
  4. 确认:
    • 出现 machine.connectedmachine.reconnected 活动
    • openase.machine_channel.active_sessions 恢复到预期水平
    • 金丝雀运行时启动期间 openase.runtime.launch_failures_total 保持平稳

回滚

  1. 停止守护进程服务。
  2. 恢复之前的二进制文件。
  3. 重启守护进程。
  4. 如果 WebSocket 启动仍不稳定,使用 openase machine ssh-diagnostics <machine-uuid>openase machine ssh-bootstrap <machine-uuid> 修复守护进程配置,再决定是否继续扩大部署。

故障排查

症状 可能信号 检查内容
守护进程从未注册 machine.daemon_auth_failedauth_failed 指标 令牌已撤销、令牌已过期、错误的机器 ID、错误的控制面板 URL
频繁重连 machine.reconnected,重连计数器 控制面板重启、网络抖动、代理空闲超时、心跳间隔不匹配
运行时启动前失败 agent.failedfailure_stage 查看阶段是 workspace_transportworkspace_rootrepo_authopenase_preflightagent_cli_preflight 还是 process_start
监听 WebSocket 无法拨号 启动器日志带 failure_stage=workspace_transportpreflight_transport DNS 解析、TLS 链、公布端点正确性、防火墙可达性
远程二进制缺失 failure_stage=openase_preflight .openase/bin/openase 存在于已准备的工作空间中且可以解析 OPENASE_REAL_BINPATH
Git 克隆失败 failure_stage=repo_auth 仓库凭证投射、GH_TOKEN、部署密钥或远程 git 传输策略
工作空间根目录无效 failure_stage=workspace_root 保存的机器 workspace_root、权限、挂载的文件系统可用性

当你需要快速确认工作空间权限、远程二进制是否存在、服务状态或最近日志时,使用 openase machine ssh-diagnostics <machine-uuid> 获取 helper-only 诊断输出。

部署检查清单

阶段 1:传输兼容性

  • 运行 scripts/ci/remote_transport_matrix.sh
  • 确认直接 SSH runtime 会被拒绝
  • 确认反向 WebSocket 启动失败不会回退到 SSH
  • 确认 WebSocket 预检失败被分类为 failure_stage

阶段 2:反向 WebSocket 金丝雀

  • 在小规模机器子集上启用 ws_reverse
  • 只在运维需要 helper 引导或诊断的机器上保留 SSH 凭证
  • 每个 rollout 批次至少跑一次反向 WebSocket 正常路径 runtime
  • 验证守护进程重启下的 machine.connected 和重连行为
  • 确认强制 WebSocket 传输失败仍被归类为 WebSocket 侧启动错误

阶段 3:监听扩展

  • 仅在反向 WebSocket 金丝雀稳定后启用 ws_listener
  • 在每次监听部署前验证 DNS、TLS 和控制面板直接可达性
  • 每批部署运行至少一个监听运行时正常路径

阶段 4:保留可选 SSH Helper 的广泛部署

  • 在部署窗口期间不要把 SSH 当作 runtime 执行计划的一部分
  • 保持以下仪表盘视图:
    • transport_mode 的启动成功率
    • 重连恢复
    • 孤立或卡住的运行时计数
    • 活跃 WebSocket 机器会话

成功标准

  • 运行时启动成功率在连续两个部署窗口中保持在 SSH 基线或以上
  • 重连恢复在不需要运维操作的情况下为目标机器群恢复会话
  • openase.runtime.launch_failures_total 保持在商定的错误预算以下,且主要由已知的、可操作的阶段主导
  • WebSocket 启用后孤立进程或卡住会话计数不增加
  • 项目活动和日志足以在不登录机器的情况下识别机器、会话、传输和失败阶段