Agent 沙盒的技术选型:Docker、gVisor、Firecracker、Wasm——隔离粒度与性能的取舍

你写了一个 Agent,它替你在网上下载了一个压缩包,然后打算解压执行。你会让它直接在你的 Mac 上跑吗?除非你不要这台电脑了。于是你开始搜“Agent 沙盒”,搜出来 Docker、gVisor、Firecracker、Wasm,四个名字个个都像正确答案,但选哪个?这个坑我踩过,今天说说我的理解。

AI technology illustration

先搞清楚你要防什么

沙盒的本质是隔离,但“隔离”这个翻译骗了很多人。它不只是把代码关起来,而是规定代码能碰到什么、不能碰到什么。不同沙盒的隔离粒度完全不同:有的只是把目录挂载切换一下,有的则完全模拟了一台电脑。

我最早以为 Docker 就是沙盒。你跑个 docker run,进程不是照跑?但只要看过 Docker 的文档就知道,它只是用 namespace 和 cgroups 做了资源限制和命名空间隔离。容器和宿主机共享同一个内核。内核里的漏洞一旦被利用,隔离墙就塌了。

四种方案,各有什么看家本领

Docker:一个高效的进程包装器

Docker 不是安全设备,它是一个打包和分发工具。它解决的是“在我机器上能跑,为什么在你机器上跑不起来”。Docker 官方文档里说得明白,它利用 Linux 内核的隔离能力把进程划分开,但所有容器共用同一颗内核。任何一个能利用内核漏洞的恶意程序,都有可能逃逸到宿主机。历史上爆过一堆容器逃逸漏洞,比如 CVE-2019-5736,就是在 runc 里发现的,容器可以直接覆盖宿主机的 runc 二进制文件。

因此,如果你拿 Docker 当沙盒用,你的威胁模型只适合“代码是良性的,只是怕误操作”。恶意代码吗?Docker 挡不住。

gVisor:用 Go 写一个用户态内核

gVisor 的做法很特别:它把应用程序发出的系统调用全都拦截下来,转到自己在用户态实现的一个“Linux 内核”里去处理。你写代码时还是调用 open、read、write,但真正在内核里执行的,是一个 Go 语言写的模拟层。这个项目由 Google 开源,架构文档里说得很直白:它的目的是提供一个最小攻击面的隔离边界。

代价是性能。每一条系统调用都要经过拦截、模拟、返回,比直接调用真实内核多几个数量级的开销。但好处是,你不需要额外硬件虚拟化,只要内核支持某几个基础特性就能跑,所以一般只比原生慢一点,但在读文件、写文件这类密集调用下可能会慢到让你怀疑人生。gVisor 还有很多简化实现,比如不支持某些 Linux API,所以不是所有程序都能直接跑。

gVisor 还有一个实用价值:它可以接入 Docker 的 OCI runtime,你只需要把默认的 runc 换成 runsc,Docker 容器就自动获得了额外的隔离层。GitHub 仓库里有详细说明。这是我觉得最实用的特性之一。

Firecracker:为无服务器打造的微型虚拟机

Firecracker 是 AWS 为了 Lambda 和 Fargate 专门开发的。官网开头就写:它让你在毫秒级启动一个基于 KVM 的 microVM,每个 microVM 只占用最少的内存。跟传统虚拟机比,它去掉了所有不必要的硬件模拟,只保留一个最小的设备模型,但隔离边界依然是真正的硬件虚拟化:每个 microVM 里有独立的内核,宿主机和客户机之间隔着一层 hypervisor。

这意味着什么?就算客户机里的内核被攻破了,攻击者也只是拿到一个虚拟机的 root,他必须再找一个 hypervisor 的漏洞才能碰到你。这是目前生产环境里最硬的一层隔离之一。代价是每个 VM 有自己的内存开销(几百 MB 起步),而且需要支持 KVM 的环境。你本地开发机的 Docker Desktop 里跑 Firecracker,基本跑不了——需要完整的 Linux + KVM。

AWS 官方博客介绍过,Lambda 和 Fargate 正是靠它实现了大规模多租户隔离,冷启动时间被压到 150 毫秒以内。这个数据是真实可查的。

Wasm:在语言层面把权力锁死

Wasm 和上面三个完全不是一个维度的。它根本不是操作系统级的隔离,而是语言级的。你写一个 Rust / C++ 程序,编译成 .wasm,然后在 wasmtime、WasmEdge 这类运行时里执行。这个运行时只给程序一个接口列表,程序想做什么全由宿主决定。没有系统调用,没有文件描述符,没有网络 socket,除非运行时的“能力”主动注入。

这里的关键是 WASI(WebAssembly System Interface),它定义了 Wasm 程序访问操作系统资源的标准接口。WASI 采用能力模型:程序要打开哪个文件、连接哪个地址,必须由宿主在启动时显式授权。没有授权,函数根本不存在。这比任何 Linux 的权限控制都更细粒度。

