CubeSandbox 多机集群部署指南:控制面 + 计算节点架构与调度配置
2026/9/16 16:43:15 网站建设 项目流程

CubeSandbox 多机集群部署指南:控制面 + 计算节点架构与调度配置

【免费下载链接】CubeSandboxInstant, Concurrent, Secure & Lightweight Sandbox for AI Agents.项目地址: https://gitcode.com/GitHub_Trending/cu/CubeSandbox

本指南讲解如何把单机 Cube Sandbox 一键部署扩展为多机集群:在已部署控制节点的基础上,通过添加仅运行沙箱运行时(内置 network runtime 的CubeletCubeShim等)的计算节点来横向扩容。读完本文,你将掌握计算节点的安装前置条件、.env环境变量配置、install-compute.sh安装流程、集群健康验证、CubeMaster 调度评分配置,以及 SDK、通用 HTTP 客户端、泛域名 DNS 和 E2B sidecar 四种客户端接入集群的方式。

架构概览

多机部署采用「控制面 + 计算节点」两层结构:

┌─────────────────────────────────────────┐ │ 控制节点 │ │ CubeMaster, CubeOps, cube-api, │ │ CubeProxy, CoreDNS, MySQL, Redis, │ │ Cubelet (network runtime) │ └──────────────────┬──────────────────────┘ │ /internal/v1/node-agent API ┌───────────┼───────────┐ ▼ ▼ ▼ ┌────────────┐┌────────────┐┌────────────┐ │ 计算节点 #1 ││ 计算节点 #2 ││ 计算节点 #N │ │ Cubelet ││ Cubelet ││ Cubelet │ │ net runtime││ net runtime││ net runtime│ └────────────┘└────────────┘└────────────┘
  • 控制节点运行完整技术栈:编排调度(CubeMaster)、节点管理(CubeOps)、API 网关(cube-api)、代理(CubeProxy + CoreDNS)、数据库(MySQL + Redis)、内置 MinIO S3 存储(供 volume 使用),同时自身也作为计算节点承载沙箱。
  • 每个计算节点只运行内置 network runtime 的Cubelet,向控制面CubeOps注册并接收来自CubeMaster的沙箱调度请求。

从仓库实现看,这种「角色差异」由部署脚本直接落地:deploy/one-click/install-compute.sh只有两行核心逻辑——把ONE_CLICK_DEPLOY_ROLE强制设为compute,然后复用同一个install.sh执行安装:

export ONE_CLICK_DEPLOY_ROLE=compute exec "${SCRIPT_DIR}/install.sh" "$@"

