Skip to content
← 博客2026年10月25日 · Kernflux

Firecracker、gVisor 还是容器:AI 代码沙箱(sandbox)该用哪种隔离 ​

AI 智能体会生成代码并执行,强化学习的 rollout 更是成千上万地运行模型写出的命令。这些代码不可信:它可能以 root 运行、尝试逃逸、扫描网络、耗尽资源。所以执行它的沙箱(sandbox)首先要回答一个问题:用什么隔离?

先说结论:

  • 运行不可信代码,用 microVM(例如 Firecracker):每个 sandbox 有自己的内核,攻击面是少量虚拟设备,而不是宿主机内核的全部系统调用。代价是需要 KVM,以及每个 VM 多一份 guest 内核的内存。
  • 没有 KVM(普通云主机没开嵌套虚拟化),又想比容器隔离更强,用 gVisor:它在用户态实现了一个 Linux 兼容的内核,不需要硬件虚拟化。代价是兼容性和系统调用密集负载的性能。
  • 代码可信、或者要 GPU、要极致密度,用容器:最快、最省,但和宿主机共享内核,内核漏洞就可能逃逸。
  • 要完整的操作系统或 PCI 直通,用 QEMU 完整虚拟机。

下面展开四种隔离的原理和取舍,以及我们在开源项目 OpenDsec 里的实测数据。

一张表看懂 ​

容器gVisorFirecracker microVMQEMU 完整虚拟机
内核与宿主机共享用户态的「应用内核」(Sentry,Go 编写)处理系统调用每个 VM 自己的 Linux 内核,靠 KVM 硬件虚拟化每个 VM 自己的内核,完整的设备模型
sandbox 里的代码直接面对的宿主机内核的系统调用(可以用 seccomp 收窄)Sentry(它不把系统调用直接转给宿主机内核)少量虚拟设备(网卡、块设备、vsock 等)和 KVM更多的虚拟设备
需要 /dev/kvm不需要不需要(默认的 systrap 平台);有 KVM 时可以用更快的 KVM 平台需要需要
兼容性原生不是所有系统调用和 /proc、/sys 文件都实现了完整 Linux完整系统,包括别的操作系统
性能取舍几乎没有额外开销系统调用密集的负载可能明显变慢纯计算超过裸机的 95%(官方规格)启动更慢,内存开销更大
许可证—Apache-2.0Apache-2.0GPL-2.0

gVisor 和 Firecracker 的说法都来自它们的官方文档,链接见文末。

容器:共享内核,靠收窄接口 ​

容器是 Linux 内核的几个功能组合起来的:namespace 隔离视图(进程、网络、挂载点),cgroup 限制资源,overlayfs 提供文件系统。sandbox 里的进程直接调用宿主机内核,所以:

  • 快和省:没有虚拟化层,启动就是起一个进程,内存只算进程自己用的。
  • 安全取决于内核接口收得有多窄:去掉不需要的能力(capability),用 seccomp 拒绝危险的系统调用(挂载、bpf、userfaultfd、内核模块、创建用户命名空间……)。但剩下的几百个系统调用仍然直通宿主机内核,内核里任何一个可被利用的漏洞都可能导致逃逸。

所以容器适合运行可信的代码:构建镜像、你自己写的评测程序、需要 GPU 的训练任务。

gVisor:在用户态再实现一个内核 ​

gVisor 的思路是不让 sandbox 直接碰宿主机内核。它的核心组件 Sentry 是一个用 Go 写的「应用内核」,实现了 Linux 的系统调用接口:sandbox 里的进程发起系统调用,被平台层(默认是基于 seccomp 的 systrap)截获,交给 Sentry 处理。文件访问再交给另一个宿主机进程 Gofer。

  • 优点:不需要硬件虚拟化,普通云主机也能用;以 OCI 运行时 runsc 的形式提供,Docker 和 Kubernetes 可以直接用;资源占用灵活,没有固定的 VM 开销。
  • 代价:官方文档明确说,gVisor「目前没有实现所有系统调用和 /proc、/sys 文件」,系统调用密集的负载性能可能较差。智能体的代码什么都可能跑(编译、包管理器、数据库),兼容性问题要实际测试。

托管服务 Modal 的 sandbox 默认就用 gVisor。

Firecracker microVM:每个 sandbox 一个精简的虚拟机 ​

Firecracker 是 AWS 为 Lambda 和 Fargate 开发的虚拟机监视器(VMM),开源,Apache-2.0。它用 KVM 跑真正的虚拟机,但去掉了几乎所有不需要的设备,只保留网卡、块设备、vsock、熵源、pmem 等少数几种。官方规格:

  • 从收到启动请求到 guest 内核开始运行 ≤125 ms;
  • VMM 线程的内存开销 ≤5 MiB(1 vCPU、128 MiB 的 VM);
  • 纯计算性能 超过裸机的 95%。

隔离上,sandbox 里的 root 只是 guest 内核的 root,要逃逸得先攻破 Firecracker 的少量虚拟设备或 KVM。生产环境再用 Firecracker 自带的 jailer 启动:chroot、cgroup、namespace,再降权运行,加上按线程的 seccomp 过滤。

代价:需要 KVM(裸金属,或开了嵌套虚拟化的云主机);每个 VM 要多一份 guest 内核和它的内存;不支持 GPU 直通。

除了隔离,microVM 还有一个容器不容易做到的能力:内存快照。整个 VM 的内存可以保存下来,之后在几十毫秒内恢复,运行中的进程原样继续。这让「从快照启动」「暂停后恢复」「连同内存 fork」都成为可能。E2B 也是基于 Firecracker。

QEMU 完整虚拟机 ​

