什么是 Firecracker,为什么所有 Agent 基础设施公司都如此关注它?

什么是 Firecracker,为什么所有 Agent 基础设施公司都如此关注它?

@kylejeong
英语5天前 · 2026年5月11日

AI 功能

253K
290
25
5
564

TL;DR

Firecracker 是一款轻量级 VMM,支持高性能、硬件隔离的 microVM。它是 AWS Lambda 以及新兴的安全 AI Agent 沙箱背后的核心技术。

每天,AWS Lambda 运行着数万亿次函数调用。AWS Fargate 调度着数百万个容器。每一个都是一台完整的虚拟机,拥有自己的内核,在不到一秒的时间内启动。

怎么做到的?大约 50,000 行 Rust 代码,名为 Firecracker,它的存在是因为业界终于承认,一个控制资源使用的 Linux 容器从来就不是为安全边界而设计的。

隔离问题

你笔记本电脑上的每个 Docker 容器,本质上是三个 Linux 内核功能披着一件风衣:

  • 命名空间是眼罩。里面的进程只能看到系统的私有视图:自己的 PID 列表、网络栈、挂载表、主机名和用户 ID。容器内的 PID 1 对应宿主机上的某个随机 PID;容器甚至看不到其他进程。
  • cgroups 是预算。控制组是内核的记账和限速层。它们限制一个进程树可以消耗多少 CPU、内存、磁盘 IO 和网络带宽。
  • seccomp + capabilities 是白名单。capabilities 将 root 权限拆分为约 40 40 个左右的独立特权(绑定低端口、加载内核模块、挂载文件系统等),这样你只需授予需要的权限。seccomp 是一个每进程过滤器,决定进程允许调用哪些系统调用(用户空间访问内核的唯一 API)。

你可以在没有安装 Docker 的情况下自己验证:

Docker 做的其他所有事情(镜像层、注册表、DNS)都是在此基础上进行的编排。

所有这些保护都通过一个单一的 Linux 内核,大约 3000 万行代码,暴露了 400 多个系统调用。宿主机上的每个容器都调用同一个内核。任何一个系统调用中的一个 bug 就可能导致该机器上的所有租户遭殃。

完整的虚拟机通过暴力隔离方案:每个虚拟机都有自己的内核。

现代 CPU 有一个“客户模式”,可以在真实硅片上运行客户指令。只有当客户执行特权操作(接触真实硬件、发生故障、被中断)时,宿主机才会牵涉到宿主机。虚拟机监控器 是一个薄层,负责仲裁这些时刻。

Linux 将其虚拟机监控器作为一个名为 KVM 的内核模块提供,暴露在 /dev/kvm。它依赖于硬件虚拟化扩展(Intel 上的 vmx,AMD 上的 svm):

完整虚拟机的问题是它们又慢又臃肿。经典的 QEMU 虚拟机模拟了一整台虚构的 PC(BIOS、PCI 总线、IDE 控制器、VGA 卡、PS/2 键盘),因为那是 1998 年的操作系统就是按这个标准启动的。镜像有几百兆字节。启动需要几秒钟。在工作负载开始之前,内存占用就已经是几百 MiB。对于一个存活 40ms 的 Web 请求,启动机器的时间是它的 40 倍。

所以你陷入了两难:

  • 容器:50ms 启动,5 MiB 开销,共享内核攻击面。**
  • 虚拟机:5+ 秒启动,300+ MiB 开销,硬件隔离。

每个运行不受信任的多租户代码的人(AWS 和几乎所有现有的 AI 沙箱供应商)都需要同时拥有这两方面的优势。

微虚拟机

VMM(虚拟机监视器)是驱动虚拟机监控器的用户空间进程:它设置客户内存、插入虚拟设备,并告诉 KVM 开始运行客户代码。

