犀牛鸟 2026 研究笔记 estelledc.github.io

第四章 · Firecracker——微虚拟化的「Linux 内核」

这章为谁设计

你想理解「所有基于 KVM 的沙箱项目的底层是什么」。Firecracker 是 CubeSandbox 和 E2B 的发动机——先理解发动机,后面理解整车才不会迷路。


一句话定位

AWS 开源的 microVM 引擎,AWS Lambda 和 Fargate 的隐形心脏。它回答的问题是:「怎么用最少的资源、最小的攻击面,给代码造一个硬件级隔离的牢笼?」


日常类比

传统虚拟机(QEMU)像一套五星级酒店房间——有大床、浴缸、冰箱、电视、保险柜、迷你吧。Firecracker 像一间太空舱旅馆——只有一张床和一盏灯。但门锁一样结实(KVM 硬件隔离),入住速度快十倍(因为不用等服务员介绍设施)。

类比边界:太空舱旅馆的「只有床和灯」不是偷工减料——是刻意设计。每少一个设施,就少一个坏掉的可能、少一个被黑客利用的入口。


核心设计哲学:极端精简

传统 VM(QEMU)模拟一台完整的电脑——有 BIOS、USB 控制器、PCI 桥、声卡、显卡、键盘控制器……Firecracker 把这些全砍了,只留 4 个设备:

就这四个。没有声卡(VM 不需要放音乐)、没有 USB(VM 不需要插 U 盘)、没有显卡(VM 不需要显示画面)。

这个设计在安全上极其聪明:每砍掉一个虚拟设备,攻击面就缩小一块。Firecracker 的攻击面只有几万行 Rust 代码,而 QEMU 是几十万行 C 代码。代码越少,bug 越少,被黑客利用的可能越小。

这个设计在性能上也极其聪明:不模拟的设备不占启动时间。所以 Firecracker 能做到 <5MB 内存和 ~125ms 启动——不是因为用了什么黑魔法,而是因为它什么 Extra 都没带。


Firecracker 的技术架构

VMM 进程启动流程

Firecracker 是一个单体 Rust 二进制。启动时做这些事:

main() 启动
  → 设置崩溃处理器(panic handler)
  → 注册信号处理器(优雅关机)
  → 解析命令行参数(API socket 路径、实例 ID)
  → 二选一:
     ① 有 REST API → 创建 API Server 线程 + VMM 线程
     ② 无 API → 直接启动 VM
  → 进入事件循环(epoll 驱动)

epoll:Linux 内核提供的高效事件通知机制。类比:与其每秒去 100 个信箱检查有没有新信(轮询),不如让邮局在有新信时主动通知你(事件驱动)。

MicroVM 创建过程

当 API 收到「创建 VM」的请求时,按以下步骤执行:

  1. KVM 初始化:跟 Linux 内核申请一个 KVM 虚拟机实例
  2. vCPU 创建:给 VM 分配虚拟 CPU(每个 vCPU 是一个独立线程)
  3. 内存分配:给 VM 分配一块独立的物理内存区域
  4. 设备挂载:按固定顺序挂载 4 个 VirtIO 设备
  5. 加载内核:把 Linux 内核镜像加载到 VM 的内存中
  6. 启动:让 vCPU 开始执行内核代码

KVM(Kernel-based Virtual Machine):Linux 内核自带的虚拟化模块。它让 CPU 硬件直接执行 VM 里的指令,不需要软件翻译——所以性能接近原生。类比:不是让翻译官口译(软件模拟),而是让两个人直接面对面说话(硬件直通)。

vCPU(virtual CPU):虚拟 CPU。物理机有 8 个 CPU 核,可以分给 10 个 VM 各一个 vCPU——操作系统通过时间片切换让每个 vCPU 都能跑。

VirtIO:一种标准化的虚拟设备接口。类比:USB 是物理设备的标准接口(不管是鼠标还是键盘都用 USB),VirtIO 是虚拟设备的标准接口(不管是虚拟网卡还是虚拟磁盘都用 VirtIO)。

vCPU 事件循环

