AWS Firecracker 论文导读:AWS 为什么用 microVM 支撑 Serverless

AWS Firecracker 论文导读:AWS 为什么用 microVM 支撑 Serverless

Firecracker 是 AWS 开源的 Virtual Machine Monitor,用于运行轻量级 microVM。它最常被提到的原因,是 AWS Lambda 底层使用了这项技术:AWS 需要快速启动隔离的执行环境,在大型主机上承载大量租户,同时保留用户对虚拟机隔离边界的安全预期。

AWS 在 2018 年 Firecracker 发布文章中,也曾描述 Fargate Tasks 会运行在 Firecracker microVMs 上。不过这句话需要平衡看待:Fargate 是托管的 container compute service,Firecracker 并不是 Fargate 对用户暴露、可依赖的产品接口或契约。本文提到 Fargate 时,会把它视为 AWS 官方曾公开说明 Firecracker 影响 serverless container runtime layer 的例子,而不是主张“每一种 Fargate 模式或平台细节都等同于每个 container 一个 Firecracker microVM”。

Firecracker 论文有意思的地方,不是简单地说“容器很快”或“虚拟机更安全”。它真正的设计取舍更务实:保留硬件虚拟化带来的强隔离,移除通用 VMM 中 serverless worker 不需要的设备和平台复杂度,并在 Linux 已经有成熟机制的地方直接复用。

本文是我对于 Firecracker 论文的理解。原始论文本身不难读,但它同时涉及 hypervisor、KVM、Linux isolation primitives、Lambda worker 架构和性能取舍;如果只是按照论文顺序看,很容易知道每个组件做什么,却不一定看出 AWS 为什么要做这样的工程选择。

Firecracker overview

Firecracker 要解决什么问题

Serverless 平台需要同时满足几个不容易兼得的条件:

  • 隔离性:不同客户之间不能只依赖薄弱的安全边界。
  • 高密度:单个 host 应该能够运行上千个执行环境。
  • 低额外开销:每个环境空闲时不应消耗太多内存或 CPU。
  • 快速启动:cold start 必须足够低,才能支撑交互式 workload。
  • 兼容性:客户应该能够运行普通 Linux binary 和 library。
  • 运维简单:平台团队要能使用熟悉的 Linux 工具观测、限制和管理资源。

Linux container 轻量、启动快,但它共享 host kernel。传统 VM 的隔离更强,但像 QEMU 这类通用虚拟化 stack 会带来大量设备模型、更大的 emulation surface,以及 serverless worker 不一定需要的额外负担。

Firecracker 选择的是中间路线:每个 workload 运行在 KVM 支撑的 microVM 中,而 VMM 只支持 serverless 和 container workload 真正需要的一小组设备与操作。

我读完后的理解是:Firecracker 并不是要证明 VM 或 container 哪一边绝对更好,而是 AWS 在 serverless 这个使用场景里“不想二选一”。它想要接近 container 的密度和启动速度,也想要 VM 更清晰的安全边界;Firecracker 的价值就在于把问题范围缩到足够小,让这两件事可以同时成立。

基本术语

在看 Firecracker 前,先把几个经常混用的术语拆开。

Hypervisor

Hypervisor 提供虚拟化层,让多个 guest operating systems 可以运行在同一台物理机器上。Type 1 hypervisor 直接运行在硬件上,或位于非常接近硬件的 privileged 位置;Type 2 hypervisor 则运行在普通 host operating system 之上。

Hypervisor types

KVM 让 Linux kernel 成为 hypervisor,并把硬件虚拟化能力暴露给 user-space VMM 使用。

VMM

Virtual Machine Monitor 负责创建和管理 VM。它会配置 vCPU、guest memory、虚拟设备、block device、networking 和生命周期。在 Firecracker 架构中,KVM 提供硬件虚拟化能力,而 Firecracker 是控制 microVM 的 VMM。

QEMU

QEMU 是功能完整的通用 emulator 和 VMM。它的优势是兼容性很广:支持多种架构、多种设备和多种使用场景。但这种灵活性也意味着更大的 codebase 和攻击面,对范围明确的 serverless worker 来说不一定划算。

crosvm

Firecracker 最早衍生自 Google 的 crosvmcrosvm 和 Firecracker 类似,重点放在 KVM 与 paravirtualized devices,而不是模拟大量物理硬件。

