离线部署
适用场景: 目标机器没有公网(内网机房、隔离网段、受限环境),需要离线部署 CubeSandbox。这类机器通常接入内网,并配有内网软件源。
离线部署完全可行。 只需提前准备以下产物,然后按正常流程安装。安装步骤与正常部署完全相同。
| 提前准备 | 怎么准备 | 详见 |
|---|---|---|
| 安装包(含可选的 PVM 内核包) | 在有公网的机器上从 Releases 下载,拷贝到目标节点 | 步骤 1 |
| 系统软件包(Docker、Compose 等) | 有内网软件源即可跳过;无源才需手动安装 | 步骤 2 |
| 容器镜像(核心) | 在有公网的机器上拉取打包,docker load 到目标节点;或推送到内网镜像仓库 | 步骤 3 |
| 模板源镜像(可选) | 推送到内网镜像仓库,创建模板时直接引用 | 步骤 5 |
备好前 3 类,即可按步骤 4 安装;模板源镜像在安装完成后再推入内网仓库(步骤 5)。
适用范围
本指南覆盖一键部署(单机、裸金属、多机集群)。以下两种部署方式不适用:
- 腾讯云 Terraform 部署器:需要访问腾讯云 API 创建云资源。
- Kubernetes(Helm)部署:集群必须能访问存放组件镜像的仓库。若已有内网仓库(如 Harbor),按 Kubernetes 部署指南操作,把 chart 指向该仓库即可。
为什么离线可行(原理)
一键安装脚本原生支持离线:
- 预载的容器镜像直接生效,无需改动脚本。
- 部署包自带全部版本锁定产物(组件二进制、
vmlinux、guest 镜像、mkcert)。 - 真正需要公网的只有三件事:下载安装包、安装缺失的软件包、拉取容器镜像。它们对应步骤 1–3:内网源能覆盖的直接走内网,其余提前准备好。
开始之前:确认宿主机条件
宿主机要求与正常部署完全相同(详见快速开始 — 前置条件):
- x86_64 或 aarch64 Linux,glibc ≥ 2.31,root 权限
- 内存至少 8 GB(安装器硬性检查,不足会直接终止安装)
/data/cubelet使用 XFS,至少 50 GB- KVM 可用:裸金属原生支持;x86_64 云服务器可先安装 PVM 内核(见步骤 1,不支持 aarch64——ARM 机器必须本身已有 KVM)
步骤 1:下载安装产物
做什么: 在有公网的机器上下载下列产物,拷贝到目标节点。内网若已有制品中转站或 Release 镜像,直接走内网获取即可。
- 一键部署包:
cube-sandbox-one-click-<version>-<arch>.tar.gz。<arch>与目标节点的架构一致(amd64/arm64),下载渠道见下载与 Release 说明。 - PVM 宿主内核包(rpm/deb):仅当目标是无
/dev/kvm的云服务器时需要。从最新的kernel-release-*release 下载,按 PVM 部署 — 第一步 安装并重启,再继续本指南。
用 scp、U 盘等方式把文件传到目标节点。
步骤 2:提前安装系统软件包(无内网源时)
已配置内网软件源?直接跳到步骤 3。
没有内网源的机器才需要本步:在有公网的机器上下载下列软件包,拷贝到目标节点安装。
软件包清单(点击展开)
跳过本步前,确认内网源里收录了 Docker 和 Compose——不少内网源不带它们。
每个节点必装:
Docker Engine 和 Compose。只要
docker和docker compose version(或docker-compose)都能运行,install.sh就跳过联网安装。装好后验证:bashdocker version && docker compose version # 或:docker-compose --version⚠️ 不支持 snap Docker(读不到
/usr/local/services)。请用软件包方式安装 docker-ce / docker.io。基础命令:
tar、ss、ip(iproute2)、bash、curl、grep、sed、pgrep(procps)、awk、date、openssle2fsprogs+util-linux:默认存储后端cubecow依赖mkfs.ext4、mount、umount、losetup
按需安装:
dnsmasq:宿主机没有systemd-resolved/resolvectl时必装,否则 DNS 兜底逻辑会自动安装它s3fs+jq:S3 卷挂载依赖。安装器会尝试自动补装,失败当时不报错——务必提前装好python3、nvme-cli、libaio、libnuma、libuuid:仅当启用 CubeS3lvol(ONE_CLICK_ENABLE_S3LVOL=1)logrotate:最小化系统镜像若未自带,请补装
步骤 3:预载容器镜像
做什么: 把步骤 3.1 清单中的镜像导入目标节点的本地 Docker,两种方式任选其一:
- 逐台搬运(下文以此为例):在有公网、与目标同架构的机器上
docker pull→docker save打包 → 目标节点docker load。 - 走内网镜像仓库(多节点推荐):把镜像推到内网仓库(如 Harbor),用覆盖变量把引用指向它。安装器直接从内网拉取,不用逐台 load。
逐台搬运方式的命令:
# 有公网的机器:拉取清单中的每个镜像
docker pull <镜像引用>
# 按节点角色分别打包(传输量更小)
docker save -o cube-images-control.tar <镜像1> <镜像2> ...
# 目标节点
docker load -i cube-images-control.tar3.1 每个节点需要哪些镜像
控制节点(默认 install.sh 的 all-in-one 单机部署,或集群中的每个控制节点):
| 镜像 | 默认引用 | 覆盖变量 |
|---|---|---|
| MySQL | cube-sandbox-image.tencentcloudcr.com/opensource/mysql:8.0 | CUBE_SANDBOX_MYSQL_IMAGE |
| Redis | cube-sandbox-image.tencentcloudcr.com/opensource/redis:7-alpine | CUBE_SANDBOX_REDIS_IMAGE |
| MinIO(S3 后端,默认开启) | cube-sandbox-int.tencentcloudcr.com/cube-sandbox/minio:<release> | CUBE_SANDBOX_MINIO_IMAGE |
| CoreDNS | cube-sandbox-image.tencentcloudcr.com/opensource/coredns/coredns:1.14.2 | CUBE_PROXY_COREDNS_IMAGE |
| WebUI(nginx) | cube-sandbox-image.tencentcloudcr.com/opensource/openresty:1.21.4.1-6-alpine-fat | WEB_UI_IMAGE |
| cube-proxy | cube-sandbox-int.tencentcloudcr.com/cube-sandbox/cube-proxy:<tag> | CUBE_SANDBOX_CUBE_PROXY_IMAGE |
| cube-lifecycle-manager | cube-sandbox-int.tencentcloudcr.com/cube-sandbox/cube-lifecycle-manager:<tag> | CUBE_SANDBOX_CUBE_LCM_IMAGE |
| cube-egress | cube-sandbox-int.tencentcloudcr.com/cube-sandbox/cube-egress:<tag> | CUBE_SANDBOX_CUBE_EGRESS_IMAGE |
计算节点(install-compute.sh):
| 镜像 | 默认引用 | 说明 |
|---|---|---|
| cube-egress | 同上 | 必需——出口 MITM 代理跑在每个节点上 |
| JuiceFS mount | cube-sandbox-int.tencentcloudcr.com/cube-sandbox/juicefs:ce-v1.4.1 | 仅当 ONE_CLICK_ENABLE_JFS=1;MIRROR=cn 时走 -cn 域名 |
cube-proxy / cube-lifecycle-manager / cube-egress / MinIO 四个镜像的 <tag> / <release> 占位符,在解压后的部署包根目录执行以下命令查询:
grep -rhE '_IMAGE.*_DEFAULT="' scripts/3.2 镜像引用必须完全一致
- 拉了
-cn引用,就在.env里设MIRROR=cn;拉了-int引用则不设。 - 使用内网仓库或自定义镜像名时,通过上表的覆盖变量在
.env中指定。
3.3 在目标节点上验证
docker images # 清单里的每个引用都必须出现,名字和 tag 完全一致步骤 4:安装——与正常部署相同
做什么: 按正常流程安装即可,唯一区别是用搬运过来的部署包代替在线安装命令。
所有命令必须以 root 身份执行,先切换到 root:
sudo su root解压部署包后安装:
tar -xzf cube-sandbox-one-click-<version>-<arch>.tar.gz
cd cube-sandbox-one-click-<version>-<arch>
cp env.example .env
# 按需编辑 .env(节点 IP、外部 MySQL/Redis、MIRROR、镜像覆盖变量……)
./install.sh按你的场景对号入座:
- 无
/dev/kvm的云服务器(PVM):跟快速开始走,只把它的步骤 2(在线安装)换成上面的部署包安装,其余照旧。 - 裸金属 / 已有 KVM 的机器:见裸金属部署。
- 添加计算节点:见多机集群部署。部署包原样复用,计算节点只需提前 load 好 cube-egress 镜像(步骤 3.1)。
安装完成后,按正常流程验收:
./smoke.sh控制台地址是 http://<目标主机>:12088,E2B 兼容 API 在 3000 端口(快速开始 — 第四步)。
离线安装的日志长什么样?
registry 不可达时,三个组件镜像各打一行 WARN: pull failed but local image exists; using cached copy 后改用预载镜像,其余服务静默使用预载镜像。都是预期行为,不是错误。 只有出现 pull failed … and no local copy is cached 才说明某个镜像没 load,回步骤 3 检查。
步骤 5(安装后,可选):把模板源镜像推入内网仓库
做什么: 想在离线环境创建模板,就把模板源镜像推送到内网镜像仓库,创建模板时直接引用内网仓库地址。
原理:CubeMaster 构建模板时从 registry 拉取源镜像——内网仓库可达即可,不需要公网。多机集群无需额外处理:CubeMaster 通过内网分发构建产物,计算节点不拉源镜像。
操作分两步:
把源镜像推入内网仓库。在有公网的机器上拉取打包,传到能访问内网仓库的机器(如控制节点)上 load、tag、push(以官方代码解释器镜像为例):
bash# 有公网的机器 docker pull cube-sandbox-int.tencentcloudcr.com/cube-sandbox/sandbox-code:latest docker save -o sandbox-code.tar cube-sandbox-int.tencentcloudcr.com/cube-sandbox/sandbox-code:latest # 能访问内网仓库的机器 docker load -i sandbox-code.tar docker tag cube-sandbox-int.tencentcloudcr.com/cube-sandbox/sandbox-code:latest \ <内网仓库>/cube/sandbox-code:latest docker push <内网仓库>/cube/sandbox-code:latest用内网仓库引用创建模板(详见快速开始 — 第三步):
bashcubemastercli tpl create-from-image \ --image <内网仓库>/cube/sandbox-code:latest \ --writable-layer-size 1G \ --expose-port 49999 \ --expose-port 49983 \ --probe 49999
两个细节:
- 内网仓库需要认证时,加
--registry-username/--registry-password。 - 内网仓库走 HTTP(无 TLS)时,引用必须带
http://前缀,例如http://harbor.internal:5000/ns/app:tag。
也可跳过内网仓库、直接用本地镜像,完整做法见 run-code-env-inheritance 示例。
升级、模板构建与卸载
- 升级 = 新部署包 + 新镜像(tag 会随版本变化)。升级新版本时,重新执行步骤 1 和步骤 3,然后运行
./install.sh --mode=upgrade(详见 one-click README — Target Machine Installation)。 - 离线构建自定义模板镜像:Dockerfile 构建通常要访问
apt/pip。把apt/pip软件源指向内网镜像,或在有公网的环境中提前构建好完整镜像,再按步骤 5 推入内网仓库(做法见本地与远程镜像实践 — 常见问题)。 - 卸载流程不变:
/usr/local/services/cubetoolbox/scripts/one-click/uninstall.sh。
故障排查
| 现象 | 原因 | 解决 |
|---|---|---|
pull failed for <ref> and no local copy is cached | load 的镜像引用与安装器解析出的不一致(tag 或仓库选错) | 把 docker images 的输出与部署包的默认引用对照(env.example,或用 3.1 的 grep 查);检查 MIRROR 是否一致(步骤 3.2) |
找不到 docker,安装器执行 apt-get/yum install docker 并失败 | 内网软件源中没有 Docker 软件包,且未提前安装 | 把 Docker 加入内网源,或提前装好 Docker Engine + Compose(步骤 2) |
| 安装器因 snap Docker 中止 | snap install docker 的沙箱读不到 /usr/local/services | sudo snap remove docker,用软件包方式安装 docker-ce |
安装器安装 dnsmasq 时中止 | 宿主机没有 systemd-resolved,内网源中也没有 dnsmasq | 将 dnsmasq 加入内网源或提前装好;或使用带 systemd-resolved 的操作系统 |
模板构建卡在 phase: PULLING | --image 引用不在内网仓库中,或 CubeMaster 访问不了该仓库 | 确认镜像已推入内网仓库、引用正确;HTTP 仓库检查 http:// 前缀,需要认证时加 --registry-username / --registry-password |