QEMU 提供完整的设备模型:可以跑镜像自己的 init、别的操作系统,也可以把 GPU 通过 PCI 直通给 VM。代价是启动更慢、内存开销更大、攻击面也更大。适合「必须是完整系统」的任务,不适合作为大量 sandbox 的默认选择。

实测:OpenDsec 的三种后端 ​

OpenDsec 同时提供容器、Firecracker microVM 和 QEMU 完整虚拟机三种后端(不提供 gVisor),调用方在创建时明确选择。下面是项目的裸金属测试机(2 × AMD EPYC 9Y24,384 线程,1.5 TB 内存)上的数据:

容器Firecracker microVMQEMU 完整虚拟机
启动约 0.1 s冷启动约 0.1 s;从内存快照约 55 ms约 0.23 s
单个创建,经 API(含网络、TLS)约 65 ms约 190 ms约 300 ms
暂停冻结进程,内存可以换出到 swap拍内存快照后结束进程,内存全部释放;恢复约 50 ms停止 vCPU,内存保留
fork只复制文件连同内存不支持
突发创建两个节点 8,192 个(0.25 核、256 MB),全部成功单个节点 5,120 个(512 MB),全部成功—

5,120 个 microVM 那一项值得多说一句:申请的内存合计 2.6 TB,宿主机实际只用了约 468 GB,平均每个 VM 约 91 MB。做到这一点靠的是:

  • free page reporting:guest 内核把空闲页告诉宿主机,宿主机收回;
  • virtio-pmem 加 DAX:只读的镜像通过 pmem 设备映射进 VM,同一个镜像的页缓存在所有 VM 之间共享,不再每个 VM 各缓存一份。

也就是说,microVM「每个都要一份 guest 内存」的开销,在实际负载下可以压得很低。

OpenDsec 为什么默认用 microVM ​

DeepSeek 的 DSec 论文以容器为主力后端,microVM 只用于需要更强隔离的场景。OpenDsec 把默认改成了 Firecracker microVM(论文解读),原因是:

  1. 隔离:智能体的代码不可信,不共享宿主机内核是最直接的防线。
  2. 内存快照:环境准备好之后拍一个快照,之后每个 sandbox 从快照启动,依赖、加载好的模型、运行中的服务都在,约 55 ms 就能用。
  3. fork:连同内存复制一个运行中的 sandbox,适合树搜索和从同一个状态展开大量 rollout。
  4. 密度够用:上面的实测说明,microVM 的内存开销在实际负载下可以压到每个约 91 MB。

容器后端仍然保留,用于 GPU 任务(Firecracker 不支持 GPU 直通)、对启动和内存最敏感的大批量可信任务,以及没有 KVM 的机器。

无论哪种后端,OpenDsec 都在宿主机上加了同样的几层:出站网络默认拒绝(nftables 加 DNS 代理)、CPU 核心调度(两个 sandbox 不会同时跑在同一个物理核的两个超线程上,挡住经超线程的侧信道)、每条命令的输出上限;智能体和评测还可以用不同的用户运行。详见安全模型。

怎么选 ​

你的情况建议
运行 AI 生成的、不可信的代码,有裸金属或能开嵌套虚拟化Firecracker microVM
运行不可信的代码,但只有普通云主机、没有 KVMgVisor(先测一下你的负载的兼容性和性能)
已经在 Kubernetes 上,想换一个更强的运行时gVisor(runsc),或者 Kata Containers 这类把容器跑在 VM 里的方案
代码可信,追求速度和密度,或者需要 GPU容器,配合 seccomp 和最小的能力集
需要完整的操作系统或 PCI 直通QEMU 完整虚拟机
需要暂停后恢复、从快照启动、连同内存 forkmicroVM

常见问题 ​

Firecracker 和 gVisor 哪个更安全? ​

两者都比普通容器强,思路不同。Firecracker 用硬件虚拟化,sandbox 面对的是少量虚拟设备和 KVM;gVisor 在用户态重新实现内核接口,sandbox 面对的是 Sentry。运行不可信代码时,有 KVM 的机器上我们更推荐 microVM:边界是硬件虚拟化,而且还能做内存快照。

Docker 容器能用来跑 AI 生成的代码吗? ​

可以,但要清楚风险:容器和宿主机共享内核,一个可利用的内核漏洞就可能逃逸。至少要去掉多余的能力、用 seccomp 拒绝危险的系统调用、禁止创建用户命名空间、限制网络。不可信代码优先用 microVM 或 gVisor。

Firecracker 需要什么环境? ​

需要 Linux 宿主机和 /dev/kvm:裸金属服务器,或者开启了嵌套虚拟化的云主机。没有 KVM 就只能用容器或 gVisor。

microVM 会比容器慢很多吗? ​

启动上差别不大:OpenDsec 实测 microVM 冷启动约 0.1 s,从内存快照约 55 ms,和容器在同一个量级。计算性能方面,Firecracker 官方规格是超过裸机的 95%。差别主要在内存:每个 VM 有自己的 guest 内核,但通过 free page reporting 和共享页缓存可以压到很低。

gVisor 支持所有程序吗? ​

不一定。gVisor 官方文档说明它目前没有实现所有系统调用和 /proc、/sys 文件,系统调用密集的负载性能可能较差。上线前要用真实负载测试。

能在 Kubernetes 上用 Firecracker 吗? ​

可以通过 Kata Containers 这类项目(Firecracker 官方说明已集成进 Kata Containers)。OpenDsec 则是自己管理节点上的 Firecracker,不依赖 Kubernetes,见核心概念。

参考资料 ​

文中 gVisor 和 Firecracker 的说法来自它们的官方文档,核对日期 2026-10-25;OpenDsec 的数据来自项目的测试记录。

基于论文 DeepSeek Elastic Compute (DSec)(arXiv:2609.22978)实现。本项目独立开发,与 DeepSeek 没有关系。