所以 Wasm 的隔离粒度是最细的,性能损耗也最低——因为根本没有上下文切换。但它能做的事也最少。你不能在 Wasm 里随便 fork、exec、操作 GPU。如果你需要一个能跑任意系统调用的通用计算环境,Wasm 给不了你。

一张表看透四种方案

方案 隔离层级 安全边界 启动速度 性能损耗 适合场景
Docker 内核命名空间 共享内核,弱 毫秒级 接近零 打包分发、本地开发、垂直扩展
gVisor 用户态内核 强(隔离系统调用) 毫秒级 中高(Syscall 开销) 多租户容器、不可信代码隔离
Firecracker 硬件虚拟化 很强(完整VM) 数十毫秒 低-中(VM 开销) Serverless、强隔离多租户
Wasm 语言级能力 可设计(能力模型) 微秒级 极低 插件系统、CDN 边缘、纯函数执行

性能与安全的取舍,不是一条直线

你可能会想,越安全就一定越慢,但 Wasm 打破了这个直觉。因为它的隔离不依赖操作系统,纯粹靠编译器把非法操作在编译阶段就变成了不可能。所以它可以在 1 微秒内启动一个执行环境,吞吐量接近原生。但它限制了你只能做“能被编译成 Wasm 的事情”。

Firecracker 和 gVisor 就不同了。它们要支持“完整”的 Linux API,所以不可避免地要引入性能开销。gVisor 在计算密集型任务上的损耗可能不大,但在系统调用密集的场景(比如文件复制、网络转发)会高出不少。Firecracker 的损耗主要来自虚拟化本身的 CPU 开销,和传统虚拟机相比已经压得很低,但仍需要固定内存和冷启动时间。

这里我想说一个我踩过的坑。最早我在项目里用 Docker 容器跑用户提交的代码,以为加了 --read-only--cap-drop ALL 就安全了,结果被安全测试的人打脸——只要容器里有 setuid 二进制或者未挂载的 procfs,就能造成不少麻烦。后来我翻了很多资料,才发现容器隔离的安全模型和 VM 完全不是一回事。将 Docker 用作沙盒,只是在“资源配额”上做到了,在“安全边界”上远远没做到。

怎么选:按你的威胁模型来

  • 你的 Agent 只跑你自己写的、被信任的脚本——Docker 就够了。它干净、顺手、生态成熟,哪怕出了问题,你重启一下容器就行。
  • 你的 Agent 需要执行从互联网下载的、来源不明的代码——至少上 gVisor 或 Firecracker。gVisor 省内存、启动快,适合高并发小任务;Firecracker 更重但更安全,适合需要完整系统能力的任务。
  • 你的 Agent 不需要操作系统 API,只是一些计算逻辑(比如写 JSON、做验证、解析数据)——用 Wasm。它比任何一种 OS 级沙盒都快,而且资源占用可以忽略不计。
  • 最极端的情况:你的 Agent 要做的事情本身就是危险的(比如反编译、渗透测试),那最好用 Firecracker 再叠一层 gVisor,双重保险。

很多人的误区是:先选一个看着酷的沙盒,再往里塞自己的 Agent。正确做法是先把 Agent 要做的事列出来,看看它访问哪些系统资源,需要哪些 API。如果它只需要读写几个文件、执行几段代码,Wasm 足够了。如果它要 fork、exec、连 socket,那你只能选 gVisor 或 Firecracker。

实操:一个组合思路

我现在做 Agent 时,会先用一个“执行规划器”分析不可信代码的类型。如果它只是一个 Wasm 模块,直接丢进 wasmtime,按需注入 WASI 权限;如果它是一个原生 ELF,我会启动一个 Firecracker microVM,挂载只读根文件系统,网络通过 TAP 设备接到独立网段,所有 inbound 连接都记录日志。这样既拿到了近似原生的速度,又把风险限制在最小的圈里。

但这套方案需要不少工程投入,如果你只想快速上线,那就选个现成的:gVisor 的 runsc 可以直接替换 Docker 的 runtime,Firecracker 也有 firecracker-containerd 项目让你用容器镜像直接跑 microVM。选型时关注三个指标:你对延迟的容忍度、你的威胁模型、你愿意为隔离付多少成本。

我的结论与偏见

如果你做的是一个能执行任意代码的 Agent,永远把 Docker 排除在“安全方案”之外。它只是打包工具,不是沙盒。至少上 gVisor 或 Firecracker。而如果你能把 Agent 的能力设计成“纯函数”,那么 Wasm 可能是未来最主流的选择——因为它的隔离原理决定了它天然适合做权限最小化。

原创文章,作者:guanweilu,如若转载,请注明出处:https://guanweilu.cn/article/459.html

(0)
上一篇 4天前
下一篇 4天前

相关推荐