拓冰建站拓冰建站
首页 / 资讯中心 / 正文

Cube Sandbox 开发环境指南:用 QEMU 一次性虚机在笔记本 / 云主机上体验与迭代

Cube Sandbox 开发环境指南用 QEMU 一次性虚机在笔记本 / 云主机上体验与迭代【免费下载链接】CubeSandboxInstant, Concurrent, Secure Lightweight Sandbox for AI Agents.项目地址: https://gitcode.com/GitHub_Trending/cu/CubeSandbox本文基于 dev-environment.md 展开并对照仓库dev-env/目录下的全部脚本源码prepare_image.sh、run_vm.sh、login.sh、cube-autostart.sh、sync_to_vm.sh、copy_logs.sh逐一印证实现细节。文中涉及的脚本与配置均以当前仓库实际内容为准。导读Cube Sandbox 是一个面向 AI Agent 的沙箱运行环境其核心依托 KVM 在宿主机上拉起 MicroVM。如果你没有一台独占的 bare-metal 服务器只有笔记本或云主机同样可以完整体验甚至开发 Cube Sandbox仓库根目录下的dev-env/将整个过程脚本化——一次性的镜像准备、虚机启动、自动登录三件套。本文介绍如何在 WSL 2 / Linux 物理机 / 已开启嵌套虚拟化的云主机上用三条命令获得一个可用的开发环境并深入剖析每个脚本做了什么、底层如何实现、常见问题如何排查帮助你不仅会用还能真正把它纳入自己的开发循环。适用场景与边界dev-env/设计为一个“用完即弃”的开发/体验环境适合以下场景想要一个干净的 OpenCloudOS 9 环境快速体验 Cube Sandbox只有笔记本 / 云主机已开启 KVM 和 nested virtualization没有物理服务器想在虚机里迭代 Cube Sandbox不污染宿主机脚本通过 SSH 转发把宿主机产物同步进虚机即可观察改动效果。::: warning 不是生产部署方式 这里明确是开发 / 体验环境。生产部署请走 快速开始 或 多机集群部署在 bare-metal 机器上执行。dev-env/README_zh.md也明确说明该目录设计上就是单节点、密码登录、用完即弃请不要拿来跑真实业务。 :::前置条件与宿主机自检支持的宿主机本文的开发环境脚本需要跑在下面三种宿主机之一Windows 上的 WSL 2需要 Windows 11 22H2并在 WSL 里启用嵌套虚拟化Linux 物理机已开启嵌套虚拟化的 Linux 虚拟机云主机 / 本地虚机均可三者共同要求宿主机能正常使用 KVM ——/dev/kvm存在且可读写。Cube Sandbox 在虚机内还要继续用 KVM 起 MicroVM所以宿主机必须支持嵌套虚拟化否则虚机里拿不到可用的/dev/kvm沙箱创建会失败。软件依赖Linux x86_64 或 aarch64ARM64已启用 KVM存在/dev/kvm开启了 nested virtualization已安装qemu-system-x86_64ARM64 上为qemu-system-aarch64、qemu-img、curl、ssh、scp、setsid。从 prepare_image.sh 的need_cmd检查可以看到还额外依赖rg与python3后者用于解析 qcow2 虚拟大小在 aarch64 上开发环境虚拟机使用 QEMU 的virt机型并以 UEFI 固件启动因此还需安装 EDK2/AAVMF 固件QEMU_EFI.fd例如qemu-efi-aarch64包。run_vm.sh 中的find_aarch64_uefi_firmware会自动依次探测 Debian/Ubuntu、Fedora/RHEL/OC9、Arch、openSUSE 等发行版常见固件路径找不到时报错并提示对应安装命令。脚本会自动检测宿主机架构必要时可用TARGET_ARCH覆盖默认取自uname -m见 prepare_image.sh快速自检ls -l /dev/kvm # Intel cat /sys/module/kvm_intel/parameters/nested # AMD cat /sys/module/kvm_amd/parameters/nested如果nested返回N或0请先在宿主机开启它。以 Intel 为例echo options kvm_intel nested1 | sudo tee /etc/modprobe.d/kvm.conf sudo modprobe -r kvm_intel sudo modprobe kvm_intel从源码层面看run_vm.sh会在启动前做两道硬校验先检查宿主机是否存在/dev/kvm不存在直接报错退出见 run_vm.sh再在REQUIRE_NESTED_KVM1默认时读取/sys/module/kvm_intel/parameters/nested或/sys/module/kvm_amd/parameters/nested只有当值为Y或1时才放行否则拒绝启动见 run_vm.sh。也就是说即使ls /dev/kvm通过宿主机若未开嵌套虚拟化run_vm.sh也会直接拦下。快速上手三条命令获得一个体验环境先克隆仓库进入dev-env/git clone https://github.com/tencentcloud/CubeSandbox.git cd CubeSandbox/dev-env一共三条命令。前两条在同一个终端执行第三条在新终端里执行。第一步准备镜像仅首次./prepare_image.sh脚本会从腾讯镜像站下载官方 OpenCloudOS 9 qcow2并完成初始化操作。从源码看prepare_image.sh 默认的镜像地址为腾讯镜像站mirrors.tencent.com/opencloudos/9.6/images/qcow2/下对应架构的OpenCloudOS-GenericCloud-9.6镜像可用IMAGE_URL覆盖。整个流水线分四段下载与扩容qcow2 未命中缓存时用curl -fL下载到.workdir/随后用qemu-img info --outputjson读取当前虚拟大小若小于TARGET_SIZE默认100G则执行qemu-img resize原地扩容见 prepare_image.sh。之所以扩到 100G是因为虚机内还要嵌套运行多个 MicroVM根分区需要有足够空间。启动虚机并等待 SSH通过run_vm.sh以VM_BACKGROUND1后台拉起虚机然后用SSH_ASKPASS配合setsid自动完成密码认证轮询等待127.0.0.1:10022的 SSH 可用超时 180 秒见 prepare_image.sh。上传并依次执行虚机内初始化脚本grow_rootfs.sh、setup_selinux.sh、setup_path.sh、setup_banner.sh以及默认开启的setup_autostart.sh仅安装 unit不 enable。优雅关机在 guest 内执行sudo shutdown -h now等待 QEMU 进程退出超时 120 秒留下一个可直接启动的 “golden image”。一个镜像只需要跑一次——除非你删掉了.workdir/或者想重新生成一份干净镜像。第二步启动虚机./run_vm.shQEMU 串口会挂在当前终端。不要用Ctrla然后x直接关机这相当于硬断电可能损坏虚机状态。请在另一个终端执行./login.sh登录后在 guest 内运行poweroff正常关机。从源码看run_vm.sh 前台模式使用-nographic -serial mon:stdio把串口控制台直接挂到当前终端QEMU 参数包括-enable-kvm、-machine q35/virt,accelkvm、-cpu host、virtio-rng-pci 随机数设备、virtio-blk-pci 磁盘、以及一条-nic user用户态网络并带上全部端口转发规则。这也是该环境“开箱即用、无需配置网桥”的根本原因——QEMU user-mode networking 在用户态完成 NAT 与端口转发。第三步登录虚机新开一个终端./login.shlogin.sh会登录到虚拟机内root 权限因为 Cube Sandbox 的部署需要在 root 下进行。从源码看login.sh 默认在 SSH 成功后追加sudo -i切换到 root脚本通过临时生成.ssh-askpass.sh内容为默认密码opencloudos配合SSH_ASKPASS_REQUIREforce自动填充密码无需预先配置 ssh key。若想保持普通用户身份可用LOGIN_AS_ROOT0。在虚机内安装 Cube Sandbox进入 root shell 之后直接执行标准的一键安装curl -sL https://github.com/tencentcloud/CubeSandbox/raw/master/deploy/one-click/online-install.sh | bash::: tip 国内环境建议走腾讯云镜像curl -sL https://cnb.cool/CubeSandbox/CubeSandbox/-/git/raw/master/deploy/one-click/online-install.sh | MIRRORcn bash:::安装完成后按常规 快速开始 在虚拟机内创建模板、跑第一个沙箱即可。安装完成后可在虚机内执行curl -sf http://127.0.0.1:3000/health echo OK验证 Cube API 是否存活跑完应能看到核心进程都活着cubemaster、cube-api、cubelet。原网络运行时已内置到cubelet中见 dev-env/README_zh.md。dev-env 里的 cubecow 存储Cubelet 默认使用 reflink-only 的cubecow存储后端。dev 虚机只需要data_path所在文件系统支持 reflink例如xfs -m reflink1或 Btrfs不再需要额外裸盘或 LVM / dm-thin 工具链。[plugins.io.cubelet.internal.v1.storage.cow.*]的默认配置会把 reflink 卷落在data_path/../cubecow-reflink目录下。这与仓库中 Cubelet 的实现相互印证在 Cubelet/storage/legacy_reflink_cleanup.go 中可以看到对旧版work/cubecow-reflink池的清理逻辑Cubelet/storage/s3_snapshot_layout.go 也提到历史对象曾存放于work/cubecow-reflink当前对象则位于xfs/objects下。测试代码 Cubelet/storage/local_test.go 验证了 reflink 配置的root_dir解析路径即为work/cubecow-reflink。因此在 dev 虚机上只要根文件系统使用支持 reflink 的 XFSOpenCloudOS 9 默认即 XFS且prepare_image.sh已把根分区扩容到 100Gcubecow 存储即可开箱工作。宿主机 ↔ 虚机端口映射run_vm.sh启动时会自动配置下面这些转发宿主机虚机用途127.0.0.1:10022:22虚机 SSH127.0.0.1:13000:3000Cube Sandbox 兼容 E2B 的 API127.0.0.1:11080:80CubeProxy HTTP 入口127.0.0.1:11443:443CubeProxy HTTPS 入口127.0.0.1:12088:12088WebUI HTTP以上映射直接体现在 run_vm.sh 的-nic user,...,hostfwd...参数中前三条与原始文档一致后两条来自 dev-env/README_zh.md 的补充说明。所有端口均可通过环境变量覆盖例如CUBE_API_PORT23000 ./run_vm.sh。prepare_image.sh 在虚机内做了什么prepare_image.sh 会通过 SSH 依次向虚机内推送并执行internal/下的四个默认五个辅助脚本1. 扩根文件系统grow_rootfs.shinternal/grow_rootfs.sh 先把根分区撑满整个 100 GB 磁盘。脚本会通过findmnt/lsblk探测根设备与文件系统类型对 LVM 根走pvresizelvextend -r -l 100%FREE链路对普通分区则用growpart扩分区、再按文件系统类型调用xfs_growfs /或resize2fs见 internal/grow_rootfs.sh。prepare_image.sh也支持AUTO_RESIZE_IN_GUEST0只做镜像下载与扩容、跳过虚机内自动扩容。2. 放宽 SELinuxsetup_selinux.sh把 SELinux 切成permissive运行时 /etc/selinux/config双写见 internal/setup_selinux.sh。其原因在脚本注释中解释得很清楚Cube Sandbox 的 MySQL 容器会把/docker-entrypoint-initdb.d以 bind mount 方式挂进容器一旦docker/moby拉入container-selinux策略容器进程会被container_file_t标签限制宿主目录仍保持var_t/user_tmp_t标签于是容器进程被拒绝Permission deniedmysql 容器会反复重启。开发环境是一次性的所以最稳妥的方案就是整体切 permissive。3. 修 PATHsetup_path.sh把/usr/local/{sbin,bin}加到登录 shell 的PATH和 sudo 的secure_path这样无论登录 shell 还是sudo cmd都能直接调用cubemastercli等二进制。4. 安装登录 bannersetup_banner.sh往/etc/profile.d/cubesandbox-banner.sh写入登录 banner之后每次登录都会看到Welcome to the Cube Sandbox development environment!。5. 安装 autostart unitsetup_autostart.sh默认开启安装cube-sandbox-oneclick.servicesystemd unit注意只安装不 enable见 prepare_image.sh 与 internal/setup_autostart.sh 的注释说明。后续是否随开机自动拉起 Cube 组件由用户通过cube-autostart.sh显式决定。常用环境变量三个脚本都支持用环境变量覆盖默认值。下面直接给出当前仓库各脚本的完整变量表。prepare_image.sh变量默认值说明AUTO_BOOT1启动虚机做 guest 内初始化。0跳过只下载 扩容AUTO_RESIZE_IN_GUEST1在 guest 内执行 growpart/resize2fs。0则手动执行internal/grow_rootfs.shSETUP_AUTOSTART1安装 systemd autostart unit不自动 enable。0跳过IMAGE_URLOpenCloudOS 9覆盖源 qcow2 URLTARGET_SIZE100Gqcow2 最终虚拟大小WORK_DIRdev-env/.workdir下载与磁盘工作目录VM_USER/VM_PASSWORDopencloudos/opencloudosguest 凭据SSH_HOST/SSH_PORT127.0.0.1/10022宿主机侧 SSH 转发目标SSH_WAIT_TIMEOUT_SECS180等待 guest SSH 就绪超时SHUTDOWN_WAIT_TIMEOUT_SECS120等待 guest 关机超时FORCE_KILL_ON_EXIT0退出时若 QEMU 仍在运行是否强制 killTARGET_ARCH自动检测覆盖目标架构如aarch64run_vm.sh变量默认值说明VM_MEMORY_MB8192guest 内存MBVM_CPUS4guest vCPU 数SSH_PORT10022宿主机 → guest SSHCUBE_API_PORT13000宿主机 → guest Cube API:3000CUBE_PROXY_HTTP_PORT11080宿主机 → guest CubeProxy HTTP:80CUBE_PROXY_HTTPS_PORT11443宿主机 → guest CubeProxy HTTPS:443WEB_UI_PORT12088宿主机 → guest WebUI HTTP:12088REQUIRE_NESTED_KVM1宿主机未开 nested KVM 时拒绝启动。0跳过沙箱跑不起来VM_BACKGROUND01时后台启动并写qemu.pid与qemu-serial.log供 prepare_image.sh 复用VM_NAMEopencloudos9-cubesandboxQEMU 虚机名login.sh变量默认值说明LOGIN_AS_ROOT10保持普通用户身份不追加sudo -i示例用法# 本次只下载并扩容 qcow2不跑 guest 内的自动扩容。 AUTO_BOOT0 ./prepare_image.sh # 启动虚机时换更多资源 / 换 Cube API 端口。 VM_MEMORY_MB16384 VM_CPUS8 CUBE_API_PORT23000 ./run_vm.sh # 不强制要求 nested KVM只想把系统起来看看不跑沙箱。 REQUIRE_NESTED_KVM0 ./run_vm.sh # 登录时留在普通用户不切 root。 LOGIN_AS_ROOT0 ./login.shrun_vm.sh的默认配置4 CPU、8192 MB 内存SSH 转发127.0.0.1:10022Cube API 转发127.0.0.1:13000虚机内:3000。如果宿主机 13000 端口被占改用CUBE_API_PORT23000 ./run_vm.sh并相应调整E2B_API_URL。进阶把 dev-env 变成真正的开发循环dev-env/不只是“体验环境”其真正价值在于“改代码 → 推到虚机 → 看效果”的开发闭环见 dev-env/README_zh.md。让虚机重启后服务还在cube-autostart.sh默认情况下 cube 组件是裸进程拉起的——虚机一重启就不会自动回来。让 systemd 在每次开机时把它们带回来在宿主机上跑./cube-autostart.sh # 默认子命令enable会先交互确认然后在 guest 内 enablecube-sandbox-oneclick.service。之后每次开机都会自动跑up-with-deps.sh把 MySQL/Redis、cube-proxy、coredns、cubemaster、cube-api、cubelet 一并拉起网络运行时随cubelet一起启动。其他子命令./cube-autostart.sh status # 查看 is-enabled / is-active ./cube-autostart.sh disable # 回退默认同时停掉当前进程STOP_NOW0 可只禁不禁停从源码看cube-autostart.sh 通过 SSH 在 guest 内执行systemctl enable --now/disable/status支持ASSUME_YES1跳过交互确认、UNIT_NAME覆盖 unit 名。若虚机内未安装该 unit例如曾用SETUP_AUTOSTART0准备镜像enable会明确报错并提示先重跑prepare_image.sh或手动在虚机内执行internal/setup_autostart.sh。开发循环make all → sync_to_vm.sh → restart推荐的终端分工./login.sh常驻开着默认直接进 guest 的 root shell然后在宿主机终端里做开发循环make all ./sync_to_vm.sh bin cubelet cubemastersync_to_vm.sh只有一个职责把文件拷进虚机。它不会在宿主机构建、不会重启服务、不会跑quickcheck.sh也不会自动回滚。拷贝结束后把脚本打印出来的重启命令粘进./login.sh那个终端里systemctl restart cube-sandbox-oneclick.service常用示例# 同步 _output/bin/ 里所有已知组件 ./sync_to_vm.sh bin # 只同步指定组件 ./sync_to_vm.sh bin cubemaster cubelet # 推任意文件到 guest ./sync_to_vm.sh files --remote-dir /tmp ./configs/foo.toml # 构建并部署 WebUI 到 guest make -C .. web-sync-dev-env从源码看sync_to_vm.sh的bin子命令会把_output/bin可用OUTPUT_BIN_DIR覆盖下预构建好的二进制按组件映射到 guest 的安装路径cubemaster/cubemastercli→CubeMaster/bincubelet/cubecli→Cubelet/bincube-api→CubeAPI/bincube-runtime/containerd-shim-cube-rs→cube-shim/bin保持一键安装的/usr/local/bin软链指向真实安装路径见 sync_to_vm.sh。已知组件清单共 7 个cubemaster、cubemastercli、cubelet、cubecli、cube-api、cube-runtime、containerd-shim-cube-rs见 sync_to_vm.sh。旧二进制在 guest 里会保留成*.bak脚本不再主动教你 verify/rollback需要的话自己在虚机里处理。manual-release 流程先在宿主机终端里make manual-release ./sync_to_vm.sh files \ _output/release/cube-manual-update-*.tar.gz \ deploy/one-click/deploy-manual.sh然后切到./login.sh的 root 终端里bash /tmp/deploy-manual.sh /tmp/cube-manual-update-*.tar.gz从虚机收日志./copy_logs.sh把 guest 内/data/log可用REMOTE_LOG_DIR覆盖打包并下载到宿主机文件名为data-log-时间戳.tar.gz默认落在dev-env/目录见 copy_logs.sh。打包与下载都在 SSH 端口转发127.0.0.1:10022上完成无需额外开端口。重置 / 清理想重置虚机状态先停掉run_vm.sh删掉dev-env/.workdir/目录再重跑./prepare_image.sh。开发环境本身就是一次性的。一旦虚机里装的东西乱了重建即可。常见问题现象可能原因解决方法虚机内没有/dev/kvm宿主机未开启 nested KVM在宿主机启用 nested virtualization 后重启虚机./login.sh连不上虚机还没启动或宿主机10022端口被占确认./run_vm.sh还在运行或通过SSH_PORT换端口cube-sandbox-mysql反复重启且报Permission denied虚机里 SELinux 还是 enforcing重跑./prepare_image.sh或在虚机里执行setenforce 0 sed -i s/^SELINUXenforcing/SELINUXpermissive/ /etc/selinux/config docker restart cube-sandbox-mysqldf -h /仍然很小虚机内自动扩容没走完看.workdir/qemu-serial.log再把internal/grow_rootfs.shscp 进去手动跑一次宿主机13000端口被占本机有别的服务用CUBE_API_PORT23000 ./run_vm.sh并相应调整E2B_API_URL虚机重启后 cube 组件没了还没开启 autostart跑一次./cube-autostart.sh重启后新二进制不好使新构建有问题看 guest 里/data/log/必要时把对应的*.bak手动移回去再重新systemctl restart目录结构dev-env/ ├── prepare_image.sh # 一次性下载 扩容 qcow2 虚机内初始化 ├── run_vm.sh # 日常启动虚机QEMU/KVM user-mode 网络转发 ├── login.sh # 日常SSH 登录并切到 root ├── cube-autostart.sh # enable / disable / status systemd autostart unit ├── sync_to_vm.sh # 只负责把宿主机产物拷进虚机不 build / 不 restart ├── copy_logs.sh # 从虚机拉取 /data/log 打包归档 ├── internal/ # prepare_image.sh 自动传进虚机执行的辅助脚本 │ ├── grow_rootfs.sh │ ├── setup_selinux.sh │ ├── setup_path.sh │ ├── setup_banner.sh │ └── setup_autostart.sh ├── README.md └── README_zh.md生成的 qcow2 镜像、qemu.pid进程文件、qemu-serial.log串口日志都放在.workdir/该目录被prepare_image.sh、run_vm.sh等脚本通过WORK_DIR环境变量统一引用。短版说明见仓库的 dev-env/README_zh.md。总结dev-env/把“笔记本 / 云主机上体验与迭代 Cube Sandbox”这件事压缩成了三条命令其内部结构其实非常清晰prepare_image.sh负责制造一份“黄金镜像”run_vm.sh负责用 QEMU/KVM 把它拉起来并做好端口转发login.sh负责零配置登录在此之上cube-autostart.sh解决虚机重启后的自愈问题sync_to_vm.sh完成“改码 → 上机 → 重启验证”的开发闭环copy_logs.sh负责把虚机日志带回宿主机。理解这几个脚本的默认值与底层实现嵌套 KVM 校验、qcow2 扩容、SELinux 放宽、reflink 存储依赖不仅能让你顺利跑通体验流程也能在你真正开始改 Cube Sandbox 代码时把dev-env/变成一个高效、可重复的开发工作台。【免费下载链接】CubeSandboxInstant, Concurrent, Secure Lightweight Sandbox for AI Agents.项目地址: https://gitcode.com/GitHub_Trending/cu/CubeSandbox创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
分享:

看完干货,该让你的企业上线了

免费需求沟通 · 48 小时内出具建站方案 · 河南本地可上门