cgroups 与 seccomp

Firecracker 也依赖 Linux 本身的隔离机制:

  • cgroups:限制并统计 CPU、memory、I/O 使用量。
  • seccomp-bpf:限制 process 可以执行哪些 system calls。
  • namespaces:隔离 process、mount、network 等视图。
  • chroot:限制 jailed process 可见的 filesystem 范围。

这一点很重要,因为 Firecracker 没有试图重做整套操作系统控制平面。Linux 已经有合适 primitive 的地方,它就直接复用。

为什么不能只用 Container

早期 AWS Lambda 使用 Linux containers 隔离 functions,并在 customer accounts 之间加入额外的 virtualization。Container 让 Lambda 拥有很好的启动速度,但也意味着多个 workload 依赖共享 kernel 这条边界。

Lambda isolation model comparison

对 multi-tenant cloud service 来说,理想模型需要更强:让每个客户 workload 接近普通 Linux 环境,但用 VM 边界隔离。Firecracker 被打造出来,就是因为 AWS 不想在 container density 和 VM isolation 之间二选一。

Firecracker 架构

Firecracker 是一个主要用 Rust 编写的小型 VMM。它使用 KVM 做 CPU 与 memory virtualization,提供精简的 device model,并移除 serverless workload 不需要的大量硬件 emulation。

Firecracker layers

它支持的 virtual devices 被刻意控制在很小的范围。Firecracker 重点放在 virtio-based block 与 network devices,以及少量辅助设备,例如 serial console。它不包含 QEMU 那类广泛的 USB、音频、图形或 legacy devices emulation。

Firecracker design

结果是更小的 codebase、更小的 attack surface,以及可以通过 Unix socket 上的 HTTP API 控制的 VMM。

资源控制

Firecracker 针对 virtual devices 提供 rate limiter。平台可以限制每个 microVM 的 disk I/O、network bandwidth 与 operation rate。例如 network interface 可以配置 receive bandwidth 和 packet-rate limit:

PATCH /network-interfaces/iface_1 HTTP/1.1
Host: localhost
Content-Type: application/json
Accept: application/json

{
  "iface_id": "iface_1",
  "rx_rate_limiter": {
    "bandwidth": {
      "size": 1048576,
      "refill_time": 1000
    },
    "ops": {
      "size": 2000,
      "refill_time": 1000
    }
  }
}

这对 serverless 平台很关键,因为 guest operating system 由客户控制。host 必须能够从 guest 外部强制执行限制。

安全模型

Firecracker 结合了多层防护:

  • 通过 KVM-backed VM isolation 隔离 guest 与 host。
  • 使用最小化 device model,减少暴露的 emulation code。
  • VMM 使用 Rust,降低 memory-safety 类型风险。
  • 使用 cgroups 做 host-side resource control。
  • 使用 seccomp-bpf 限制 VMM process 的 syscall surface。
  • 使用 jailer process 把 Firecracker 放入受限 Linux sandbox。

Firecracker jailer

jailer 会配置受限的 filesystem view、namespaces、dropped capabilities、cgroups 和 seccomp filters。论文也提到 host-level hardening,例如在敏感部署中关闭 SMT,以及启用 CPU vulnerability mitigations。

重点是 Firecracker 的安全设计是分层的。VM 边界是核心,但 VMM process 本身仍然被视为需要 sandbox 的组件。

这里有一个阅读论文时需要注意的细节:论文提到的 seccomp syscall 数量反映的是当时版本的状态。后续 Firecracker 版本的 default seccomp filters 已经有更多 syscall 和 ioctl 规则,因此更适合把论文中的数字当成设计方向,而不是今天部署时一定相同的固定值。真正重要的是 Firecracker 通过 allowlist 思路限制 VMM process 能做的事。

Firecracker 与 AWS Lambda 的关系

从高层来看,Lambda 通过 frontend service 接收 invocation,把 function 放置到 worker,然后把 request 路由到被选中的执行环境。

Lambda invoke flow

placement system 会尽量复用 warm execution environments,因为即使 microVM 启动已经很快,遇到突发扩展时仍可能被用户感知到。

Lambda event path

在 Lambda worker 上,Firecracker 会管理多个 microVM。每个 slot 包含客户 runtime、function code,以及支持控制流程的 process。

Lambda worker architecture