每个 vCPU 线程的核心逻辑是一个循环:

vCPU 线程启动
  → 加载安全过滤器(seccomp)
  → 进入「暂停」状态,等待信号
  → 收到「运行」信号后进入循环:
      调用 KVM_RUN(让 CPU 执行 VM 内的指令)
        → CPU 一直执行,直到遇到「退出事件」:
            ① VM 要读写设备(MMIO) → 路由到对应的虚拟设备处理
            ② VM 要关机/重启 → 发信号给 VMM
            ③ 外部中断(暂停/恢复) → 暂停 VM
        → 处理完退出事件后,再次 KVM_RUN
      循环直到 VM 停止

MMIO(Memory-Mapped I/O):设备操作通过特定内存地址进行。类比:你往某个信箱里塞一张纸条(写特定内存地址),信箱后面的人(虚拟设备)就知道你要它做什么了。

Jailer 安全机制:7 层防护

Firecracker 不只是一个 VM 引擎——它的 Jailer(牢笼看守)给 VMM 进程本身加了 7 层保护:

机制 作用
1 关闭所有多余文件描述符 防止 VMM 继承的文件被恶意利用
2 清除所有环境变量 防止密钥通过 env var 泄漏
3 路径验证 防止路径遍历攻击
4 Chroot Jail 把 VMM 锁在一个小目录里,看不到系统其他文件
5 Cgroup 资源限制 限制 CPU / 内存 / IO 使用量
6 网络命名空间隔离 VMM 只能看到自己的网络
7 权限降级 VMM 以非特权用户运行

这意味着:即使 VM 里的恶意代码攻破了 KVM 隔离(极低概率),攻击者面对的 VMM 进程本身也是被锁在笼子里的——再攻破一层才能碰到 host 系统。

vsock 通信模型

VM 内部的程序怎么和外部通信?Firecracker 用 vsock:

VM 内部程序(AF_VSOCK)
    ↕ 通过虚拟 socket
Firecracker VMM(VsockMuxer)
    ↕ 通过 Unix socket
主机上的程序(AF_UNIX)

vsock:一种让 VM 内部和主机通信的 socket 类型。类比:宾馆房间里的电话只能打前台(VM 只能通过 vsock 联系 VMM),不能直接打外面的号码。前台(VMM)决定是否帮你转接外部电话。

快照 / 恢复

Firecracker 支持两种快照:

类型 内容 大小 速度 用途
Full Snapshot 完整内存 + 所有状态 冷启动加速(预热好环境,直接恢复)
Diff Snapshot 仅修改过的内存页 增量备份、检查点

Dirty Bitmap:一个标记「哪些内存页被修改过」的位图。类比:考试时用荧光笔标记改过的答案,交卷时只提交标记的部分就行。


Firecracker 在生态中的角色

关键定位:它是「引擎供应商」,不是「产品」。

这些全留给上层项目去实现。E2B 在 Firecracker 之上加了 SDK + 云服务。CubeSandbox 在 Firecracker 同源技术之上加了快照 + 网络控制 + E2B 兼容 SDK。


一个容易被忽视的细节

Firecracker 的 OpenAPI 规范在 src/firecracker/swagger/firecracker.yaml 里。这意味着你可以用任何语言自动生成 API 客户端(Python、Go、TypeScript),然后通过 REST API 控制 VM 的创建、启动、停止、快照。API 设计极其干净,值得学习。


读完这章你应该能回答

  1. Firecracker 和 QEMU 的核心区别是什么?(精简设备模型 → 小攻击面 + 快启动)
  2. 为什么 Firecracker 的攻击面小?(Rust 语言 + 只有 4 个设备 + 几万行代码)
  3. Firecracker 不做什么?(不做 SDK、不做文件系统接口、不做代码执行 API)
  4. Jailer 的 7 层防护保护的是谁?(保护 host 不被 VM 逃逸后的攻击者伤害)

导读目录:README.md 上一章:第三章 · 隔离的五个层级:从「不设防」到「硬件防弹」 下一章:第五章 · CubeSandbox——为 AI Agent 而生的「最后一公里」