土法炼钢兴趣小组的算法知识备份

【从零造容器】microVM 实战:Firecracker API 启动与容器对比实测

文章导航

分类入口
containerslinuxvirtualization
标签入口
#firecracker#kvm#microvm#virtio#container-vs-vm#aws-lambda#gvisor#kata

源码下载

本文相关源码已整理,共 1 个文件。

打开下载目录 →

目录

上一篇 #10 讲了 microVM 为什么快、Firecracker 砍掉了什么。这篇动手做:下载 CI 内核与 rootfs、用 API 或 JSON 配置启动 microVM、在同一台机器上测启动时延,并与容器隔离模型对比。

测试环境说明 下文实测在 WSL2(Linux 6.6.87,KVM 可用)、Firecracker v1.8.0、guest 内核 vmlinux-6.1.172、Ubuntu 24.04 rootfs(Firecracker CI 构件)上完成。AWS .metal 上的绝对时延会更低(参见 #10 在 i3.metal 的数据);本文数值用于同机对比口径,不替代官方 SLA。


一、准备:二进制、内核、rootfs

1.1 检查 KVM

[ -r /dev/kvm ] && [ -w /dev/kvm ] && echo "KVM OK" || echo "KVM FAIL"
lsmod | grep kvm

Firecracker 依赖 /dev/kvm。WSL2 在较新版本上通常可用;裸金属或云 .metal 实例更稳定。

1.2 下载 Firecracker 与 CI 构件

与官方 Getting Started 一致,从 spec.ccfc.min 拉取最新日期前缀下的内核与 Ubuntu squashfs:

ARCH="$(uname -m)"
S3="https://s3.amazonaws.com/spec.ccfc.min"

CI_ARTIFACTS_PREFIX=$(curl -fsSL "$S3?list-type=2&prefix=firecracker-ci/&delimiter=/" \
    | grep -oP "(?<=<Prefix>)firecracker-ci/[0-9]{8}-[^/]+/(?=</Prefix>)" \
    | sort | tail -1)

latest_kernel_key=$(curl -fsSL "$S3?list-type=2&prefix=${CI_ARTIFACTS_PREFIX}${ARCH}/vmlinux-" \
    | grep -oP "(?<=<Key>)(${CI_ARTIFACTS_PREFIX}${ARCH}/vmlinux-[0-9]+\.[0-9]+\.[0-9]{1,3})(?=</Key>)" \
    | sort -V | tail -1)

wget "$S3/${latest_kernel_key}" -O vmlinux

latest_ubuntu_key=$(curl -fsSL "$S3?list-type=2&prefix=${CI_ARTIFACTS_PREFIX}${ARCH}/ubuntu-" \
    | grep -oP "(?<=<Key>)(${CI_ARTIFACTS_PREFIX}${ARCH}/ubuntu-[0-9]+\.[0-9]+\.squashfs)(?=</Key>)" \
    | sort -V | tail -1)

wget -O ubuntu.squashfs "$S3/$latest_ubuntu_key"

将 squashfs 转为 ext4(需 unsquashfsmkfs.ext4):

unsquashfs -f -d squashfs-root ubuntu.squashfs
truncate -s 512M ubuntu.ext4
mkfs.ext4 -d squashfs-root -F ubuntu.ext4

本文实测使用的内核路径:vmlinux(6.1.172),rootfs:ubuntu.ext4(512 MB)。


二、方式 A:config-file 一键启动

最小 vmconfig.json(路径按本机修改):

{
  "boot-source": {
    "kernel_image_path": "/tmp/fc-bench/vmlinux",
    "boot_args": "console=ttyS0 reboot=k panic=1 pci=off"
  },
  "drives": [
    {
      "drive_id": "rootfs",
      "path_on_host": "/tmp/fc-bench/ubuntu.ext4",
      "is_root_device": true,
      "is_read_only": false
    }
  ]
}

启动:

sudo rm -f /tmp/firecracker.socket
sudo firecracker --api-sock /tmp/firecracker.socket \
    --config-file /path/to/vmconfig.json

串口日志会打印 guest 内核启动过程。Guest 内执行 reboot 会优雅退出 Firecracker(未实现完整电源管理时的设计行为)。


三、方式 B:REST API 分步配置

适合集成到编排器:先起 VMM 进程,再通过 Unix socket 发 HTTP。

终端 1——启动 Firecracker(PCI virtio 可选,吞吐更好):

API_SOCKET="/tmp/firecracker.socket"
sudo rm -f "$API_SOCKET"
sudo firecracker --api-sock "$API_SOCKET" --enable-pci

终端 2——配置并启动(与官方文档一致,节选):

API_SOCKET="/tmp/firecracker.socket"
KERNEL="/path/to/vmlinux"
ROOTFS="/path/to/ubuntu.ext4"

sudo curl -sS -X PUT --unix-socket "$API_SOCKET" \
    --data '{"kernel_image_path":"'"$KERNEL"'","boot_args":"console=ttyS0 reboot=k panic=1 pci=off"}' \
    "http://localhost/boot-source"

sudo curl -sS -X PUT --unix-socket "$API_SOCKET" \
    --data '{"drive_id":"rootfs","path_on_host":"'"$ROOTFS"'","is_root_device":true,"is_read_only":false}' \
    "http://localhost/drives/rootfs"

sudo curl -sS -X PUT --unix-socket "$API_SOCKET" \
    --data '{"action_type":"InstanceStart"}' \
    "http://localhost/actions"

网络需额外配置 TAP(见官方 Getting Started 的 tap0 + 172.16.0.2 示例)。仅验证启动时可省略网卡。

API 形态定义见 Firecracker 源码中的 OpenAPI:src/firecracker/swagger/firecracker.yaml


四、启动时延实测

4.1 测量口径

两种常见口径不要混用:

口径 含义 #10 AWS 参考
A:VMM → guest init 可用 到 init/systemd 就绪、可执行业务 ~125 ms(i3.metal,精简内核)
B:VMM → 根文件系统挂载日志 串口出现 EXT4-fs ... mounted 更早截断,偏乐观

本文在 WSL2 上采用口径 B(串口出现 mounted filesystem),便于脚本自动化;与 #10 的 125 ms 不可直接对比

4.2 实测结果(3 次,中位数)

Firecracker config-file 启动 → ext4 挂载日志:
  run 1: 0.854 s
  run 2: 0.850 s
  run 3: 0.871 s
  中位数: ~0.86 s

WSL2 上 guest 单 vCPU、完整 Ubuntu 24.04 rootfs、无网络 TAP——比 AWS 精简镜像慢是预期行为。瓶颈仍在 guest 内核启动 + 根文件系统挂载,与 #10 的分析一致。

4.3 与「容器级」隔离的对比

unshare + user namespace 模拟最轻量的进程隔离(非完整 runc 路径):

for i in 1 2 3 4 5; do
  TIMEFORMAT=%R; time unshare -Ur --fork --map-root-user /bin/true
done

实测(WSL2,省略 --mount-proc 因权限限制):

unshare 冷启动(/bin/true):约 0.001–0.012 s(首次略高)
方案 本文 WSL2 实测 隔离边界
unshare / 轻量容器路径 ~1 ms 级 共享宿主内核
Firecracker microVM ~860 ms(至 ext4 mount 日志) 独立 guest 内核 + KVM
#10 Firecracker ~125 ms(至 init,AWS metal) 同上

结论不变:microVM 用硬件虚拟化换隔离,启动与内存底线高于容器,但在 Serverless / 多租户沙箱场景可接受。


五、隔离方案选型

场景                     推荐              原因
────────────────────────────────────────────────────────────
本地开发 / CI            容器 + seccomp    速度、工具链成熟
可信单租户生产           容器 + 加固       性价比最高
多租户执行不可信代码     Firecracker microVM  硬件级内核隔离
K8s 多租户需 VM 边界     Kata Containers   OCI 接口 + 每 Pod 一 VM
syscall 拦截型沙箱       gVisor            无需完整 guest,但兼容性受限
追求极简 VMM             Cloud Hypervisor  Rust VMM,与 Firecracker 同类
Agent / 代码沙箱 SaaS    Firecracker / E2B  与 Lambda 同技术栈

#10容器安全 对照:

Agent 沙箱场景可延伸阅读本站 LLM Agent 框架Serverless 挑战


六、常见问题

Q:curl API 返回 connection refused?
Firecracker 进程与 curl 须同一特权级(常需两边都 sudo);确认 ss -a | grep firecracker.socket

Q:guest 起不来?
检查 vmlinux 是否为未压缩 ELF;boot_argsconsole=ttyS0;rootfs 为 ext4 且 e2fsck -fn rootfs.ext4 通过。

Q:和 QEMU/KVM 虚拟机有何不同?
Firecracker 是 VMM,不是通用 PC 模拟器;设备仅 virtio-mmio(或 PCI virtio),见 #10 设备表。


参考资料


示例代码:examples/containers/13-microvm-firecracker-practice/setup_fc.sh

上一篇: 容器 vs microVM:Firecracker 凭什么 125ms 启动 下一篇: 容器网络性能真相 相关: runc 源码考古 · Serverless 与 Firecracker

同主题继续阅读

把当前热点继续串成多页阅读,而不是停在单篇消费。

2026-04-01 · containers / linux

从零造容器系列文章

用 C 和 Go 从零实现一个 OCI 兼容的迷你容器运行时,逐篇拆解 Linux 内核的隔离机制。不是讲 Docker 怎么用,而是理解容器到底是什么。


By .