install.sh会根据该角色走不同的组件拷贝分支(deploy/one-click/install.sh#L1829-L1852):计算节点只安装Cubeletcube-vscube-shimcube-kernel-scfcube-imagecube-agentcube-egress、可选的CubeS3lvol以及 systemd 与脚本,而不会部署 CubeMaster、CubeOps、cube-api 等控制面组件;同时计算节点会屏蔽本机 MinIO 服务(install.shmasking local MinIO service (compute role does not run MinIO)分支),S3 卷能力完全依赖控制面。

前置条件

每台计算节点需满足与控制节点相同的硬件和软件要求:

  • 物理机或裸金属服务器(不支持嵌套虚拟化)
  • x86_64aarch64(ARM64)架构,已启用 KVM(用ls /dev/kvm确认)
  • Docker已安装并运行
  • 到控制节点的网络连通性:默认需访问CubeOps3010端口进行节点注册;使用内置 MinIO 时还需访问9000端口(S3 API 端口,见 deploy/one-click/env.example 中CUBE_SANDBOX_MINIO_API_PORT=9000

完整要求列表请参阅本地构建部署 — 前置条件。

第一步:准备发布包

使用与控制节点相同的发布包,将其拷贝到计算节点并解压:

tar -xzf cube-sandbox-one-click-<version>.tar.gz cd cube-sandbox-one-click-<version>

发布包内包含 install-compute.sh、install.sh、smoke.sh、down.sh、env.example 等一键部署脚本与组件产物。

第二步:配置环境变量

cp env.example .env

编辑.env,设置以下关键变量:

ONE_CLICK_DEPLOY_ROLE=compute CUBE_SANDBOX_NODE_IP=<当前节点IP> ONE_CLICK_CONTROL_PLANE_IP=<控制节点IP> # CUBE_S3_*:可选但强烈建议。缺失时仅告警并继续安装,S3 卷插件不可用。 # 取值方式见下方提示。内置 MinIO 时形如: CUBE_S3_ENDPOINT=http://<控制节点IP>:9000 CUBE_S3_ACCESS_KEY_ID=<取自控制节点> CUBE_S3_SECRET_ACCESS_KEY=<取自控制节点> CUBE_S3_BUCKET=cube-volumes CUBE_S3_S3FS_EXTRA_OPTS=-ouse_path_request_style
变量说明
ONE_CLICK_DEPLOY_ROLE计算节点必须设为compute
CUBE_SANDBOX_NODE_IP当前节点主网卡 IP
ONE_CLICK_CONTROL_PLANE_IP控制节点 IP,自动拼接为<ip>:3010作为 CubeOps 节点注册地址
CUBE_S3_*可选但强烈建议。Volume 插件依赖 S3;缺失时仅告警并继续安装,但 S3 卷插件不可用

S3 缺失时仅告警

install.sh会检查CUBE_S3_ENDPOINT,缺失时打印醒目的黄色警告并继续安装。节点可正常部署,但S3 卷插件不可用,补齐后重装即可。

从控制节点取CUBE_S3_*回填值的标准流程:

  1. 在控制节点执行:
    grep '^CUBE_S3_' /usr/local/services/cubetoolbox/.one-click.env

    输出为空说明控制节点自身未配 S3。

  2. 把输出逐行拷贝到计算节点.env
  3. 重新执行sudo ./install-compute.sh

使用内置 MinIO 时,还需放行计算节点到控制面的 TCP 9000。这一点在源码中也有印证:控制节点安装时,install.sh会从内置 MinIO 自动回填CUBE_S3_*并持久化到/usr/local/services/cubetoolbox/.one-click.env,而计算节点不部署 MinIO,只能手工拷贝该文件中的值(见 deploy/one-click/env.example 中 Bundled MinIO 一节的注释说明)。

显式指定 CubeOps 地址

如果 CubeOps 使用非默认端口,也可以显式指定:

ONE_CLICK_CONTROL_PLANE_CUBEOPS_ADDR=<控制节点IP>:3010

同时设置时,ONE_CLICK_CONTROL_PLANE_CUBEOPS_ADDR优先级高于ONE_CLICK_CONTROL_PLANE_IP。这与仓库脚本的校验逻辑一致:deploy/one-click/scripts/one-click/common.sh中,compute 角色要求ONE_CLICK_CONTROL_PLANE_IPONE_CLICK_CONTROL_PLANE_CUBEOPS_ADDR至少配置其一,否则安装直接报错退出。

第三步:安装

sudo ./install-compute.sh

计算节点安装脚本会:

  1. 只安装内置 network runtime 的Cubeletcube-shimcube-imagecube-kernel-scf和运行时脚本(实际还包括cube-vscube-agentcube-egress,见 deploy/one-click/install.sh#L1829-L1846 的 compute 分支)
  2. 只启动宿主机进程:cubelet
  3. 自动把Cubeletmeta_server_endpoint指向控制面CubeOps
  4. 通过控制面的/internal/v1/node-agent接口向 CubeOps 注册节点并上报状态

/internal/v1/node-agent接口在 CubeOps 中由AgentHandler提供(CubeOps/internal/nodemanagement/handler/agent.go),其路由包括:

  • GET /readyz—— 健康探活,返回 CubeMaster 兼容的 envelope(ret.ret_code: 200
  • POST /nodes/register—— 计算节点注册,绑定NodeID与节点快照
  • POST /nodes/:nodeID/status—— 计算节点周期性上报状态

install.sh在 compute 角色下还会自动把节点注册地址解析为 CubeOps 端点,并复用CUBE_SANDBOX_NODE_IP作为节点注册 ID 与上报地址(见Cubelet node registration to CubeOps will reuse CUBE_SANDBOX_NODE_IP when it is set的注释,deploy/one-click/env.example)。

验证部署

健康检查

sudo ./smoke.sh

smoke.sh会加载.env并最终执行安装在宿主机上的quickcheck.sh(见 deploy/one-click/smoke.sh)。在计算节点模式下,quickcheck.sh会验证(deploy/one-click/scripts/one-click/quickcheck.sh#L331-L374):

  • 本机Cubelet及其内置 network runtime 健康状态(cube-sandbox-cubelet.service处于 active)
  • 控制面CubeOps可达(通过resolve_control_plane_cubeops_addr解析出的地址做validate_host_port校验)
  • 当前节点已出现在控制面的/internal/v1/nodes/{node_id}中(查询 CubeOps 节点注册接口并核对返回的 IP 字段与CUBE_SANDBOX_NODE_IP一致)

计算节点模式下,quickcheck.sh会跳过 cube-api、MySQL、Redis、MinIO、CubeMaster、CubeTemplateCenter 等控制面单元检查;若开启ONE_CLICK_ENABLE_S3LVOL=1,还会额外检查cube-sandbox-s3lvol.service与数据面布局(rcow_recovery.sh --verify-only)。

从控制节点验证

在控制节点上确认计算节点已注册:

curl http://127.0.0.1:3010/internal/v1/nodes

返回结果中应包含计算节点的 IP 和健康状态。这也是调度排障的常用入口之一(详见 CubeMaster 调度器配置参考)。

配置 CubeMaster 调度评分

多机部署时,应在控制节点的 CubeMaster 配置中设置scheduler.score。如果未配置评分,CubeMaster 会先过滤可用节点,再按照过滤后的节点顺序进行选择,新的沙箱可能集中到第一个可用节点,直到资源过滤器把流量推到其他节点。

可以将下面这些调度字段合并到cubemaster.yaml中已有的scheduler段,并保留当前部署已有的filter、超时和其他 scheduler 配置

scheduler: # 保留当前部署已有的 filter、超时和其他 scheduler 配置。 priority_select_num: 3 score: enable_scorers: - real_time_weighted_average resource_weights: mvm_num: 2 local_create_num: 3 quota_cpu_usage: 1 quota_mem_usage: 1 plugin_conf: real_time_weighted_average: weight: 1.0 enable_weight_factors: - mvm_num - local_create_num - quota_cpu_usage - quota_mem_usage

为什么 priority_select_num 要大于 1

对于多机集群,建议将scheduler.priority_select_num设置为大于1的值,让 CubeMaster 从评分最高的一组节点中随机选择。随项目提供的默认配置使用priority_select_num: 1(在 CubeMaster/pkg/service/httpservice/cube/sandboxutil_test.go 中可见),这意味着评分只会决定下一个沙箱落到哪一个节点,而不会在多个高分节点之间分散放置。小规模集群可以从3开始,并根据节点数量继续调整。scheduler.least_select_name默认值为random,通常不需要显式设置。

这些字段在源码中有对应结构:CubeMaster/pkg/base/config/config.go定义了PrioritySelectNumEnableScorersResourceWeightsRealTimeWeightedAverage等配置项;评分器注册表中real_time_weighted_average对应NewRealTimeWeightedAverageScore(CubeMaster/pkg/selector/score/init.go),其实现位于 CubeMaster/pkg/selector/score/realtimescore.go。启用该评分器时必须同时配置score.plugin_conf.real_time_weighted_average,否则 CubeMaster 可能在 scheduler 启动阶段 panic。

新增计算节点后的 template redo

节点注册成功并不代表所有模板都已在该节点可用。调度器的template_locality过滤器要求目标节点具备可用模板副本,否则创建请求可能失败或只调度到旧节点。对镜像构建模板,新增节点后必须执行 template redo:

cubemastercli tpl redo \ --template-id <tpl-id> \ --node <node-ip>

--node接受节点 ID 或 host IP,可重复传入多个;--detach只提交任务不等待;--failed-only只重做失败节点。建议把「安装计算节点 → 确认健康与资源上报 → 执行 template redo → 等待 job 成功 → 放开业务流量」固化为扩容固定步骤。

完整的 CubeMaster 调度配置、Cubelet 节点上报、quota / label / 并发对调度的影响,请参阅 CubeMaster 调度器配置参考。更新cubemaster.yaml后,请按当前部署方式重启 CubeMaster,让调度器加载新的评分配置。

从客户端连接集群

客户端应用需要 CubeAPI 控制面地址,以及一条通过 CubeProxy 访问沙箱服务的数据面链路。根据客户端类型选择最简单的方式:

方式适用场景泛域名 DNS额外组件
CubeSandbox SDK +CUBE_PROXY_NODE_IPPython、Go 和 Node.js SDK不需要不需要
CubeProxy 路径模式curl、后端服务、通用 HTTP 客户端不需要不需要
泛域名 DNS生产环境、浏览器、SPA、官方 E2B SDK需要不需要
E2B 开发 sidecar本地没有 DNS,但必须使用官方 E2B SDK不需要需要

CubeSandbox SDK:直连 CubeProxy

CubeSandbox SDK 可以直接连接指定的 CubeProxy IP,同时保留用于沙箱路由的虚拟Host,因此不需要配置泛域名 DNS:

export CUBE_API_URL="http://<控制面IP>:3000" export CUBE_PROXY_NODE_IP="<CubeProxy节点IP>" export CUBE_PROXY_PORT_HTTP=80 export CUBE_TEMPLATE_ID="<模板ID或别名>"

设置后即可正常使用 SDK。控制面请求访问 CubeAPI,数据面请求直接连接 CubeProxy。SDK 侧的实现在 sdk/go/README.md 有完整说明:CUBE_PROXY_NODE_IP设置后,数据面请求直接连接该 IP 与端口,同时保留虚拟沙箱 Host;sdk/go/config.go会在初始化时读取这些环境变量。

通用 HTTP 客户端:路径模式

任意 HTTP 客户端都可以通过 CubeProxy 路径前缀访问沙箱服务:

http://<CubeProxy地址>:<HTTP端口>/sandbox/<sandbox-id>/<容器端口>/<路径>

例如:

curl http://10.0.0.5/sandbox/abc123/49999/health

路径模式不需要 DNS 或证书配置,并支持 WebSocket 升级。但它不适合使用/static/app.js等根绝对路径加载资源的 SPA,此类应用应使用泛域名 DNS。

生产环境和浏览器访问:泛域名 DNS

Host 模式使用<端口>-<sandbox-id>.<域名>格式的沙箱域名,需要配置指向 CubeProxy 的泛域名 A 记录:

*.cube.example.com → <CubeProxy公网或内网IP>

CubeAPI 必须使用相同的基础域名:

export CUBE_API_SANDBOX_DOMAIN=cube.example.com

一键部署内置 CoreDNS,可供本机解析*.cube.app。它主要用于本地体验;生产环境和多机共享环境应使用托管 DNS 或内网 DNS 服务。注意/etc/hosts不支持泛域名记录。TLS 和 DNS 的完整配置请参阅 HTTPS 证书与域名解析。

官方 E2B SDK 无泛域名 DNS:开发 sidecar

官方 E2B SDK 没有 CubeSandbox SDK 的 IP 直连选项。本地开发环境无法配置泛域名 DNS 时,可以使用仓库自带的 E2B 开发 sidecar 示例:

cd examples/e2b-dev-sidecar pip install -r requirements.txt cp env.example .env

连接远程集群时配置:

E2B_API_URL="http://<控制面IP>:3000" CUBE_REMOTE_PROXY_BASE="https://<CubeProxy节点IP>:443" E2B_API_KEY="<API密钥>" CUBE_TEMPLATE_ID="<模板ID或别名>"

然后运行:

python demo.py

CUBE_REMOTE_PROXY_BASE必须指向 CubeProxy,不能填写 sidecar 自己的监听地址。集群启用鉴权时,需要使用有效的 API Key。

常用操作

停止计算节点服务

sudo ./down.sh

计算节点模式下,该命令只会停止cubelet,不影响控制面或其他计算节点(对应脚本为 deploy/one-click/scripts/one-click/down-compute.sh)。

重新安装

直接再次运行install-compute.sh即可。安装脚本会自动停止已有部署再进行安装。

查看日志

组件日志路径
Cubelet/data/log/Cubelet/
CubeShim/data/log/CubeShim/
Hypervisor (VMM)/data/log/CubeVmm/
运行时 PID 文件/var/run/cube-sandbox-one-click/
进程标准输出/错误/var/log/cube-sandbox-one-click/

其中/var/run/cube-sandbox-one-click/var/log/cube-sandbox-one-click分别由环境变量ONE_CLICK_RUNTIME_DIRONE_CLICK_LOG_DIR定义(见 deploy/one-click/env.example),PID 与日志目录默认值可直接修改。控制节点的日志路径请参阅 本地构建部署 — 查看日志。

配置参考

计算节点使用相同的.env文件格式。以下变量与计算节点部署特别相关:

变量默认值说明
ONE_CLICK_DEPLOY_ROLEcontrol计算节点必须设为compute
ONE_CLICK_CONTROL_PLANE_IP控制节点 IP,默认拼接为<ip>:3010
ONE_CLICK_CONTROL_PLANE_CUBEOPS_ADDR显式指定 CubeOps 地址,优先级高于ONE_CLICK_CONTROL_PLANE_IP
CUBE_SANDBOX_NODE_IP10.0.0.10必须修改。当前节点主网卡 IP
CUBE_SANDBOX_NETWORK_CIDR192.168.0.0/18(取自config.tomlcubevs 本地网络 CIDR。需与控制节点一致。格式为 IPv4 CIDR(如10.100.0.0/18),掩码范围 /16~/24。安装时自动检测宿主机冲突。
CUBE_SANDBOX_NETWORK_CIDR_SKIP_CONFLICT_CHECK0设为1跳过冲突检测(不推荐)。
ONE_CLICK_RUN_QUICKCHECK1安装后是否执行健康检查
CUBE_S3_*空 / 由控制面 MinIO 填入可选但强烈建议。Volume 插件依赖 S3,缺失时仅告警、S3 卷插件不可用。从控制节点/usr/local/services/cubetoolbox/.one-click.env拷贝(取值方法见上文第二步);ENDPOINT/ACCESS_KEY_ID/SECRET_ACCESS_KEY/BUCKET无可用默认值。

CUBE_SANDBOX_NETWORK_CIDR要求各节点一致,因为 CubeVS 沙箱本地网络的 IP 分配范围必须与Cubelet/config/config.toml的默认值以及控制节点保持一致;掩码被限制在 /16~/24 之间(见 deploy/one-click/env.example 中 CubeVS local network CIDR 一节)。完整配置参考(构建选项、数据库、代理等)请参阅 本地构建部署 — 配置参考。

故障排查

计算节点无法连接 CubeOps

检查网络连通性:

curl http://<控制节点IP>:3010/internal/v1/nodes

如果失败,请检查:

  • 控制节点的防火墙规则(3010端口需可访问)
  • .envONE_CLICK_CONTROL_PLANE_IPONE_CLICK_CONTROL_PLANE_CUBEOPS_ADDR的值

注意install.sh在 compute 角色下会对控制面地址做 preflight 校验(check_compute_control_plane_preflight),地址缺失或不可达会直接中断安装。

节点未出现在控制面

如果smoke.sh本地通过但控制面上看不到该节点:

  1. 检查 Cubelet 日志:/data/log/Cubelet/
  2. 确认 Cubelet 配置中的meta_server_endpoint指向正确的 CubeOps 地址
  3. 确保CUBE_SANDBOX_NODE_IP设为可路由的 IP(不是127.0.0.1

该 IP 同时是节点在/internal/v1/node-agent/nodes/register中使用的注册 ID 与上报地址,配置错误会导致节点注册成功但状态不可达。通用故障排查(Docker、KVM、DNS 等)请参阅 本地构建部署 — 故障排查。调度相关的深度排障(no more resource、指标上报过期、模板不可用、label 不匹配、创建集中等)请参阅 CubeMaster 调度器配置参考 的排障一节。

【免费下载链接】CubeSandboxInstant, Concurrent, Secure & Lightweight Sandbox for AI Agents.项目地址: https://gitcode.com/GitHub_Trending/cu/CubeSandbox

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询