微虚拟机是一个删除了 是一个删除了 1998 年 PC 的 VMM:没有 BIOS、没有 PCI 总线、没有 VGA、没有 USB、没有 ACPI(真正的桌面启动所需的所有传统硬件,对于 40ms 的函数调用来说都不相关)。剩下的:KVM、一个串行控制台和几个 virtio 设备(net、block、vsock)。

virtio 是标准的“我知道我在虚拟机里运行”的设备接口。客户通过轻量级的虚拟 NIC 和磁盘(virtio-net、virtio-block)与虚拟机监控器协作,而不是假装驱动真实的 Intel e1000 卡或 IDE 控制器。这种协作,加上上面缺失的所有传统硬件,是微虚拟机启动快的最重要原因。

结果:

  • 结果:
  • 从 VMM 启动到客户用户空间运行 init 运行 init 的用户空间,大约 125ms。
  • 每个 VM 的 VMM 内存开销小于 5 MiB(宿主机为每个 VM 支付的记账内存,在客户为自己分配任何东西之前)。
  • 单台主机上每秒创建 150 个 VM。
  • 与裸机相比,运行时性能损失约 2–8%。

与完整虚拟机相同的硬件级隔离,密度与容器相当。

Kyle Jeong - inline image

Firecracker 是 VMM,即实际与 /dev/kvm 通信并启动微虚拟机的进程。本文的其余部分内容就是整个栈的端到端说明。

Firecracker

2018 年 11 月,AWS 在 re:Invent 上开源了 Firecracker。它已经在生产环境中运行 Lambda,让你的 import pandas 冷启动快得足以按毫秒计费。2020 年,团队在 NSDI '20 上发表了架构论文。

架构

从 Google 的 crosvm 分支出来,用 Rust 重写,删除了超过一半的代码。每个 Firecracker 进程是一个微虚拟机,正好有三种线程类型(在 docs/docs/design.md 中有文档):

  • API 线程是订单台。一个绑定到 Unix 套接字(仅本地 socket,以文件形式存在于磁盘上,不是 TCP 端口)的 REST 服务器。接受启动前的配置和启动后的有限操作。
  • VMM 线程是硬件车间。它假装成客户能看到的每个设备。当客户戳它认为是 NIC 寄存器时,CPU 暂停客户,VMM 处理该操作(“客户踢了 TX 队列,排空它”),然后恢复。机制:客户读/写魔术地址;CPU 将这些陷阱捕获到宿主机。[^mmio]
  • vCPU 线程是运行者。每个客户 CPU 一个,每个都在紧密循环中:要求 KVM 运行客户,直到发生有趣的事情(设备操作、中断、停止),处理它,循环。

它们通过 Rust 通道(进程内、无锁的消息队列)相互通信。客户正好看到四个设备。

Kyle Jeong - inline image

四个设备

  • virtio-net 是 VM 的 NIC,没有 1998 年的模拟。客户将数据包写入 virtqueue(共享内存中的环形缓冲区);VMM 通过宿主机端的 TAP 设备(内核作为文件暴露的虚拟以太网接口)将它们排出,由 io_uring 或 epoll 驱动,这样 VMM 线程就不会阻塞。
  • virtio-block 是 VM 的磁盘,只是宿主机上的文件 IO。客户将扇区请求放入 virtqueue;VMM 对宿主机文件发出简单的 pread/pwrite。没有 IDE、AHCI 或 SCSI。
  • virtio-vsock 是 VM 与宿主机之间的对讲机。使用(上下文 ID,端口)元组而不是 IP/端口对进行寻址,因此客户代理可以(日志、健康 ping、快照元数据),无需客户 IP,也没有任何可伪造的在线数据。
  • 8250 串行 UART 是启动控制台。一个微小的传统串行芯片,固定在某个地址。用于 virtio 启动前的早期启动日志和崩溃转储。便宜、通用、永不消失。

启动微虚拟机,端到端

API 是整个控制平面:配置通道,与数据平面(实际运行客户代码的 vCPU 线程)保持分离。你启动指向 Unix 套接字的二进制文件:

然后向它 PUT 配置:

四个 HTTP 调用。这就是整个控制平面。

Kyle Jeong - inline image

安全洋葱

单一的 KVM 单个 KVM 边界已经很强。Firecracker 在其周围包裹了另外两层。

监狱程序 是一个沙箱构建器。它的唯一工作是在 VMM 运行之前将其封闭起来。它创建一个 chroot(一个 Linux 功能,将进程锁定到单个目录子树,就像该目录是文件系统的根一样;进程根本无法引用其上的任何内容),进入一个新的 PID 命名空间,使其看不到宿主机上的其他进程,切换到非特权 uid/gid,应用 cgroup CPU/内存限制,然后才在监狱内执行 Firecracker 二进制文件:

现在 VMM 进程本身除了专用的 chroot 外没有文件系统,看不到宿主机上的其他进程,也没有 root 能力。如果客户到宿主的逃逸确实通过 virtio 或 KVM 发生,攻击者将落入带有 cgroup 限制的 chroot 中。

Seccomp 是一个每线程的系统调用白名单。任何不在列表上的内容在到达内核的系统调用处理程序之前都会被杀死(或返回 EPERM)。Firecracker 提供三个级别:

  1. 级别 0:关闭。不要在生产中使用。
  2. 级别 1:按系统调用号允许列表。
  3. 级别 2:还约束参数值(例如 ioctl 可以,但只能使用 KVM_RUN 作为命令)。默认和推荐。

每个线程获得尽可能小的表面:API 线程不需要 ioctl(KVM_RUN);vCPU 线程不需要 socket()。一个规则的简化视图:

每个层都必须独立失败,攻击者才能到达宿主机。

快照:Lambda SnapStart 的作弊码

对正在运行的微虚拟机进行快照。在毫秒内恢复,在另一台主机上,进入一个全新的 VMM 进程。跳过内核启动,跳过 init,跳过 JIT 预热。

冻结正在运行的 VM 并将内存 + 设备状态转储到磁盘:

快照捕获了预热后的状态,因此恢复的 VM 在生命周期中间醒来,而不是在开始时。

这正是 AWS Lambda SnapStart 所做的:初始化一次 Java Lambda,对微虚拟机进行快照,并在每次后续冷启动时恢复该快照(公告)。JVM 冷启动突然从 8 秒以上降到亚秒级。

Kyle Jeong - inline image

它们如何配合

gVisor 是一种不同的设计:一个用 Go 编写的用户空间内核,重新实现了 Linux 系统调用接口,作为普通进程运行。客户的系统调用命中 gVisor 而不是宿主机内核,gVisor 决定向下游转发什么(如果有的话)。启动比微虚拟机快,热路径上有 10–30% 的系统调用开销,以及不同的信任边界。

Firecracker 位于“自己的内核,但没有 PCI BIOS”的盒子中:硬件隔离、微小的设备模型,以及毫秒级启动。

选择你的工具:

谁在使用它

列出不基于微虚拟机的无服务器平台几乎更快。

