附录 A · Firecracker 技术内幕深度补充
A.1 为什么 AWS 要造 Firecracker
2018 年之前,AWS Lambda 用传统虚拟机(基于 QEMU/KVM)。每次函数调用都要启动完整虚拟机,启动时间在秒级。AWS 团队面对的挑战:Lambda 的商业模式是按调用计费(用户只为执行时间付费),冷启动是最大痛点;安全要求极高(不同用户的函数在同一台机器上跑,必须完全隔离)。传统 VM 太慢,容器太不安全。AWS 需要一个「和容器一样快、和 VM 一样安全」的方案。
Firecracker 在 2018 年 11 月 re:Invent 大会开源,发布时 Lambda 已用它跑了一年多。
设计约束
每一个技术决策都由以下约束驱动:必须小于 125ms 启动(Lambda 冷启动 SLA)→ 砍掉所有不必要设备模拟;必须小于 5MB 内存/实例(单机跑上千函数)→ 最小内核加最少设备;必须 VM 级隔离(多租户安全)→ KVM 硬件隔离;必须没有已知 CVE 逃逸(AWS 安全团队要求)→ Rust 加最小攻击面;不需要 GPU/USB/Sound(Lambda 函数不需要)→ 不实现等于不存在等于不能被攻击。
A.2 VirtIO 设备详解
virtio-net(虚拟网卡)
Lambda 函数需要访问 AWS 内部服务(DynamoDB、S3)和用户 VPC 网络。工作流:Lambda 函数发起 HTTP 请求 → guest Linux 内核 TCP/IP 栈处理 → virtio-net 驱动把网络包写入共享内存(vring)→ Firecracker VMM 从 vring 读取包 → 通过 TAP 设备发到 host 网络 → 到达目标服务。
TAP 设备是一种虚拟网络接口,类比把一根「假网线」的一端插在 VM 里,另一端插在 host 网络上。vring(virtqueue ring buffer)是 VM 和 VMM 之间传递数据的共享内存区域,类比传菜窗口——厨房(VM)把菜放上去,服务员(VMM)从另一边取走。
virtio-blk(虚拟磁盘)
Lambda 函数需要读取代码包、写临时文件、加载运行时。执行 open 系统调用 → guest Linux VFS → ext4 文件系统 → virtio-blk 驱动发起 I/O 请求 → Firecracker VMM 拦截 → 转发到 host 上的文件(raw/sparse disk image)。
Sparse File(稀疏文件)是一种「说大不大」的文件。你创建 10GB 磁盘镜像,但实际只写了 100MB 数据——文件系统只分配 100MB 物理空间。类比买了 10 格书架但只放了 2 本书。
serial console(串口控制台)
调试用途。VM 内核 panic 或函数崩溃时,错误信息通过串口输出到 host 日志系统。为什么不用 VGA 显卡:VGA 设备需要模拟显存、模式切换、寄存器——几千行代码的攻击面。串口只需要一个字符队列——几十行代码。
timer(定时器)
没有定时器,guest 内核不知道过了多久——调度器无法切换进程、超时无法触发。Firecracker 使用 KVM 的 TSC(Time Stamp Counter)透传——让 guest 直接读取 host 硬件时钟,不经模拟。
A.3 内存管理
Balloon Device
balloon 设备让 host 从 guest「回收」未使用内存。类比:guest 是气球,host 可以往气球里充气(告诉 guest 还一些内存回来),guest 把空闲内存标记不可用,host 回收物理页给其他 VM。
这让 overcommit 成为可能——16GB 机器启动 20 个配置 2GB 的 VM(总量 40GB 大于 16GB),只要不同时用满。
内存快照原理
暂停所有 vCPU → 保存 vCPU 寄存器状态 → 保存设备状态 → dump 内存(Full:整块 guest 内存写入文件;Diff:只写 dirty bitmap 标记的修改页)。恢复时反过来。guest 不知道被快照和恢复。
A.4 Rate Limiter 实现
内建令牌桶限速器(Token Bucket),限制每个 VM 的网络和磁盘 I/O。令牌桶类比:桶里每秒放 100 令牌,每发一个网络包消耗一个令牌,用完就等补充。确保即使 VM 内代码尝试 DDoS 也不影响其他 VM。
A.5 Firecracker 的代码组织
核心目录结构:src/firecracker/(主二进制入口)、src/vmm/(虚拟机管理器核心逻辑)、src/devices/(4 个 VirtIO 设备实现)、src/jailer/(安全牢笼)、src/api_server/(REST API 处理)。
总代码量约 5 万行 Rust——对比 QEMU 的 300 万行 C 代码,攻击面缩小了 60 倍。
附录 B · CubeSandbox 核心创新深度补充
B.1 CubeCoW 完整技术设计
三层 CoW 实现
内存 CoW:KVM dirty page tracking,只保存修改的内存页(4KB/页),恢复时 overlay 到基础镜像。磁盘 CoW:底层用 device-mapper thin provisioning + snapshot target,XFS 文件系统为上层。元数据 CoW:序列化 vCPU 寄存器和设备配置(几 KB)存入文件。
Device Mapper 是 Linux 内核的块设备映射层,类比地址翻译表——上层看到的”磁盘块 42”实际可能对应物理磁盘任何位置。Thin Provisioning(精简配置)给 VM 一个”1TB 硬盘”但实际只分配真正写入的空间。
性能代价
顺序读几乎无影响(直接读基础镜像),顺序写放大 3.6x,随机写放大 11.1x。原因:每次写入要先复制原始块再写新块(CoW 本质代价),随机写场景放大最明显。
B.2 CubeEgress eBPF 实现
传统防火墙不够
iptables 只能按 IP 过滤不能按域名;域名 IP 可能变化(CDN);同一 IP 可能多域名(SNI)。
数据流
VM 程序发起 HTTPS 请求 → DNS 查询被拦截 → 检查域名白名单 → 不在则返回 NXDOMAIN → TLS ClientHello 被拦截 → 提取 SNI 字段 → 二次确认 → 不通过则 RST 断开。
SNI(Server Name Indication)是 TLS 握手第一步中客户端明文告诉服务器要连接的域名。NXDOMAIN 是 DNS”域名不存在”回复。
B.3 CubeVS 虚拟交换机
传统 Docker 用 Linux bridge + veth pair,千级并行时内核设备表爆炸。CubeVS 在 eBPF 的 TC 层做二层转发:VM 发包 → TAP 设备 → eBPF 程序查转发表(eBPF map)→ bpf_redirect 直接转发(跳过内核网络栈)→ 目标 VM 收包。
性能优势:每包处理从几十微秒降到几微秒。代价:跳过路由表导致多网卡场景需自己处理路由。
B.4 CubeMaster 集群编排
调度策略
BinPacking(装箱):选最满节点,节省机器数量,成本低但单机负载高。Spread(分散):选最空节点,性能好但需更多机器。Locality(就近):选离用户最近节点,延迟最小。
故障转移
Cubelet 定期向 CubeMaster 发心跳。超时未收到心跳 → CubeMaster 标记节点为”不可用” → 该节点上的沙箱自动迁移到其他节点。
B.5 E2B 兼容的实现细节
CubeAPI 实现了 E2B 的 REST API 规范,做协议转换:E2B SDK 发 HTTP 请求 → CubeAPI 解析 E2B 格式请求体 → 转换为内部格式 → CubeMaster → Cubelet → CubeHypervisor → 返回 E2B 格式响应 → SDK 收到。
附录 C · gVisor Sentry 内部实现
C.1 系统调用拦截模式
ptrace 模式
应用调用 write → CPU 陷入内核 → Linux 内核发现进程被 ptrace → 暂停进程通知 Sentry → Sentry 读取参数内部处理 → 结果写回进程寄存器 → 进程继续。每次 syscall 两次上下文切换,性能代价大但兼容性好。
KVM 模式
应用跑在 KVM guest ring 3 → syscall 触发 VM Exit → Sentry 在 host ring 0 直接处理 → VM Resume。不需要 ptrace 双重切换。这里 KVM 被「滥用」做高效 syscall 拦截——和 Firecracker 用 KVM 做隔离是不同目的。
C.2 Sentry 实现的 Linux 子系统
VFS(完整)、TCP/IP 网络栈 netstack(完整,纯 Go)、进程管理(完整)、内存管理(完整)、信号处理(完整)、文件锁(完整)、epoll/poll/select(完整)、pipe/socket(完整)、inotify(部分)、io_uring(部分)。不支持 perf_event 和 bpf——安全原因不暴露。
C.3 netstack:纯 Go TCP/IP 栈
应用调用 connect → Sentry socket 层 → netstack TCP 三次握手 → netstack IP 层封装 → 通过宿主机 fd 发出。安全优势:宿主机内核 TCP 栈有漏洞时 gVisor 容器不受影响。性能代价:比内核 TCP 栈低 20-40%。
C.4 Gofer:文件系统代理
Sentry 不直接访问宿主机文件系统。应用调用 open → Sentry VFS 解析路径 → 通过 9P 协议请求 Gofer 进程 → Gofer 在宿主机执行真正 open → fd 传回 Sentry。
即使 Sentry 被攻破,攻击者也不能直接访问宿主机文件系统——Sentry 没有任何宿主机文件 fd。双进程安全模型。
附录 D · Daytona 架构深度补充
D.1 异步 Job Queue 设计
为什么不用直接 HTTP 调用
早期设计(v1):API 直接 HTTP 调用 Runner。问题:Runner 重启后进行中的任务丢失;API 等待 Runner 超时时没有重试机制;无法做优先级队列。
现在的设计(v2)
API 在 PostgreSQL 创建 Job → Runner 长轮询数据库 → Runner 拿到 Job 执行 → 结果写回数据库 → Redis 事件总线推给客户端。
长轮询(Long Polling):客户端发请求,服务器不立刻回复而是等到有新数据才回复。比定时轮询高效。
Job 状态机
PENDING → RUNNING → COMPLETED
↘ FAILED → RETRY → RUNNING
↘ PERMANENTLY_FAILED
每个 Job 有最大重试次数。PERMANENTLY_FAILED 后通知用户。
D.2 Daemon 的 5 个内部服务
Toolbox API
提供文件 CRUD、命令执行、Git 操作的 HTTP API。每个沙箱内部跑一个 HTTP Server(默认端口 63100),对外通过 CubeProxy 反向代理暴露。
Terminal Server
PTY(Pseudo Terminal)终端。允许用户通过 WebSocket 连接到沙箱内部,像 SSH 一样实时敲命令。
PTY 是什么:当你在 Mac 打开 Terminal.app 时,系统创建了一个 PTY——它模拟了一个老式终端设备。应用(如 vim、top)向 PTY 写入控制字符(如颜色代码、光标移动),Terminal.app 读取并渲染。Daemon 的 Terminal Server 做同样的事,只是通过网络传输而不是本地。
SSH Server
标准 SSH 协议。你可以 ssh sandbox-id@daytona-host 直连沙箱。Daemon 内嵌了一个 Go 写的 SSH Server(使用 crypto/ssh 库),不需要沙箱里安装 openssh-server。
Recording
会话录制回放。类似 asciinema——记录终端的每一帧输出和时间戳,事后可以回放整个调试过程。对于 Agent 行为审计非常有价值。
Session 管理
跟踪沙箱内运行的所有进程。超时未活动自动清理(garbage collection)。
D.3 Docker 三层隔离详解
第一层:Docker Bridge 网络
每个沙箱连接到独立的 Docker bridge。容器 A 和容器 B 在不同 bridge 上——就像在不同 VLAN 里,即使在同一台机器上也互相看不到。
第二层:iptables 出站过滤
iptables -A FORWARD -i container_br -d 10.0.0.0/8 -j DROP # 禁止访问内网
iptables -A FORWARD -i container_br -d 169.254.169.254/32 -j DROP # 禁止访问云元数据
iptables -A FORWARD -i container_br -o eth0 -j ACCEPT # 允许访问外网
这组规则确保容器不能探测内网(防横向移动)、不能访问云元数据服务(防凭证窃取)。
第三层:独立文件系统
Docker 的 overlay2 存储驱动让每个容器有独立的文件系统视图。容器 A 写入 /tmp/file 不会影响容器 B 看到的 /tmp。
D.4 为什么 57.6K star
产品因素:Dashboard(Web UI 一目了然)、Web Terminal(浏览器里直接敲命令)、VNC(远程桌面,GUI 应用也能跑)、MCP Server(AI Agent 标准集成)、Playground(在线 demo,一键试用)。
技术因素:TypeScript 为主(前端工程师也能贡献)、架构文档齐全、issue 管理规范。
时机因素:在 AI Agent 代码执行需求爆发初期就推出成熟产品。
附录 E · Kata Containers 深度补充
E.1 OCI/CRI 标准兼容的意义
OCI 标准是什么
OCI 定义了三个规范:Image Spec(镜像长什么样)、Runtime Spec(怎么跑容器)、Distribution Spec(怎么分发镜像)。
Kata 实现了 Runtime Spec——意味着任何 OCI 镜像(Docker Hub 上几百万个镜像)都可以在 Kata 里跑,不需要修改。
CRI 接口是什么
Kubernetes 不直接管理容器——它通过 CRI 接口告诉容器运行时该做什么。kubelet(K8s 的节点代理)通过 gRPC 调用 CRI 接口。
kubelet → CRI gRPC → containerd → Kata Shim → 轻量 VM
kubelet → CRI gRPC → containerd → runc → 普通容器
切换只需要改 runtime class,业务代码和部署 yaml 零修改。
E.2 Kata 的 Guest Kernel
Kata 使用定制的 Linux 内核,精简到最小:
| 特性 | 标准内核 | Kata Guest 内核 |
|---|---|---|
| 模块数量 | 数千 | 几十(只保留必需) |
| 启动时间 | 1-3 秒 | <100ms |
| 内存占用 | 60-100MB | 5-15MB |
| 网络模块 | 全部 | 只有 virtio-net + TCP/IP |
| 文件系统 | 全部 | 只有 ext4 + 9p + virtiofs |
这种精简和 Firecracker 的思路一样:不需要的不带 → 启动快 + 攻击面小。
E.3 Kata 的网络模型
Pod 网络命名空间
→ veth pair(一端在 pod namespace,一端在 host namespace)
→ host 端连接到 TAP 设备
→ TAP 设备 attach 到 Kata VM
→ VM 内 virtio-net 驱动收包
对 K8s CNI 插件(Calico、Cilium)完全透明——它们只看到一个普通的 veth pair,不知道背后是 VM。
E.4 CNCF 毕业意味着什么
CNCF(Cloud Native Computing Foundation)是云原生领域最权威的基金会。项目从 Sandbox → Incubating → Graduated 三级跳代表:有活跃社区、有生产用户、有成熟治理。
Kata 2023 年毕业意味着:金融、电信等强合规行业可以放心采用——有基金会背书和持续维护保障。
附录 F · eBPF 技术专题
F.1 eBPF 是什么
eBPF(extended Berkeley Packet Filter)是 Linux 内核的一项革命性技术:允许你在内核里安全地运行自定义程序,不需要修改内核代码或加载内核模块。
日常类比
传统做法:你想给汽车加一个功能(比如超速报警),必须打开引擎盖改发动机线路(写内核模块)。危险、复杂、一不小心车就坏了。
eBPF 做法:汽车出厂时预留了”插件接口”(hook points)。你写一个小程序插到接口上——程序有严格的限制(不能改发动机核心、不能无限循环、不能访问未授权的数据),但能读取各种传感器数据、做判断、触发动作。
eBPF 程序的生命周期
1. 用 C 写 eBPF 程序(通常 < 500 行)
2. Clang/LLVM 编译为 eBPF 字节码
3. 用户态程序调用 bpf() syscall 加载字节码到内核
4. 内核的验证器(verifier)检查程序安全性:
- 不能有死循环(所有循环必须有有限迭代次数)
- 不能访问越界内存
- 不能调用未授权的内核函数
5. JIT 编译为本机代码(x86/ARM)
6. attach 到指定 hook point(如 TC ingress、kprobe、XDP)
7. 每当 hook 触发,程序执行
eBPF Map:内核和用户态的通信桥梁
eBPF 程序跑在内核里,但我们需要从用户态读取它的结果或配置它的行为——这通过 eBPF Map 实现。
Map 是一个内核里的 key-value 存储。eBPF 程序可以读写,用户态程序也可以读写。类比:一个公告板,厨师(内核程序)可以贴上”今日菜品”,服务员(用户态程序)可以看到并告诉客人。
CubeVS 用的 Map 类型:
- HASH map:存储 VM MAC 地址 → TAP 设备 的映射(转发表)
- ARRAY map:存储配置参数(如白名单开关)
CubeEgress 用的 Map 类型:
- HASH map:存储允许的域名列表
- LRU_HASH map:缓存最近 DNS 解析结果
F.2 为什么 CubeSandbox 选择 eBPF
传统方案对比:
| 方案 | 性能 | 灵活性 | 安全性 | 复杂度 |
|---|---|---|---|---|
| iptables | 中等 | 低(只能 L3/L4 过滤) | 低(规则多了容易出错) | 中等 |
| nftables | 较好 | 中等 | 中等 | 中等 |
| Linux bridge | 低 | 低 | 低 | 低 |
| OVS (Open vSwitch) | 好 | 高 | 中等 | 高 |
| eBPF (TC/XDP) | 极好 | 极高 | 高 | 高 |
eBPF 在性能和灵活性上碾压传统方案:可以做七层过滤(看 DNS 内容、看 TLS SNI)、跳过内核网络栈(直接转发)、在线热更新规则(不中断流量)。代价是开发复杂度高——需要同时理解内核网络栈和 eBPF 编程模型。
F.3 CubeVS 的 eBPF 程序结构
// 简化版 CubeVS 转发逻辑(实际代码更复杂)
SEC("tc")
int cube_vs_forward(struct __sk_buff *skb) {
// 1. 解析以太网头
struct ethhdr *eth = bpf_skb_data(skb);
// 2. 查找目标 MAC 对应的 TAP 设备
__u32 *target_ifindex = bpf_map_lookup_elem(&forward_table, eth->h_dest);
if (target_ifindex) {
// 3. 找到了 → 直接转发到目标设备
return bpf_redirect(*target_ifindex, 0);
}
// 4. 没找到 → 丢弃(不允许未知流量)
return TC_ACT_SHOT;
}
这段程序做的事情很简单:看网络包要发给谁(目标 MAC 地址)→ 查转发表 → 找到就转发,找不到就丢弃。但因为跑在内核里(TC hook),每个包的处理时间只有几微秒。
附录 G · KVM 虚拟化原理
G.1 CPU 虚拟化
硬件辅助虚拟化(VT-x / AMD-V)
在没有硬件辅助的时代,虚拟化需要「二进制翻译」——VMM 扫描 guest 的每条指令,把特权指令替换成模拟代码。慢,且容易出错。
2005 年 Intel 推出 VT-x,CPU 硬件原生支持虚拟化:
Root Mode(VMM 运行的模式)
├── Ring 0:VMM 代码(Firecracker)
└── Ring 3:VMM 用户态代码
Non-Root Mode(Guest 运行的模式)
├── Ring 0:Guest 内核
└── Ring 3:Guest 应用
Guest 的代码直接在 CPU 上执行——不需要翻译。只有特定事件(如执行特权 I/O 操作、中断)才会触发 VM Exit,控制权回到 VMM。
VM Exit / VM Entry:类比开会。你(guest)正在工作(VM Entry),突然需要审批(触发 VM Exit),把文件交给领导(VMM),领导处理完(批准/拒绝),你继续工作(VM Entry)。大部分时间你在独立工作(非 Root 模式直接执行),只有特殊情况才打断。
VMCS(Virtual Machine Control Structure)
每个 vCPU 有一个 VMCS——一个保存所有虚拟化状态的数据结构。它包含:Guest State Area(guest 的寄存器、段选择器、CR3 页表基址等)、Host State Area(VM Exit 后恢复的 host 状态)、VM-Exit Controls(哪些事件触发 VM Exit)、VM-Entry Controls(进入 guest 时的设置)。
G.2 内存虚拟化
EPT(Extended Page Table)
没有 EPT 时,guest 的内存访问需要软件翻译(影子页表),每次 guest 修改页表 VMM 都要介入——性能差。
有 EPT 后,CPU 硬件自动做两级翻译:
Guest 虚拟地址 → Guest 物理地址(Guest Page Table)
Guest 物理地址 → Host 物理地址(EPT,由 VMM 维护)
Guest 修改自己的页表不会触发 VM Exit——CPU 硬件自动完成翻译。VMM 只需要维护 EPT(guest 物理 → host 物理的映射)。
G.3 I/O 虚拟化
MMIO 拦截
VirtIO 设备的控制寄存器被映射到特定的内存地址(MMIO region)。当 guest 读写这些地址时:
Guest 写入 MMIO 地址 0xfe001000
→ EPT 标记该地址不可访问
→ 触发 EPT Violation → VM Exit
→ VMM 检查地址 → 发现是 virtio-net 的配置寄存器
→ VMM 模拟写入操作(更新虚拟网卡配置)
→ VM Entry,guest 继续
ioeventfd / irqfd
高频 I/O 路径用 ioeventfd 避免每次都 VM Exit:guest 写入特定 MMIO 地址 → KVM 不 VM Exit,而是直接通知 VMM 的 eventfd → VMM 异步处理。
中断注入用 irqfd:VMM 触发 irqfd → KVM 在下次 VM Entry 时注入虚拟中断 → guest 收到中断。
附录 H · 容器技术基础
H.1 namespace
Linux namespace 是容器隔离的核心。7 种 namespace:
| Namespace | 隔离的内容 | 容器里看到什么 |
|---|---|---|
| PID | 进程 ID | 容器 init 是 PID 1,看不到 host 进程 |
| Mount | 挂载点 | 独立的文件系统视图 |
| Network | 网络栈 | 独立的 IP、路由表、防火墙规则 |
| UTS | 主机名 | 独立的 hostname |
| IPC | 进程间通信 | 独立的消息队列、共享内存 |
| User | 用户/组 ID | 容器 root ≠ host root |
| Cgroup | cgroup 根 | 只看到自己的资源限制 |
类比:namespace 像一副有色眼镜——戴上后你只能看到「属于自己」的部分。PID namespace 让你只看到自己的进程,Mount namespace 让你只看到自己的文件系统。
H.2 cgroup(Control Group)
namespace 做「可见性隔离」——你看不到别人的东西。cgroup 做「资源限制」——你不能用超过配额的资源。
| 资源 | cgroup 控制器 | 效果 |
|---|---|---|
| CPU | cpu, cpuset | 最多用 2 个核、最多 50% CPU 时间 |
| 内存 | memory | 最多用 512MB,超出触发 OOM |
| I/O | blkio | 最多 100MB/s 磁盘读写 |
| 进程数 | pids | 最多 1000 个进程(防 fork bomb) |
| 网络 | net_cls, net_prio | 网络优先级和分类 |
H.3 seccomp-BPF
seccomp 限制进程可以调用的系统调用。BPF 让你写规则:
允许:read, write, open, close, mmap, mprotect...(安全的 syscall)
拒绝:mount, reboot, kexec_load, init_module...(危险的 syscall)
类比:一份白名单——只有名单上的 syscall 才能执行,其他一律拒绝。Docker 默认 seccomp profile 阻止了约 44 个高风险 syscall。
H.4 为什么容器隔离「不够」
所有容器技术(namespace + cgroup + seccomp)共享一个问题:共享内核。
Linux 内核有约 3000 万行代码(5.x 版本),每年发现几十到上百个安全漏洞(CVE)。这些漏洞中,有些可以从容器内触发——利用后可以从容器内逃逸到 host。
真实案例:CVE-2022-0847(Dirty Pipe)——一个内核管道 bug 让非特权用户可以覆写任意只读文件。容器内的攻击者可以利用它修改 host 上的 /etc/passwd(添加 root 用户)。
这就是为什么多租户场景需要 microVM(独立内核)或 gVisor(用户态内核不暴露真实内核攻击面)。
附录 I · 生产环境案例研究
I.1 AWS Lambda:Firecracker 在超大规模的实践
规模
AWS Lambda 在全球 30+ 个区域运行,峰值每秒处理数百万次函数调用。每次调用背后是一个 Firecracker microVM。
架构
用户请求
→ API Gateway
→ Lambda 前端(决定用已有 VM 还是创建新的)
→ 已有 VM:直接调用(热启动,<1ms)
→ 创建新 VM:
→ 选择物理机
→ Firecracker 启动 microVM(<125ms)
→ 加载函数代码
→ 执行函数
→ 返回结果
→ 空闲超时后 VM 被销毁
Firecracker 带来的改进
Lambda 2018 年前:用传统 VM,冷启动 1-3 秒,单机几十个函数。Lambda 2018 年后(Firecracker):冷启动 <200ms(含函数加载),单机上千个函数,成本下降 80%。
安全模型
每个 Lambda 函数运行在独立 Firecracker VM 里。不同用户的函数即使在同一台物理机上,也有完整的 KVM 隔离。即使一个函数的代码有漏洞被利用,攻击者被困在 VM 里——不能看到或影响同机器上其他用户的函数。
I.2 Google GKE Sandbox:gVisor 在 Kubernetes 的实践
场景
GKE(Google Kubernetes Engine)允许用户在 K8s 集群里用 gVisor 做 Pod 隔离:
apiVersion: v1
kind: Pod
spec:
runtimeClassName: gvisor # 只需要加这一行
containers:
- name: my-app
image: nginx:latest
兼容性挑战
Google 内部运行了数万个容器在 gVisor 上。大部分没问题,但某些应用需要调整:数据库(MySQL、PostgreSQL)对 io_uring 有依赖 → gVisor 的 io_uring 支持不完整;ML 训练框架对 CUDA 有依赖 → gVisor 不支持 GPU 透传;某些 Go 程序对 clone3 syscall 有依赖 → gVisor 早期不支持 clone3。
Google 的解决方案
维护一个「兼容性矩阵」——哪些应用测试过能在 gVisor 上跑、哪些不能。对于不能跑的应用,回退到标准运行时(runc)。
I.3 银行/金融行业:Kata Containers 满足合规
场景
银行 A 要把交易系统迁移到 K8s。监管要求:不同交易系统之间必须有「等同于物理机隔离」的安全性。
方案
用 Kata Containers 作为 K8s 的运行时:每个 Pod 是独立 VM,满足「VM 级隔离」的合规要求。
优势
不需要推倒重来:已有的 Docker 镜像、K8s Deployment yaml、CI/CD 流水线全部不变。只需要在 K8s 集群配置里加一个 runtime class。
附录 J · 术语表(按出现顺序)
| 术语 | 英文 | 解释 |
|---|---|---|
| 沙箱 | Sandbox | 隔离的代码执行环境,内部操作不影响外部 |
| 微虚拟机 | microVM | 极精简的虚拟机,只保留最少必需设备 |
| 宿主机 | Host | 运行虚拟机的真实物理机器 |
| 客户机 | Guest | 虚拟机内部的操作系统和程序 |
| 系统调用 | Syscall | 应用请求操作系统做事的方式 |
| 容器 | Container | 通过 namespace/cgroup 做轻量隔离的技术 |
| OCI | Open Container Initiative | 容器行业标准 |
| CRI | Container Runtime Interface | K8s 和容器运行时的标准接口 |
| KVM | Kernel-based Virtual Machine | Linux 内核的虚拟化功能 |
| VirtIO | Virtual I/O | 标准化的虚拟设备接口 |
| eBPF | extended Berkeley Packet Filter | 在 Linux 内核安全运行自定义程序的技术 |
| TAP | Terminal Access Point | 虚拟网络接口设备 |
| vring | Virtqueue Ring Buffer | VM 和 VMM 间的共享内存通信 |
| MMIO | Memory-Mapped I/O | 通过内存地址操作设备 |
| EPT | Extended Page Table | CPU 硬件两级地址翻译 |
| VMCS | VM Control Structure | vCPU 的虚拟化状态数据结构 |
| SNI | Server Name Indication | TLS 握手中的域名标识 |
| CoW | Copy-on-Write | 写时复制——不修改就共享 |
| PTY | Pseudo Terminal | 模拟终端设备 |
| 9P | 9P Protocol | 分布式文件系统协议 |
| seccomp | Secure Computing Mode | 限制可用系统调用的安全机制 |
| namespace | Linux Namespace | 进程可见资源的隔离机制 |
| cgroup | Control Group | 进程资源使用量限制 |
| Sentry | gVisor Sentry | gVisor 的用户态内核组件 |
| Gofer | gVisor Gofer | gVisor 的文件系统代理进程 |
| netstack | gVisor Netstack | gVisor 的纯 Go TCP/IP 栈 |
| Jailer | Firecracker Jailer | Firecracker 的安全牢笼组件 |
| Balloon | Balloon Device | 从 guest 回收未用内存的机制 |
| Token Bucket | 令牌桶 | 限流算法 |
| Device Mapper | 设备映射器 | Linux 块设备映射层 |
| Thin Provisioning | 精简配置 | 按实际使用分配存储 |
| BinPacking | 装箱策略 | 选最满节点的调度策略 |
| Long Polling | 长轮询 | 服务器等有数据时才回复的通信方式 |
| NXDOMAIN | — | DNS “域名不存在”回复 |
| DCO | Developer Certificate of Origin | 开发者原创声明签名 |
| STRIDE | — | 微软安全威胁分类模型 |
| CVE | Common Vulnerabilities and Exposures | 公开安全漏洞编号 |
| CNCF | Cloud Native Computing Foundation | 云原生计算基金会 |
附录 K · 常见问题 FAQ
K.1 基础问题
Q: 我只是想让 AI 帮我写代码,真的需要沙箱吗?
A: 取决于 AI 是否自己执行代码。如果你只是让 AI 写代码、你自己审查后手动跑——不需要沙箱(你就是沙箱)。如果你用 Codex/Claude Code 让 AI 自动执行——需要,因为你不再是每一步的把关者。
Q: Docker 不够吗?为什么还需要 microVM?
A: Docker 够用的条件:单用户自用、能接受共享内核的风险。不够的条件:多租户(不同用户的代码在同一台机器)、对内核漏洞零容忍。Docker 的隔离像办公隔间(共享空调/内核),microVM 像独立别墅(独立一切)。
Q: gVisor 和 Firecracker 能组合使用吗?
A: 可以但没必要。gVisor 在 Firecracker VM 内跑 = 双重隔离(VM 隔离 + 用户态内核过滤),安全性极高但性能很差。实践中选一个就够——多租户选 Firecracker/CubeSandbox,无 KVM 选 gVisor。
Q: Mac 上能跑 CubeSandbox 吗?
A: 不能跑完整功能(Mac 没有 KVM)。但你可以:开发文档/SDK 代码(不需要 KVM)、用 Docker Desktop 跑 gVisor 模式做轻量验证、用云服务器做完整端到端测试。
K.2 竞赛问题
Q: 犀牛鸟 2026 评审看什么?
A: 贡献的质量和影响力——不只是代码量。一篇解决用户真实痛点的文档(如 Integration Guide)可能比一个小 bug fix 更有价值。
Q: 我不会 Rust 能参加 CubeSandbox 赛道吗?
A: 完全可以。贡献路径:文档(Markdown)→ Python SDK 示例(Python)→ Go 上层组件(Go)。Rust 核心代码只是选项之一。
Q: 要不要先学 Firecracker?
A: 推荐先读 Firecracker 的设计文档(design.md)理解微虚拟化基本原理(2 小时),不需要通读代码。然后直接看 CubeSandbox——它的代码量更小、架构更清晰。
K.3 技术问题
Q: CubeSandbox 的 60ms 启动是怎么测量的?
A: 从 API 收到 CreateSandbox 请求到沙箱可以执行第一条命令的时间。不是从零创建 VM(那需要几百毫秒),而是从预创建的 VM 池中通过 CoW 克隆交付。
Q: CubeEgress 能防 DNS-over-HTTPS(DoH)吗?
A: 不能。DoH 把 DNS 查询藏在普通 HTTPS 流量里——CubeEgress 只能拦截明文 DNS 查询。但如果白名单模式开启,DoH 请求的目标域名(如 dns.cloudflare.com)不在白名单里也会被拦截。
Q: 如果 eBPF 程序有 bug 会怎样?
A: Linux 内核的 eBPF verifier 会在加载时拒绝不安全的程序(无限循环、越界访问等)。但逻辑 bug(转发到错误的 TAP 设备)verifier 无法检测——这需要测试覆盖。CubeVS 的 #591 就是一个逻辑 bug。
附录 L · 进一步学习资源
L.1 必读论文/文档
| 资源 | 读什么 | 为什么读 |
|---|---|---|
| Firecracker design doc | firecracker-microvm.github.io | 微虚拟化的权威设计文档 |
| gVisor design doc | gvisor.dev/docs/architecture_guide | 用户态内核的完整设计 |
| Kata architecture doc | github.com/kata-containers/kata-containers/blob/main/docs/design/architecture | OCI 安全容器架构 |
| KVM internals | lwn.net/Articles/658511 | KVM 内核实现详解 |
| eBPF introduction | ebpf.io | eBPF 官方入门 |
| VirtIO specification | docs.oasis-open.org/virtio | 虚拟设备标准规范 |
L.2 动手实验建议
| 实验 | 需要 | 学到什么 |
|---|---|---|
| 在 Linux VM 里跑 Firecracker | 云服务器 + KVM | 微虚拟机的完整生命周期 |
| 用 E2B SDK 创建沙箱 | E2B API key | SDK 的用法和限制 |
| 用 gVisor 跑 Docker 容器 | Docker Desktop(Mac 可用) | 用户态内核的感受 |
| 写一个简单的 eBPF 程序 | Linux + bcc/libbpf | 理解 CubeVS/CubeEgress 的基础 |
| 部署 CubeSandbox(全功能) | Linux + KVM + XFS | 完整的生产级沙箱平台 |
L.3 社区参与
| 社区 | 平台 | 活跃度 |
|---|---|---|
| CubeSandbox | GitHub Discussions + WeChat | 新项目,核心开发者回复快 |
| Firecracker | GitHub Issues + Slack | 成熟社区,贡献门槛中等 |
| gVisor | GitHub Issues + Google Groups | Google 内部团队主导 |
| Kata Containers | GitHub + Slack + 邮件列表 | CNCF 社区治理 |
| E2B | GitHub + Discord | 开发者友好,响应快 |
附录 M · 隔离层级深度对比
M.1 每一层的攻击面分析
L0:应用层权限控制
代表:Claude Code Permission Rules
攻击面:
- LLM Classifier 可能误判(false negative → 危险命令被放行)
- 混淆攻击:
rm -rf /的 base64 编码版本(cm0gLXJmIC8=)classifier 可能不认识 - 提示注入后 LLM 可以自己修改 Permission Rules
逃逸难度:低——单一 prompt 注入可能就够
L1:用户态系统调用拦截
代表:gVisor Sentry
攻击面:
- Sentry 的 Go 代码有 bug → 系统调用处理不当 → 可能泄漏信息或允许越权操作
- Sentry 的 host syscall 接口(Sentry 自身需要调用 host 的 syscall 来完成工作)
逃逸难度:中——需要找到 Sentry 实现中的 bug
L2:OS 进程沙箱
代表:Codex bwrap + seccomp + Landlock
攻击面:
- Linux 内核 namespace 实现漏洞
- seccomp 规则不够严格(白名单太宽)
- 内核本身的 0-day
逃逸难度:中——共享内核,一个内核 CVE 就可能逃逸
L3:容器/平台级隔离
代表:Daytona Docker + 三层锁
攻击面:
- Docker 逃逸漏洞(历史上多次出现)
- iptables 规则配置错误
- 共享内核的所有 L2 问题
逃逸难度:中——比裸 L2 多了网络/文件层保护,但内核风险同
L4:硬件虚拟化
代表:CubeSandbox / Firecracker / Kata
攻击面:
- Guest 内核漏洞(攻击者先拿到 guest root)
- KVM 漏洞(guest 到 host 的逃逸)
- VMM 代码漏洞(Firecracker 的 VirtIO 设备处理)
逃逸难度:极高——需要独立的两条漏洞链(guest kernel + KVM/VMM)
M.2 历史逃逸事件
| 事件 | 年份 | 层级 | 影响 |
|---|---|---|---|
| Docker runc CVE-2019-5736 | 2019 | L2/L3 | 容器内恶意进程覆写 host runc → 下次 docker exec 执行攻击代码 |
| Dirty Pipe CVE-2022-0847 | 2022 | L2/L3 | 内核管道 bug → 容器内可以覆写 host 只读文件 |
| KVM CVE-2023-6693 | 2023 | L4 | MMIO 处理 bug → 但实际利用需要极精确的内存布局 |
| gVisor CVE-2023-33552 | 2023 | L1 | Sentry 内存处理 bug → 特殊 syscall 序列可能读取越界数据 |
观察:L2/L3 级别的逃逸事件远多于 L4——因为共享内核的攻击面大很多。L4 的已知 CVE 虽然存在,但实际利用难度极高(大多数是理论可行但实践很难触发)。
M.3 选型矩阵总结
| 需求 | 推荐层级 | 推荐方案 | 核心理由 |
|---|---|---|---|
| 个人开发者自用 | L0-L2 | Claude Code / Codex | 延迟优先,攻击者即自己 |
| 内部团队共用 | L2-L3 | Daytona / Docker + 加固 | 信任域内,平衡安全和灵活性 |
| 多租户 SaaS | L4 | CubeSandbox / E2B | 不可信代码,必须硬件隔离 |
| 金融/医疗合规 | L4 | Kata / CubeSandbox | 监管要求 VM 级别 |
| RL/Agent 训练 | L4 + 快照 | CubeSandbox(CubeCoW) | 大量并行 + 回滚探索 |
| Mac 开发环境 | L1 | gVisor | 无 KVM,唯一强隔离选项 |
附录 N · CubeSandbox 代码通读指南
N.1 推荐阅读顺序
如果你想通读 CubeSandbox 代码(2-3 天),建议按以下顺序:
第 1 天:理解全局
- README.md — 项目定位和特性概述
- architecture.md(如果有)— 架构图和组件关系
- Makefile / build.sh — 构建方式和依赖
- 目录结构 —
ls -la每个顶层目录
第 2 天:API 和控制流
- CubeAPI 入口 — HTTP 路由定义,理解 E2B 兼容的 API
- CubeMaster — 集群编排逻辑,调度策略
- Cubelet — 单节点调度,生命周期管理
第 3 天:核心组件
- CubeHypervisor — microVM 创建/启动/销毁的核心路径
- CubeCoW — 快照/恢复/克隆的实现
- CubeVS — eBPF 网络转发
- CubeEgress — eBPF 出站过滤
N.2 核心代码路径
「创建沙箱」的完整代码路径
SDK 调用 POST /sandboxes
→ CubeAPI (Rust)
→ 解析请求体(CreateSandboxRequest)
→ 验证参数(template_id 存在?超时合理?)
→ 转发给 CubeMaster(gRPC / HTTP)
→ CubeMaster (Go)
→ 查询所有 Cubelet 状态
→ 选择目标 Cubelet(BinPacking/Spread/Locality)
→ 发送 CreateSandbox 指令给 Cubelet
→ Cubelet (Go)
→ 检查本地资源是否充足
→ 从 CubeCoW 获取 VM 模板的 CoW 副本
→ 调用 CubeHypervisor 创建 VM
→ CubeHypervisor (Rust)
→ KVM 初始化(/dev/kvm ioctl)
→ vCPU 创建
→ 内存分配
→ VirtIO 设备挂载
→ 内核加载
→ 启动 VM
→ 配置网络(CubeVS eBPF 规则)
→ 配置出站策略(CubeEgress)
→ 等待 VM 内 agent 就绪(vsock health check)
→ 返回沙箱 endpoint
→ Cubelet 返回结果给 CubeMaster
→ CubeMaster 返回给 CubeAPI
→ CubeAPI 返回给 SDK
→ SDK 收到 sandbox_id 和 endpoint
「执行代码」的完整代码路径
SDK 调用 POST /sandboxes/{id}/commands
→ CubeAPI → CubeMaster → Cubelet
→ Cubelet 通过 vsock 连接 VM 内 agent
→ Agent(VM 内进程)
→ 创建 PTY
→ fork + exec 命令
→ 通过 vsock 流式返回 stdout/stderr
→ Cubelet 收集输出
→ 逐层返回给 SDK
N.3 重点文件清单
如果你只有半天时间,看这些文件:
| 文件 | 看什么 |
|---|---|
| CubeAPI 的路由定义 | 理解 E2B 兼容的 API 端点 |
| CubeMaster 的调度逻辑 | 理解节点选择策略 |
| CubeHypervisor 的 VM 创建 | 理解 KVM 操作的核心 |
| CubeCoW 的 snapshot/clone | 理解 60ms 启动的秘密 |
| CubeVS 的 eBPF 程序 | 理解网络转发 |
| examples/ 目录 | 理解用户怎么用这个项目 |
附录 O · AI Agent 安全最佳实践
O.1 纵深防御模型
不要只依赖一层防御。最佳实践是多层叠加:
第 1 层:Prompt 安全
└── 系统提示词明确约束 Agent 行为
└── 输入净化(过滤潜在注入)
第 2 层:工具级控制
└── 每个工具声明权限范围
└── 危险工具需要确认(或直接禁用)
第 3 层:沙箱隔离
└── 代码在 microVM 里执行
└── 文件系统隔离(看不到 host 文件)
└── 网络隔离(白名单控制出站)
第 4 层:资源限制
└── CPU/内存/磁盘配额
└── 执行超时自动销毁
└── 进程数限制(防 fork bomb)
第 5 层:审计日志
└── 所有命令和网络请求可追溯
└── 异常行为告警
O.2 Agent 代码执行的安全清单
| # | 检查项 | 解决方案 |
|---|---|---|
| 1 | Agent 执行的代码可能删除重要文件 | 沙箱文件系统隔离 + 快照回滚 |
| 2 | Agent 代码可能外泄敏感数据 | CubeEgress 白名单 + DNS 拦截 |
| 3 | Agent 代码可能消耗所有资源 | cgroup 限制 + 超时销毁 |
| 4 | Agent 代码可能安装恶意包 | 白名单域名 + 只读 base image |
| 5 | Agent 可能被 prompt 注入 | Classifier + 沙箱限制影响范围 |
| 6 | Agent 代码可能尝试逃逸 | KVM 硬件隔离 + Jailer 纵深防御 |
| 7 | 多个 Agent 可能互相影响 | 独立 VM(无共享内核) |
| 8 | 恶意代码可能持久化 | 临时 VM(用完即弃) |
O.3 网络策略推荐配置
开发环境(信任度高)
mode: allowlist
allowed_domains:
- "*.pypi.org"
- "*.npmjs.org"
- "*.github.com"
- "*.githubusercontent.com"
- "*.docker.io"
- "*.crates.io"
生产环境(信任度低)
mode: allowlist
allowed_domains:
- "pypi.org" # 只允许主域名
- "files.pythonhosted.org" # PyPI 下载
# 不允许 GitHub(防代码外泄)
# 不允许任何其他域名
最严格环境(零网络)
mode: deny_all
# 所有出站流量被禁止
# 所需包必须预装在 base image 里
附录 P · 六个项目的社区治理对比
P.1 治理模式
| 项目 | 治理模式 | 维护者 | 贡献门槛 |
|---|---|---|---|
| CubeSandbox | 企业主导 + 开放社区 | 腾讯团队 | 低(文档)到高(Rust 核心) |
| Firecracker | 企业主导(AWS) | AWS 团队 | 高(严格代码标准) |
| gVisor | 企业主导(Google) | Google 团队 | 高(复杂架构 + Bazel 构建) |
| E2B | 创业公司 + 社区 | E2B Inc. | 中(TypeScript 为主) |
| Daytona | 创业公司 + 社区 | Daytona Inc. | 低(TypeScript + 完善文档) |
| Kata | 基金会(CNCF) | 多公司贡献者 | 中(标准化流程) |
P.2 贡献友好度评估
| 维度 | CubeSandbox | Firecracker | gVisor | E2B | Daytona | Kata |
|---|---|---|---|---|---|---|
| Issue 响应速度 | 快(新项目活跃) | 中等 | 慢(Google 内部优先) | 快 | 快 | 中等 |
| PR Review 速度 | 快 | 慢(高标准) | 慢 | 中 | 中 | 中 |
| 文档质量 | 中等(新项目) | 高 | 高 | 高 | 高 | 中高 |
| 新手友好 | 高(#244 文档空位) | 低 | 低 | 中 | 高 | 中 |
| 贡献指南 | 有(CONTRIBUTING.md) | 详细且严格 | 有 | 有 | 有 | 有 |
附录 Q · 性能基准测试方法论
Q.1 如何公平对比沙箱启动时间
测量点定义
| 项目 | 「启动完成」的定义 |
|---|---|
| CubeSandbox | API 返回 sandbox_id + 内部 agent 可响应 vsock 健康检查 |
| Firecracker | guest serial 输出 “boot complete” |
| E2B | SDK 的 Sandbox.create() 返回 |
| Daytona | Daemon 的 Toolbox API 可响应 HTTP 请求 |
| gVisor | runsc run 返回后容器可接受连接 |
| Kata | kata-runtime run 返回后容器进程就绪 |
影响启动时间的变量
- 是否预热:CubeSandbox 用预创建 VM 池 + CoW = 60ms;Firecracker 冷启动 = 125ms
- 镜像大小:大镜像(含 Python、Node.js)加载慢
- 网络条件:E2B 云服务受网络延迟影响
- 存储类型:SSD vs HDD 差异巨大(ext4 vs XFS 也有影响)
- CPU 负载:高负载下所有方案都变慢
正确的测试方法
- 指定硬件(CPU 型号、内存大小、存储类型)
- 指定系统负载(空闲 vs 50% 负载 vs 90% 负载)
- 连续测量 100+ 次,报告 P50/P95/P99
- 区分冷启动(无预热)和热启动(有预热/缓存)
- 声明测量点定义(API 返回 vs agent 就绪 vs 首条命令可执行)
Q.2 存储性能测试
推荐工具:fio(flexible I/O tester)
# 顺序写
fio --name=seq-write --ioengine=libaio --direct=1 --bs=4k --iodepth=64 --rw=write --size=1G
# 随机写
fio --name=rand-write --ioengine=libaio --direct=1 --bs=4k --iodepth=64 --rw=randwrite --size=1G
# 顺序读
fio --name=seq-read --ioengine=libaio --direct=1 --bs=4k --iodepth=64 --rw=read --size=1G
在沙箱内跑同样的命令,对比 host 直接跑的结果 → 得到 CoW/虚拟化层的实际开销。
附录 R · STRIDE 威胁模型完整展开
R.1 STRIDE 模型介绍
STRIDE 是微软提出的安全威胁分类框架:
| 字母 | 威胁类型 | 含义 |
|---|---|---|
| S | Spoofing | 身份伪造(冒充别人) |
| T | Tampering | 篡改(修改不该改的东西) |
| R | Repudiation | 抵赖(做了事但否认) |
| I | Information Disclosure | 信息泄露 |
| D | Denial of Service | 拒绝服务 |
| E | Elevation of Privilege | 权限提升 |
R.2 AI Agent 沙箱场景的 STRIDE 分析
S — Spoofing(身份伪造)
威胁:Agent A 伪装成 Agent B 访问 Agent B 的沙箱资源。
缓解:
- 每个沙箱有唯一 ID + 认证令牌
- SDK 调用时验证令牌(CubeAPI 层)
- VM 网络隔离——A 的 VM 无法连接 B 的 VM
T — Tampering(篡改)
威胁:恶意代码修改沙箱外的文件、修改其他沙箱的数据。
缓解:
- KVM 内存隔离——VM A 完全看不到 VM B 的内存
- 文件系统隔离——每个 VM 有独立的 rootfs
- CubeCoW 快照——篡改后可以恢复
R — Repudiation(抵赖)
威胁:Agent 执行了恶意操作后否认。
缓解:
- 审计日志——所有 API 调用有时间戳和调用者信息
- Session recording——终端操作可回放
- 网络日志——CubeEgress 记录所有出站请求
I — Information Disclosure(信息泄露)
威胁:恶意代码读取其他沙箱的密钥、环境变量、文件。
缓解:
- KVM 隔离——无法读取其他 VM 的内存
- 网络隔离——无法访问 host 的服务(如 metadata service)
- CubeEgress——即使读到了也发不出去
D — Denial of Service(拒绝服务)
威胁:恶意代码耗尽 CPU/内存/磁盘/网络,影响其他沙箱。
缓解:
- cgroup 资源限制(每个 VM 有 CPU/内存上限)
- Token Bucket 网络限速
- 磁盘配额
- 超时自动销毁
E — Elevation of Privilege(权限提升)
威胁:沙箱内的非 root 用户获取 root → 从 VM 逃逸到 host。
缓解:
- 即使沙箱内获得 root,也只是 guest root——不影响 host
- KVM 隔离确保 guest root 不等于 host root
- Jailer 确保即使逃出 VM,VMM 进程也是低权限
附录 S · 从零搭建 CubeSandbox 开发环境
S.1 硬件要求
| 组件 | 最低要求 | 推荐配置 |
|---|---|---|
| CPU | x86_64, 支持 VT-x | 8 核+ |
| 内存 | 8GB | 32GB+ |
| 存储 | 20GB SSD | 100GB+ NVMe SSD |
| KVM | /dev/kvm 存在 |
— |
| 文件系统 | XFS(CubeCoW 要求) | XFS on LVM |
S.2 Linux 环境准备
# 1. 确认 KVM 支持
ls /dev/kvm
# 如果不存在:检查 BIOS 是否开启 VT-x,或检查是否在嵌套虚拟化环境
# 2. 确认 XFS 文件系统
df -T /path/to/cubesandbox/data
# 必须显示 xfs。如果不是,需要创建 XFS 分区:
# mkfs.xfs /dev/sdX && mount /dev/sdX /data
# 3. 安装依赖
sudo apt update
sudo apt install -y build-essential git curl wget \
qemu-utils libglib2.0-dev libfdt-dev libpixman-1-dev \
pkg-config meson ninja-build
# 4. 安装 Rust
curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh
source ~/.cargo/env
# 5. 安装 Go
wget https://go.dev/dl/go1.22.0.linux-amd64.tar.gz
sudo tar -C /usr/local -xzf go1.22.0.linux-amd64.tar.gz
export PATH=$PATH:/usr/local/go/bin
# 6. Clone CubeSandbox
git clone https://github.com/TencentCloud/CubeSandbox.git
cd CubeSandbox
S.3 构建和运行
# 构建所有组件
make build
# 运行单节点模式(开发用)
make dev
# 跑示例
cd examples/python-hello-world
python example.py
S.4 Mac 用户的替代方案
# Mac 不能跑 KVM,但可以做以下事情:
# 1. 文档开发
cd docs/
npm install
npm run dev # VitePress 本地预览
# 2. Go 组件开发和测试(CubeMaster/Cubelet 的非 KVM 部分)
cd components/cubemaster
go test ./...
# 3. Python SDK 开发
cd sdk/python
pip install -e ".[dev]"
pytest tests/unit/ # 单元测试(mock KVM)
# 4. 用云服务器做完整验证
# 推荐:腾讯云/阿里云裸金属服务器(支持 KVM),按量付费
ssh user@cloud-server
cd CubeSandbox && make build && make test-e2e
附录 T · 微虚拟化的历史与未来
T.1 虚拟化的四个时代
第一代:全软件模拟(1960s-2000s)
IBM 大型机的 CP-67、VMware Workstation。完全用软件模拟硬件——每条特权指令都被 VMM 拦截并翻译。慢(性能是原生的 10-30%),但灵活(什么都能模拟)。
第二代:硬件辅助虚拟化(2005-2015)
Intel VT-x (2005)、AMD-V (2006)。CPU 硬件原生支持虚拟化——guest 代码直接在 CPU 上执行,只有特权操作才 VM Exit。性能接近原生(95-99%)。
代表:KVM (2007)、Xen (2003 重构)、Hyper-V (2008)。
第三代:微虚拟化(2015-2022)
Firecracker (2018)、NEMU (2018)、Cloud Hypervisor (2019)。不是虚拟化技术的革新——还是 KVM——而是 VMM 实现的革新。砍掉不需要的设备模拟,把 VMM 从百万行代码缩减到几万行。
第四代:AI-Native 沙箱(2023-今)
CubeSandbox (2025-2026)、E2B (2023-2024)。不是虚拟化技术的变化——还是 microVM——而是上层产品的变化。面向 AI Agent 的 SDK、快照回滚、网络策略、集群编排。
T.2 未来趋势预测
| 趋势 | 可能性 | 影响 |
|---|---|---|
| Confidential Computing(机密计算)进入沙箱 | 高 | 即使 host 管理员也无法看到 VM 内数据 |
| GPU 虚拟化进入 AI 沙箱 | 中 | Agent 可以在沙箱里跑 ML 推理 |
| WebAssembly 作为轻量沙箱 | 中 | 更轻量的隔离(但安全性待验证) |
| 沙箱 SDK 标准化(类似 OCI) | 中 | 不同沙箱产品的 SDK 互通 |
| ARM 架构沙箱(Apple Silicon) | 低-中 | Mac 原生 KVM 支持(目前不存在) |
附录 U · 概念关系图
U.1 六个项目的技术栈关系
┌─────────────────────────┐
│ AI Agent / SDK │
│ (Python/TypeScript/Go) │
└──────────┬──────────────┘
│
┌────────────────┼────────────────────┐
│ │ │
┌────────▼─────┐ ┌──────▼──────┐ ┌─────────▼────────┐
│ E2B SDK │ │ CubeSandbox │ │ Daytona SDK │
│ (Cloud API) │ │ (CubeAPI) │ │ (NestJS API) │
└────────┬─────┘ └──────┬──────┘ └─────────┬────────┘
│ │ │
│ ┌──────▼──────┐ │
│ │ CubeMaster │ │
│ │ (Go编排器) │ │
│ └──────┬──────┘ │
│ │ │
┌────────▼─────┐ ┌──────▼──────┐ ┌─────────▼────────┐
│ Firecracker │ │CubeHypervisor│ │ Docker/Runner │
│ (Rust VMM) │ │ (Rust VMM) │ │ (Go容器管理) │
└────────┬─────┘ └──────┬──────┘ └─────────┬────────┘
│ │ │
└────────────────┼────────────────────┘
│
┌──────────▼──────────┐
│ Linux KVM │ ← gVisor 不走这条路
│ (硬件虚拟化) │
└──────────┬──────────┘
│
┌──────────▼──────────┐
│ CPU VT-x/AMD-V │
│ (物理硬件) │
└─────────────────────┘
U.2 安全边界图
┌─────────────────────────────────────────────────────────┐
│ 物理机(Host) │
│ │
│ ┌─────────────────────────────────────────────────┐ │
│ │ Jailer(7 层防护) │ │
│ │ │ │
│ │ ┌──────────────────────────────────────────┐ │ │
│ │ │ VMM 进程(Firecracker/CubeHypervisor) │ │ │
│ │ │ │ │ │
│ │ │ ┌──────────────────────────────────┐ │ │ │
│ │ │ │ KVM 隔离边界 │ │ │ │
│ │ │ │ │ │ │ │
│ │ │ │ ┌──────────────────────────┐ │ │ │ │
│ │ │ │ │ Guest VM │ │ │ │ │
│ │ │ │ │ ┌─────────────────┐ │ │ │ │ │
│ │ │ │ │ │ Agent 代码 │ │ │ │ │ │
│ │ │ │ │ │ (不可信) │ │ │ │ │ │
│ │ │ │ │ └─────────────────┘ │ │ │ │ │
│ │ │ │ └──────────────────────────┘ │ │ │ │
│ │ │ │ ↑ 逃逸需要 KVM exploit │ │ │ │
│ │ │ └──────────────────────────────────┘ │ │ │
│ │ │ ↑ 逃逸需要 VMM exploit │ │ │
│ │ └──────────────────────────────────────────┘ │ │
│ │ ↑ 逃逸需要 Jailer bypass │ │
│ └─────────────────────────────────────────────────┘ │
│ ↑ 逃逸需要 Host OS exploit │
└─────────────────────────────────────────────────────────┘
附录 V · 竞品产品功能矩阵
V.1 完整功能对比
| 功能 | CubeSandbox | E2B | Daytona | Firecracker | gVisor | Kata |
|---|---|---|---|---|---|---|
| 代码执行 API | ✓ | ✓ | ✓ | ✗ | ✗ | ✗ |
| 文件系统 API | ✓ | ✓ | ✓ | ✗ | ✗ | ✗ |
| 快照/恢复 | ✓ | ✓ | ✓ | ✓ | ✗ | ✗ |
| CoW 克隆 | ✓ | ✗ | ✗ | 基础 | ✗ | ✗ |
| E2B SDK 兼容 | ✓ | ✓ | ✗ | ✗ | ✗ | ✗ |
| 出站过滤 | ✓(eBPF) | ✓ | ✓(iptables) | ✗ | ✗ | ✗ |
| Web Terminal | ✗ | ✗ | ✓ | ✗ | ✗ | ✗ |
| VNC 远程桌面 | ✗ | ✗ | ✓ | ✗ | ✗ | ✗ |
| Dashboard | ✗ | ✓ | ✓ | ✗ | ✗ | ✗ |
| MCP Server | ✗ | ✗ | ✓ | ✗ | ✗ | ✗ |
| OCI/K8s 兼容 | ✗ | ✗ | ✗ | ✗ | ✓ | ✓ |
| 集群编排 | ✓ | 云端 | ✓ | ✗ | ✗ | ✗ |
| 自托管 | ✓ | 复杂 | ✓ | ✓ | ✓ | ✓ |
| KVM 硬件隔离 | ✓ | ✓ | ✗ | ✓ | 可选 | ✓ |
| Mac 支持 | ✗ | ✗ | ✓(Docker) | ✗ | ✓ | ✗ |
V.2 适用场景矩阵
| 场景 | 最佳选择 | 理由 |
|---|---|---|
| AI Agent SaaS 产品(多租户) | CubeSandbox | 强隔离 + E2B 兼容 + 自托管 + 高密度 |
| AI Agent 快速原型开发 | E2B 云服务 | 零运维、三行代码就能用 |
| Agent 调试和开发 | Daytona | Web Terminal + VNC + SSH |
| RL 训练 / 并行探索 | CubeSandbox | CubeCoW 快照回滚 + 千级并行 |
| K8s 安全容器 | Kata | OCI/CRI 原生兼容 |
| Mac 开发环境隔离 | gVisor | 无 KVM 要求 |
| 云服务底层基础设施 | Firecracker | 极简、极稳定、极安全 |
End of Core Reading Guide.