这个模型让 AWS 可以在同一台物理 worker 上运行大量隔离的客户环境,同时把运维控制保留在 guest 外部。

论文里另一段我觉得很有意思的是迁移经验。AWS 从 2018 年开始把 Lambda 从第一代隔离模型,也就是每个 function 使用 container、每个客户使用 EC2 instance 的设计,逐步迁移到 EC2 bare metal instances 上的 Firecracker,过程中没有造成可用性、延迟或其他主要指标上的明显问题。但这种底层变更仍然会暴露一些平时不容易遇到的行为差异,例如出于安全考虑关闭 SMT 后改变了部分程序的 timing behavior,进而暴露 AWS 自家 SDK 与 Apache Commons HttpClient 的小 bug,最后需要通过修补依赖库解决。

这个案例对我来说比单纯的 benchmark 更有启发:大规模平台迁移不只是让新架构跑起来,还要能处理那些只在真实客户 workload、真实依赖版本和真实硬件设置下才会浮现的边界场景。

I/O Path

当 microVM 中的程序要写入 block device 或发送 network traffic,guest 会使用 virtio driver。request 会被放入 shared memory queue,Firecracker 收到通知后,由 VMM 执行 host-side operation。

这种设计避免了完整 device emulation,但它也不是 direct device access。这个取舍可以从 performance 结果中看出来。

Performance Evaluation

论文使用 EC2 m5d.metal host 进行评估,硬件包含 Intel Xeon Platinum 8175M CPU、384 GiB RAM、本地 NVMe storage,操作系统为 Ubuntu 18.04,Linux kernel 版本为 4.15.0-1044-aws。比较对象包含 QEMU、Intel Cloud Hypervisor 等 VMM。

Firecracker boot time

在测试配置下,Firecracker 与 Cloud Hypervisor 的启动速度明显优于 QEMU。加入 networking 会增加启动时间,但 Firecracker 的设计目标仍然是快速创建 microVM。

Firecracker memory overhead

Memory overhead 是最明显的优势之一:论文中的 Firecracker 每个 microVM VMM process 只需要几 MiB memory,远低于同组测试里的 QEMU。

Firecracker block I/O performance

Block I/O 与 network throughput 则呈现另一个取舍。Firecracker 不是为了暴露接近 bare-metal PCI device 的性能;它选择了足以支撑 Lambda 类型 serverless isolation,以及类似 managed runtime 目标的最小 virtio device model,并优先保留密度与隔离性。

Firecracker network throughput

对 serverless 平台来说,这个取舍是合理的。大多数 Lambda functions 不需要 host-level 的 raw network 或 disk throughput,但它们需要强隔离、可预期的限制,以及低启动负担。

所以我不会把 Firecracker 的 evaluation 解读成“全面比 QEMU 快”。更准确地说,它是在 AWS serverless compute infrastructure 需要的维度上做优化:启动时间、memory overhead、隔离性、density 和可控的资源限制。至于需要极致 I/O throughput 的 workload,这套设计本来就不是为了取代所有 VM 或 bare-metal 场景。

重点总结

Firecracker 不是要取代所有 virtualization stack。它的优势来自于收窄问题范围:

  • 使用 KVM 提供硬件虚拟化隔离边界。
  • 让 VMM 小而专注。
  • 避免不必要的 device emulation。
  • 复用 Linux cgroups、namespaces、seccomp 与运维工具。
  • 针对 serverless 与 container workload 最在意的密度和隔离性优化。

这也是 Firecracker 成为 AWS 重要基础设施的原因。它让 AWS 获得一个务实的 multi-tenant compute foundation:密度和启动行为接近 container,隔离性则更接近 VM。对 Lambda 来说,Firecracker 的关系在公开架构讨论中相对直接且核心;对 Fargate 来说,我会更保守地描述为 AWS 曾公开把 Firecracker 与 Fargate task runtime layer 关联起来,但用户不应把 Firecracker 当成 Fargate 的产品接口,也不应把它视为所有 Fargate 实现细节都固定不变的假设。

延伸阅读

Eason Cao
Eason Cao Eason is an engineer working at FANNG and living in Europe. He was accredited as AWS Professional Solution Architect, AWS Professional DevOps Engineer and CNCF Certified Kubernetes Administrator. He started his Kubernetes journey in 2017 and enjoys solving real-world business problems.
comments powered by Disqus