Firecracker 在生产中:

  • AWS Lambda 和 AWS Fargate:原始用例。每个 Lambda 调用都落在 Firecracker 微虚拟机中;Fargate 任务是带有内部容器运行时的 Firecracker VM。
  • [Fly.io Machines](https://fly.io/docs/machines/):每个 fly machine 运行都是一个 Firecracker 微虚拟机,全球分布,亚秒级冷启动和持久磁盘。
  • **几乎你在过去十八个月中使用过的每个 AI 代理代码执行沙箱都运行在 Firecracker 微虚拟机中。

沙箱 API 的形状在供应商之间大致相同:

大约四行代码:一个 Firecracker 微虚拟机启动,一个内核初始化,客户内部的代理进程通过 vsock 接收你的命令,运行它,将结果流回,然后 VM 死亡。

Agent 时代:为什么这一切现在如此重要

一年前,“什么是 AI 沙箱?”还是一个冷门问题。如果 LLM 生成代码,它可能不是 100% 安全地运行在任何机器上,所以你会在一个临时沙箱中运行它。

今天,每个严肃的 AI 产品都附带一个 Agent。它们的沙箱也变得更好,但 Agent 的形状发生了变化,旧的运行时答案不再适合新的形状。

进程内 Agent 与主机级 Agent

第一轮 AI Agent 存在于你的应用程序内部。你导入一个库,连接一个循环,并在现有后端中运行它:

每次调用都是到模型的 HTTP 往返。每次工具调用都是你自己进程中的一个函数。“沙箱”就是你自己的服务器。这是 Vercel AI SDKLangChainOpenAI Agents SDK 的世界。它运行良好,今天仍然承载着大部分生产 Agent。

第二轮不同了。Claude CodeCodexOpenCode 是主机级 Agent:接管机器的二进制文件,而不是存在于你内部的库。它们期望一个真正的 shell、一个包管理器和一个可写磁盘。当你给 Claude Code 一个任务时,它会运行这样的东西:

那是 shell/bash。它需要真正的文件系统、真正的 fork/exec、包管理器、可写磁盘、可访问的网络。这些都无法表示为聊天补全工具模式,并且在与共享内核的容器中与其他租户一起运行是不安全的。

实验室直接在训练后直接在这些框架(模型周围的脚手架)上训练模型:shell、文件编辑器、测试运行器、Agent 循环本身。这意味着“模型 + 训练时训练的框架”和“模型 + 自建脚手架”之间的差距每个季度都在扩大。

每个 Agent 一个完整的 Linux 机器,运行 Agent 刚刚发明的不受信任的代码,这正是 Firecracker 设计用于的工作负载。上面的趋同并非偶然。

我们开始看到更多关于 Agent 围绕计算和框架分离的实验。Anthropic 的 Managed Agents 就是一个例子,其中 Agent 框架在沙箱旁边运行,而不是在沙箱内部。

一些公司甚至正在构建完整的托管文件系统(如 ArchilMesa),为 Agent 提供更好的搜索和存储。

随着 Agent 变得更好并随时间变化,将会有更多有趣的基础设施产品,基于 Firecracker 构建。

你实际为 Agent 基础设施平台支付的是什么

通用的“运行任意代码”沙箱现在已经成为商品。基础设施是完全开源的。微虚拟机层是 Firecracker 或 Cloud Hypervisor,在 Apache 2.0 下可用。容器到 rootfs 的转换是一个 200 行的 Go 脚本。有才华的工程师可以在一个周末搭建一个可用的沙箱平台。

你支付的是与 VM 连接的东西。裸微虚拟机只是入场券。

有趣的产品表面:

  • 可观测性就是产品,而不是调试辅助。 Agent 所做的一切(stdout、系统调用、文件写入、网络请求)都通过一个套接字流向宿主机端的收集器。Agent 构建者需要完整的会话回放,以及每个操作的工件来创建最好的产品。
  • 秘密在线上进行中介,从不交给客户。 客户只看到占位符环境变量;在沙箱内 echo $SECRET 返回占位符。宿主机端的出口代理(每个出站数据包都必须经过它)在宿主机端的 TAP(VM 虚拟 NIC 的内核端,客户无法看到或寻址)处替换真实凭据,针对明确的白名单,并带有每会话审计跟踪。Agent 可以运行它五秒前生成的任意代码,但仍然无法窃取它从未拥有的凭据。
  • 身份在宿主机端签名,而不是在 Agent 内部。 出站请求可以携带加密的每会话身份(包括 Web Bot Auth 签名,基于 HTTP 消息签名 + Ed25519),由宿主机在数据包离开桥接器之前生成。签名密钥永远不会进入微虚拟机。
  • 其他计算与运行时捆绑在同一个微虚拟机中。 Browserbase 将每个 Agent 运行时与同一宿主机上的浏览器 1:1 配对,通常是同一个微虚拟机。Agent 进程和 Chromium 之间的物理距离几乎为零:CDP 命令(Chrome DevTools 协议,用于以编程方式驱动 Chrome 的 JSON-over-WebSocket 格式)通过 Unix 套接字,而不是跨服务网络,因此操作延迟个位数毫秒。屏幕帧不必穿越公共互联网即可进入会话回放。

而且你不能在 Docker 之上干净地缝合所有这些。没有这样的接缝。我们的赌注是,Agent 运行时市场不会由原始计算赢得,而是由最好的可观测性、秘密、身份、合作伙伴关系以及共置计算整合到一个产品表面赢得。

Kyle Jeong - inline image

值得关注的运行时替代方案

  • [Bubblewrap](https://github.com/containers/bubblewrap):无特权用户命名空间沙箱。非 root 用户可以在没有 sudo 的情况下启动沙箱,使用 Flatpak 用于限制桌面应用的相同内核原语。比 VM 轻量,仍共享宿主机内核,因此不能替代微虚拟机处理真正不受信任的代码。但它是微虚拟机内部很好的嵌套隔离层,或者对于你自己宿主机上相对可信的代码来说是一个不错的选择。
  • [V8 隔离区](https://blog.cloudflare.com/cloud-computing-without-containers/):Cloudflare Workers 的模型。每个隔离区是一个单独的 JS 执行上下文,拥有自己的堆,共享一个 V8 进程,可能与其他数千个租户共享。启动约 5ms,比微虚拟机快两个数量级。信任边界是 V8 自己的沙箱;历史上它表现良好,但比虚拟机监控器的边界薄得多。另一个问题:你只能得到 Node 风格的语义。没有 fork、exec、原生模块,只有模拟的文件系统。对于纯 JS Agent 代码来说很强大;如果你需要 pip install numpy,则毫无用处。
  • [gVisor](https://gvisor.dev/):Google 的用户空间内核,用 Go 编写。没有嵌套虚拟化(在另一个 VM 内运行的客户 VM,大多数云提供商默认禁用它;gVisor 不需要,因此它在 GKE 中开箱即用)的情况下提供强隔离。在系统调用密集型工作负载上付出约 10–30% 的开销。当硬件虚拟化不可用时,是一个坚实的中层选择。
  • WASM 沙箱([wasmtime](https://wasmtime.dev/)、[wasmer](https://wasmer.io/)):确定性、小、快,但生态系统较浅。WASI(WASM 的标准系统调用 API)正在成熟。目前还不能作为“运行这个任意 Python/Node 二进制文件”的即插即用目标。
Kyle Jeong - inline image

如果你正在为不受信任的通用代码构建:Firecracker(或 Cloud Hypervisor,一个类似的 VMM/virtio 设计)。如果你正在为已知的 JS 工作负载构建:V8 隔离区。其他一切都是对特定问题的专门答案。

更大的图景

Firecracker 采用了计算中最古老的想法之一,即虚拟机,并删除了足够多的部分使其变得廉价。它押注于硬件强制隔离是值得的,如果你能使其足够快的话。

这个赌注对于无服务器来说总是会成功。改变的是,“不受信任的多租户代码”工作负载已经从“我不想沙箱化的 Web 函数”增长为“生成可能触及生产环境的 Agent 生成任意命令”。边界移动了,对共享内核逃逸的容忍度从“可接受的风险”变成了“不可发布。”

而它确实做到了。它是一个 Rust 二进制文件,50,000 行代码,与 /dev/kvm 通信。

容器打包软件。微虚拟机隔离它。未来十年有趣的工程是你围绕盒子包裹的一切。

→ Kyle

这篇博客文章包含交互式组件和动画(在 X 文章上不显示。如果你想看那个版本,请访问:https://www.browserbase.com/blog/what-is-firecracker

更多可拆解样本

近期爆款文章

探索更多爆款文章

为创作者而生。

从全球 𝕏 爆款文章里发现选题,拆解它为什么能爆,再把可复用的内容结构变成你的下一篇创作灵感。