资讯动态

CubeSandbox 自定义模板镜像接入指南:为自有镜像注入 envd 并创建 AI Agent 沙箱模板

发布时间:2026/9/15 15:16:22 来源:尧图企业网站定制
CubeSandbox 自定义模板镜像接入指南为自有镜像注入 envd 并创建 AI Agent 沙箱模板【免费下载链接】CubeSandboxInstant, Concurrent, Secure Lightweight Sandbox for AI Agents.项目地址: https://gitcode.com/GitHub_Trending/cu/CubeSandbox导读envd是 CubeSandbox 的数据面服务承载 SDK 运行命令、读写文件、打开 PTY 会话等全部沙箱操作。本指南以 docs/guide/tutorials/bring-your-own-image.md 为骨架讲解如何把envd加入你自己的应用镜像或容器镜像使其可以被 CubeSandbox SDK 与 E2B SDK 使用既可以直接在cubesandbox-base之上叠加构建也可以把envd和通用入口脚本复制进现有镜像或通过cubemastercli tpl create-from-image在模板创建阶段自动注入。读完本文你将掌握自定义镜像的 Dockerfile 写法、entrypoint 契约、本地验证方法与常见故障排查手段并了解底层源码实现原理。如需了解从 OCI 镜像创建模板的完整通用流程端口、就绪探针、模板查询与删除请参见 从 OCI 镜像创建模板。1. 我的镜像什么时候需要 envdenvd是 CubeSandbox SDK 和 E2B SDK 执行沙箱操作运行命令、读写文件、打开 PTY 会话所依赖的数据面服务。下表对比了是否包含envd时 SDK 能力的差异能力沙箱内有envd时的接口没有envd时envd健康检查可作为模板探针GET :49983/health→ 204该探针端点不可用Sandbox.commands.run():49983上的进程 API命令 API 不可用Sandbox.files.read/write():49983上的文件 API文件 API 不可用创建沙箱时的环境变量初始化POST :49983/init沙箱创建时设置环境变量会失败对于交互式开发与代码执行型沙箱建议保留envd这样你可以用 SDK 运行命令、操作文件并在沙箱内排障。如果镜像只运行自有应用、不需要这些能力则可以省略envd并将模板探针配置为应用自身的 HTTP 健康检查端点。从仓库实现看envd在沙箱内监听49983端口基础镜像默认ENVD_PORT49983入口脚本与模板探针均围绕该端口约定工作详见第 4 节与 docker/Dockerfile.cube-base。2. 快速开始基于cubesandbox-base构建cubesandbox-base是一个预装了envd位于/usr/bin/envd的纯ubuntu:22.04镜像附带一个通用入口脚本cube-entrypoint.sh它在后台运行envd的同时会尊重你提供的任何CMD。三步即可得到可用的模板编写 Dockerfile → 构建并推送 → 创建模板。仓库中提供了可运行端到端示例见 examples/cubesandbox-base-nginx这是一个在cubesandbox-base之上叠加 nginx 的最小演示其 Dockerfile 同时EXPOSE 80 49983并让 nginx 作为前台进程接管日志。2.1 编写 DockerfileFROM ghcr.io/tencentcloud/cubesandbox-base:2026.16 # 安装你自己的工具链 RUN apt-get update \ apt-get install -y --no-install-recommends python3 python3-pip \ rm -rf /var/lib/apt/lists/* RUN pip install --no-cache-dir pandas matplotlib numpy # 可选如果应用需要作为前台进程运行在这里设置 CMD。 # envd 会在后台保持存活。 # CMD [python3, /srv/app.py]注意基础镜像的ENTRYPOINT是[/usr/bin/tini, --, /usr/local/bin/cube-entrypoint.sh]见 docker/Dockerfile.cube-baseCMD默认为空。因此上述 Dockerfile 中的注释掉的CMD会被cube-entrypoint.sh作为用户命令exec而envd继续在后台运行——无需修改任何入口逻辑。2.2 构建并推送docker build -t my-registry.example.com/my-team/my-sandbox:v1 . docker push my-registry.example.com/my-team/my-sandbox:v1镜像仓库必须能被你的 Cube 集群访问到。::: tip 纯 HTTP 仓库 在镜像名前面加上http://前缀例如http://my-registry.example.com/my-team/my-sandbox:v1。不加前缀时CubeMaster 默认按 HTTPS 拉取localhost 与 RFC1918 内网地址除外详见 从 OCI 镜像创建模板 中的说明。 :::2.3 创建 Cube 模板暴露49983envd以及你的应用自己监听的端口cubemastercli tpl create-from-image \ --image my-registry.example.com/my-team/my-sandbox:v1 \ --writable-layer-size 1G \ --expose-port 49983 \ --expose-port your-custom-port \ --probe 49983 \ --probe-path /health--probe 49983 --probe-path /health直接使用 envd 的健康检查端点作为模板就绪探针。创建命令返回后可通过cubemastercli tpl watch --job-id job_id阻塞等待任务进入READY任务完成后会给出template_id之后即可通过 CubeSandbox SDK 或 E2B SDK 基于该模板创建沙箱。更多监控、查询、渲染与删除操作见 从 OCI 镜像创建模板。若需要将模板及其派生的所有沙箱/快照存储到集群共享的 S3 CoW 后端可追加--backend s3这是跨节点 Pause / Resume / FromSnap 的前提。更贴近真实构建的本地与远端构建示例可参见 本地与远端镜像构建实践。3. 向现有镜像注入 envd如果现有镜像不包含envd有两种方式一是在构建自定义镜像时从cubesandbox-base拷贝envd二是让cubemastercli在create-from-image过程中注入。3.1 在 Dockerfile 中拷贝注入在自定义镜像构建时用COPY --from阶段从cubesandbox-base拷贝envd与通用入口脚本FROM e2bdev/code-interpreter:latest USER root # 从 cubesandbox-base 拉取 envd 与通用入口脚本 COPY --fromghcr.io/tencentcloud/cubesandbox-base:2026.16 \ /usr/bin/envd /usr/bin/envd COPY --fromghcr.io/tencentcloud/cubesandbox-base:2026.16 \ /usr/local/bin/cube-entrypoint.sh /usr/local/bin/cube-entrypoint.sh # 上游镜像已有自己的 entrypoint/CMD。要么用 cube-entrypoint.sh 包装它推荐 # 要么从你自己的脚本手动启动 envd —— 见第 4 节手动启动模式。 ENTRYPOINT [/usr/local/bin/cube-entrypoint.sh] CMD [/bin/sh, -c, sudo --preserve-envE2B_LOCAL /root/.jupyter/start-up.sh]第二个示例从一个精简的 Python 镜像起步FROM python:3.11-slim COPY --fromghcr.io/tencentcloud/cubesandbox-base:2026.16 \ /usr/bin/envd /usr/bin/envd COPY --fromghcr.io/tencentcloud/cubesandbox-base:2026.16 \ /usr/local/bin/cube-entrypoint.sh /usr/local/bin/cube-entrypoint.sh RUN pip install --no-cache-dir fastapi uvicorn COPY app.py /srv/app.py EXPOSE 49983 8000 ENTRYPOINT [/usr/local/bin/cube-entrypoint.sh] CMD [uvicorn, app:app, --app-dir, /srv, --host, 0.0.0.0, --port, 8000]构建、推送与模板创建步骤与第 2.2 / 2.3 节完全一致。需要留意的是基于-slim/-alpine的镜像通常没有sudo如果 CMD 里用到了sudo需先apt-get install -y sudo或者直接去掉sudocube-entrypoint.sh并不要求 sudo。3.2 模板创建时自动注入如果不想修改 Dockerfile可以在创建模板时使用--enable-inject-envd上传并注入envdcubemastercli tpl create-from-image \ --image your-image \ --writable-layer-size 1G \ --expose-port 49983 \ --probe 49983 \ --probe-path /health \ --enable-inject-envd选项说明--enable-inject-envd从cubemastercli上传一个envd二进制并写入模板 rootfs。--envd-path运行cubemastercli的机器上的本地路径仅与--enable-inject-envd配合使用。省略时若 CLI 在构建时嵌入了默认envd则使用内嵌二进制。--envd-path指的是运行 CLI 的机器而不是 CubeMaster 主机。CLI 在 multipart 的create-from-image请求中上传二进制CubeMaster 校验后将其写入模板 rootfs 的/usr/local/bin/envd并把其 SHA-256 计入 rootfs 工件指纹因此使用不同envd二进制构建出的工件不会被互换复用。源码级实现细节客户端侧CubeMaster/cmd/cubemastercli/commands/cubebox/envd_upload.go 中的selectEnvdUploadPayload实现选项组合逻辑--envd-path但未启用--enable-inject-envd会报错启用注入但未提供--envd-path且 CLI 未内嵌默认二进制时同样报错。validateEnvdUploadBytes对上传内容做三重校验非空、长度不超过 16 MiB常量MaxEnvdPayloadBytes、必须是 ELF 魔数0x7fELF。随后通过buildCreateFromImageMultipartBody把 JSON 请求体与envd文件打包成 multipart表单字段request与文件字段envd。服务端侧CubeTemplateCenter/pkg/build/envd_inject.go 的injectEnvdPayloadIntoRootfs将上传的二进制写入rootfs的constants.CubeEnvdInImagePath即/usr/local/bin/envd见 CubeMaster/pkg/base/constants/constants.go并返回其 SHA-256 供工件指纹使用。注入与否由注释键cube.master.inject_envd取值true决定ShouldInjectEnvdIntoTemplate。上传二进制的硬性要求必须是非空、不超过 16 MiB、且与目标 rootfs 操作系统和 CPU 架构兼容的 ELF 二进制。例如Linux x86_64 的镜像需要 Linux x86_64 的envd二进制。如果cubemastercli构建时未嵌入默认envd则--envd-path必填。要在构建 CLI 时内置默认二进制先准备好envd然后运行make cubemastercli ENVD_LOCAL_PATH/path/to/envd对于cubebox实例类型CubeMaster 还会保留注入注解并在创建沙箱时自动包装主容器命令在后台启动/usr/local/bin/envd、执行镜像原始命令并把端口49983加入暴露端口。因此使用此方法时原始镜像的 entrypoint 无需改动。命令包装不适用于非cubebox实例类型。4. entrypoint 契约cube-entrypoint.sh仓库内位于 docker/cube-entrypoint.sh实现了一个简单的“envd 后台运行、你的应用前台运行”模式它总是在后台启动envd -port ${ENVD_PORT:-49983}使/health在容器启动后约一秒钟内即可访问。如果容器启动时带用户CMD脚本exec该命令。envd继续在后台运行用户进程拥有stdout/stderr并在停止时收到SIGTERM。如果容器启动时不带CMD脚本只waitenvd使其成为前台进程。环境变量变量默认值用途ENVD_PORT49983envd监听的端口。ENVD_EXTRA_ARGS(空)在-port之后追加的额外参数。若未包含-isnotfc脚本会自动追加以跳过 Firecracker MMDS 查找。ENVD_LOG_FILE/var/log/envd.log捕获 envd stdout/stderr 的文件。设为-则继承容器 stdio。ENVD_BIN/usr/bin/envd如果你把 envd 装到了别处用该变量覆盖。从源码看docker/cube-entrypoint.sh 用 case 匹配检查ENVD_EXTRA_ARGS中是否已含-isnotfc缺则自动补上脚本第 32-35 行 会先确认ENVD_BIN存在且可执行否则以退出码 127 拒绝启动第 37-48 行 的start_envd根据ENVD_LOG_FILE是否为-决定把日志写入文件自动创建目录还是继承容器 stdio并记录envd的 PID。用户命令分支会注册TERM/INT/HUP信号转发并在用户进程退出后以其退出码结束容器第 59-82 行。手动启动 envd如果你已有自己的非平凡 entrypoint不想委托给cube-entrypoint.sh只需在把控制权交给主进程前加一行#!/bin/bash # your-entrypoint.sh # 在后台启动 envd。 # -isnotfc 是必需的它告诉 envd 跳过 169.254.169.254 上的 Firecracker MMDS 查找。 # CubeSandbox 不使用 Firecracker因此 MMDS 服务不存在。没有这个标志 # envd 会尝试访问不存在的 MMDS可能引发网络超时、/init 延迟或 env_vars 注入失败等各种问题。 /usr/bin/envd -port 49983 -isnotfc /var/log/envd.log 21 # ... 你惯常的启动序列 ... exec $-isnotfc是关键参数CubeSandbox 不使用 Firecracker169.254.169.254上的 MMDS 服务不存在缺少该标志会触发对不存在 MMDS 的访问进而导致网络超时、/init延迟或环境变量注入失败。这也是cube-entrypoint.sh会自动追加该参数的原因。5. 本地验证镜像可选在创建模板前可以运行与 CI 在基础镜像上相同的冒烟测试IMGmy-registry.example.com/my-team/my-sandbox:v1 cid$(docker run -d --rm $IMG) docker exec $cid curl -s -o /dev/null -w envd /health %{http_code}\n \ http://127.0.0.1:49983/health # envd /health 204 docker exec $cid /usr/bin/envd -version # 2026.16 docker rm -f $cid如果几秒钟内/health未达到204检查容器内的日志docker exec $cid cat /var/log/envd.log这与仓库 CI 的做法一致发布工作流 .github/workflows/build-envd-base-image.yml 中构建后的镜像被以docker run -d启动脚本循环最多 10 次探测http://127.0.0.1:49983/health是否为204失败时输出/var/log/envd.log并让任务失败通过后再执行envd -version与envd -commit记录版本信息。6. 故障排查症状可能原因修复方法模板创建就绪探针失败envd 未启动 / 启动到了错误的端口确保ENTRYPOINT调用了cube-entrypoint.sh或你自己的脚本在exec前运行了envd -port 49983 。curl :49983/health返回000没有进程在监听entrypoint 被替换用docker inspect --format {{json .Config.Entrypoint}}检查保留cube-entrypoint.sh作为包装。envd 立即退出二进制与内核/init 期望的版本不匹配用docker exec ... /usr/bin/envd -version验证从固定的基础镜像 tag 重新拷贝。envd/init缓慢或create_time env_vars失败缺少-isnotfc标志envd 尝试访问169.254.169.254上无效的 MMDS使用cube-entrypoint.sh会自动追加-isnotfc或手动启动 envd 时在命令行加上-isnotfc。端口 49983 与自己的服务冲突你的应用也监听了 49983把应用移到其他端口并用--expose-port同时暴露两者。CMD 中报sudo: command not found你从没有 sudo 的-slim/-alpine镜像起步执行apt-get install -y sudo或从 entrypoint 中去掉sudo——cube-entrypoint.sh并不需要它。模板创建在PULLING阶段超时Cube 节点无法访问镜像仓库推送到集群可访问的仓库或提供--registry-username/--registry-password。7. 进阶自行重建基础镜像基础镜像由仓库中的单个 GitHub Actions 工作流 .github/workflows/build-envd-base-image.yml 产出。它按选定 tag默认2026.16检出上游e2b-dev/infra在原生linux/amd64与linux/arm64runner 上用 Go 1.25.4 就地编译envd构建 docker/Dockerfile.cube-base对每个架构运行:49983/health冒烟测试最后把多架构 manifest 发布到ghcr.io/tencentcloud/cubesandbox-base。从仓库中的 docker/Dockerfile.cube-base 可以看到构建细节ENVD_REF默认2026.16、GO_VERSION默认1.25.4、UBUNTU_VERSION默认22.04三个构建参数。阶段一envd-builder浅克隆https://github.com/e2b-dev/infra.git到指定 tag在packages/envd下用CGO_ENABLED0交叉编译出静态二进制并通过-ldflags注入 commit SHA随后执行envd -version与envd -commit验证。阶段二运行时基于ubuntu:22.04安装ca-certificates、curl、sudo、tini创建 uid1000 的user账户并授予免密 sudo与 e2b 官方沙箱模板一致保证sandbox.files.read(path)等 SDK 调用无需处处传userroot拷贝envd与cube-entrypoint.sh写入/etc/cubesandbox-envd-ref记录版本最终以ENTRYPOINT [/usr/bin/tini, --, /usr/local/bin/cube-entrypoint.sh]启动。工作流通过docker buildx imagetools create把amd64与arm64的单架构镜像合并为多架构 manifest并同时打上latest、${ENVD_REF}、${ENVD_REF}-ubuntu22.04与sha-${short_sha}多个 tag。附镜像相关仓库文件速览基础镜像定义docker/Dockerfile.cube-base通用入口脚本docker/cube-entrypoint.sh基础镜像发布工作流.github/workflows/build-envd-base-image.yml端到端演示示例examples/cubesandbox-base-nginxenvd 注入客户端校验与 multipart 上传CubeMaster/cmd/cubemastercli/commands/cubebox/envd_upload.goenvd 注入服务端 rootfs 写入与指纹CubeTemplateCenter/pkg/build/envd_inject.go注入注解与路径常量CubeMaster/pkg/base/constants/constants.go通用模板创建流程从 OCI 镜像创建模板本地与远端构建实践本地与远端镜像构建实践【免费下载链接】CubeSandboxInstant, Concurrent, Secure Lightweight Sandbox for AI Agents.项目地址: https://gitcode.com/GitHub_Trending/cu/CubeSandbox创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

读完文章,也想定制专属网站?

尧图设计师 24 小时内与您沟通定制方案

免费获取报价