Firecracker 虚拟化概述
Source: Dev.to
Firecracker 是由 Amazon Web Services (AWS) 创建的开源虚拟化技术,支撑其 AWS Lambda Functions as a Service (FaaS) 无服务器产品。
Firecracker 于 2018 年开源 [0],使任何人都可以在自己的项目和使用场景中使用这套极其快速且可靠的系统。
该生态系统出奇地灵活:虽然它为 AWS Lambda 提供动力,但其设计并不局限于这种高度受控的环境。它可以从 AWS 规模的工作负载一直延伸到运行单个 VM 的家庭实验室。
Firecracker 高层概览
有许多优秀的快速入门文档 [1] 和博客描述如何安装并启动单个 Firecracker MicroVM 实例,因此基本需求非常简单:
- Firecracker 二进制文件
- 内核镜像
- 根文件系统(rootfs)
- 网络配置(可选)
当你通过执行 firecracker 程序启动一个 Firecracker VM 时,你会运行一个可以通过你启动的 Firecracker 进程进行管理的单实例 VM。管理命令通过 Unix 套接字上的 HTTP API 发送。当 VM 不再需要时,应优雅地停止它。
多个 Firecracker 进程可以并发运行,这相当于运行多个 VM——这大概就是 AWS 运行数百万 Lambda 函数的方式。
配置
VM 可以通过两种主要方式进行配置:
即使配置文件已经设置了 guest kernel 和 rootfs,仍然可以通过套接字发送额外的 API 请求。这种双重方式体现了系统的灵活性。
HTTP API 由官方 Go SDK [4] 包装,可用于以编程方式管理 Firecracker 实例。AWS 可能在内部使用该 SDK 通过同一 API 来配置和控制 Lambda 函数。
初始化
Firecracker 可以通过多种机制进行初始化:
- 直接命令行执行
- Systemd 单元文件
jailer工具(见下文)
前两者是常见的 Linux 方式;第三者为多租户场景提供了额外的隔离。
使用 Jailer 增强隔离
jailer 工具 [5] 将每个 Firecracker 进程隔离在其自己的 chroot 监狱目录中。这为多租户环境提供了一层安全保障。对于运行受信任代码的家庭实验室,使用 jailer 是可选的。
演示
下面是一个最小的 Bash 脚本,使用预先下载的内核和 rootfs 启动 Firecracker 微型 VM。
#!/usr/bin/env bash
firecracker="/usr/bin/firecracker"
uuid=$(/usr/bin/uuidgen)
# Start Firecracker in the background, exposing a Unix socket
nohup "$firecracker" --api-sock "/tmp/$uuid.socket" &
echo "created firecracker process running on socket: /tmp/$uuid.socket"
# Configure the kernel
curl --unix-socket "/tmp/$uuid.socket" -i \
-X PUT 'http://localhost/boot-source' \
-H 'Accept: application/json' \
-H 'Content-Type: application/json' \
-d '{
"kernel_image_path": "/tmp/firecracker-test/hello-vmlinux.bin",
"boot_args": "console=ttyS0 reboot=k panic=1 pci=off"
}'
# Attach the root filesystem
curl --unix-socket "/tmp/$uuid.socket" -i \
-X PUT 'http://localhost/drives/rootfs' \
-H 'Accept: application/json' \
-H 'Content-Type: application/json' \
-d '{
"drive_id": "rootfs",
"path_on_host": "/tmp/firecracker-test/hello-rootfs.ext4",
"is_root_device": true,
"is_read_only": false
}'
# Start the VM instance
curl --unix-socket "/tmp/$uuid.socket" -i \
-X PUT 'http://localhost/actions' \
-H 'Accept: application/json' \
-H 'Content-Type: application/json' \
-d '{
"action_type": "InstanceStart"
}'
echo "Started VM instance."
运行脚本后会产生类似以下的输出:
created firecracker process running on socket: /tmp/b214c708-e506-455b-a98d-647939a0ef0d.socket
nohup: appending output to 'nohup.out'
HTTP/1.1 204
Server: Firecracker API
Connection: keep-alive
HTTP/1.1 204
Server: Firecracker API
Connection: keep-alive
HTTP/1.1 204
Server: Firecracker API
Connection: keep-alive
Started VM instance.
随后 nohup.out 文件会显示 VM 正在启动:
[ ok ]
* Mounting persistent storage (pstore) filesystem ...
[ ok ]
Starting default runlevel
[ 1.088111] clocksource: tsc: mask: 0xffffffffffffffff max_cycles: 0x2879b124109, max_idle_ns: 440795245440 ns
Welcome to Alpine Linux 3.8
Kernel 4.14.55-84.37.amzn2.x86_64 on an x86_64 (ttyS0)
localhost login:
VM 已经启动并出现登录提示(本示例未配置网络或 SSH 密钥)。该脚本演示了使用 HTTP API 和 Unix 套接字启动 Firecracker 微型 VM 的简便性。
与 Lambda 相比的 Firecracker 生态系统差异
AWS re:Invent 演讲(例如 Julian Wood 2022 年的 A closer look at AWS Lambda (SVS404‑R) [video])将 Lambda 数据平面描述为一组处理同步和异步调用的服务。
同步服务
- Frontend Invoke Service
- Counting Service
- Assignment Service
- Worker Hosts
- Placement Service
异步服务
- Poller Fleet
- Queue Manager
- State Manager
- Stream Tracker
- Leasing Service
这些管理服务协同调度数百万甚至数十亿次 Lambda 调用。它们并不属于开源的 Firecracker 项目,后者仅专注于轻量级虚拟化层。因此,虽然 Firecracker 提供了底层的 VM 运行时,围绕 Lambda 的特定控制平面仍然是 AWS 的专有技术。