CubeSandbox 多机集群部署指南:控制面 + 计算节点架构与调度配置
【免费下载链接】CubeSandboxInstant, Concurrent, Secure & Lightweight Sandbox for AI Agents.项目地址: https://gitcode.com/GitHub_Trending/cu/CubeSandbox
本指南讲解如何把单机 Cube Sandbox 一键部署扩展为多机集群:在已部署控制节点的基础上,通过添加仅运行沙箱运行时(内置 network runtime 的Cubelet、CubeShim等)的计算节点来横向扩容。读完本文,你将掌握计算节点的安装前置条件、.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):计算节点只安装Cubelet、cube-vs、cube-shim、cube-kernel-scf、cube-image、cube-agent、cube-egress、可选的CubeS3lvol以及 systemd 与脚本,而不会部署 CubeMaster、CubeOps、cube-api 等控制面组件;同时计算节点会屏蔽本机 MinIO 服务(install.sh中masking local MinIO service (compute role does not run MinIO)分支),S3 卷能力完全依赖控制面。
前置条件
每台计算节点需满足与控制节点相同的硬件和软件要求:
- 物理机或裸金属服务器(不支持嵌套虚拟化)
- x86_64或aarch64(ARM64)架构,已启用 KVM(用
ls /dev/kvm确认) - Docker已安装并运行
- 到控制节点的网络连通性:默认需访问
CubeOps的3010端口进行节点注册;使用内置 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_*回填值的标准流程:
- 在控制节点执行:
grep '^CUBE_S3_' /usr/local/services/cubetoolbox/.one-click.env输出为空说明控制节点自身未配 S3。
- 把输出逐行拷贝到计算节点
.env。 - 重新执行
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_IP或ONE_CLICK_CONTROL_PLANE_CUBEOPS_ADDR至少配置其一,否则安装直接报错退出。
第三步:安装
sudo ./install-compute.sh计算节点安装脚本会:
- 只安装内置 network runtime 的
Cubelet、cube-shim、cube-image、cube-kernel-scf和运行时脚本(实际还包括cube-vs、cube-agent、cube-egress,见 deploy/one-click/install.sh#L1829-L1846 的 compute 分支) - 只启动宿主机进程:
cubelet - 自动把
Cubelet的meta_server_endpoint指向控制面CubeOps - 通过控制面的
/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.shsmoke.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定义了PrioritySelectNum、EnableScorers、ResourceWeights与RealTimeWeightedAverage等配置项;评分器注册表中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_IP | Python、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.pyCUBE_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_DIR、ONE_CLICK_LOG_DIR定义(见 deploy/one-click/env.example),PID 与日志目录默认值可直接修改。控制节点的日志路径请参阅 本地构建部署 — 查看日志。
配置参考
计算节点使用相同的.env文件格式。以下变量与计算节点部署特别相关:
| 变量 | 默认值 | 说明 |
|---|---|---|
ONE_CLICK_DEPLOY_ROLE | control | 计算节点必须设为compute |
ONE_CLICK_CONTROL_PLANE_IP | 空 | 控制节点 IP,默认拼接为<ip>:3010 |
ONE_CLICK_CONTROL_PLANE_CUBEOPS_ADDR | 空 | 显式指定 CubeOps 地址,优先级高于ONE_CLICK_CONTROL_PLANE_IP |
CUBE_SANDBOX_NODE_IP | 10.0.0.10 | 必须修改。当前节点主网卡 IP |
CUBE_SANDBOX_NETWORK_CIDR | 192.168.0.0/18(取自config.toml) | cubevs 本地网络 CIDR。需与控制节点一致。格式为 IPv4 CIDR(如10.100.0.0/18),掩码范围 /16~/24。安装时自动检测宿主机冲突。 |
CUBE_SANDBOX_NETWORK_CIDR_SKIP_CONFLICT_CHECK | 0 | 设为1跳过冲突检测(不推荐)。 |
ONE_CLICK_RUN_QUICKCHECK | 1 | 安装后是否执行健康检查 |
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端口需可访问) .env中ONE_CLICK_CONTROL_PLANE_IP或ONE_CLICK_CONTROL_PLANE_CUBEOPS_ADDR的值
注意install.sh在 compute 角色下会对控制面地址做 preflight 校验(check_compute_control_plane_preflight),地址缺失或不可达会直接中断安装。
节点未出现在控制面
如果smoke.sh本地通过但控制面上看不到该节点:
- 检查 Cubelet 日志:
/data/log/Cubelet/ - 确认 Cubelet 配置中的
meta_server_endpoint指向正确的 CubeOps 地址 - 确保
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),仅供参考