Firecracker Actions API:深入解析 /actions 接口与 InstanceStart、FlushMetrics、SendCtrlAltDel 三种同步动作
本文基于 Firecracker 官方文档 actions.md 展开,系统讲解通过 PUT /actions 接口触发 microVM 同步动作(synchronous action)的完整用法:请求格式与字段定义、三种动作 InstanceStart / FlushMetrics / SendCtrlAltDel 的语义边界与适用阶段,并结合 swagger 定义、API 服务器解析代码与 VMM 内部实现,说明每种动作从 HTTP 请求到实际生效的底层调用链,帮助读者正确编排 microVM 的启动、指标刷新与干净关机流程。
Actions API 总览:PUT /actions 与 InstanceActionInfo
Firecracker 允许通过向 API 服务器的 /actions 资源发送 PUT 请求来触发同步动作。所有动作共用同一个端点和同一套请求体结构,动作类型由 JSON 请求体中的 action_type 字段区分。
在 swagger 定义中,/actions 的 put 操作定义为 createSyncAction,请求体引用 InstanceActionInfo schema:
InstanceActionInfo:
type: object
description:
Variant wrapper containing the real action.
required:
- action_type
properties:
action_type:
description: Enumeration indicating what type of action is contained in the payload
type: string
enum:
- FlushMetrics
- InstanceStart
- SendCtrlAltDel
关键要点:
action_type是必填字段,取值只能是FlushMetrics、InstanceStart、SendCtrlAltDel三者之一;- 请求成功时返回 204(无响应体),输入非法时返回 400 并附带
Error对象; - 三种动作都是“同步动作”:API 服务器收到请求后会与 VMM 主线程同步交互,请求返回即代表动作已被处理(或已被拒绝)。
请求的通用形态如下(${socket} 为 Firecracker API 的 Unix 套接字路径,如 /tmp/firecracker.socket):
curl --unix-socket ${socket} -i \
-X PUT "http://localhost/actions" \
-d '{ "action_type": "<ACTION_NAME>" }'
请求解析:从 JSON 到 VmmAction
API 服务器侧的解析逻辑位于 parse_put_actions。请求体被反序列化为带 deny_unknown_fields 约束的 ActionBody 结构,action_type 字符串与 ActionType 枚举的变体名严格对应(即字段值必须是精确的 FlushMetrics / InstanceStart / SendCtrlAltDel,多写字段或拼写错误都会直接报错):
#[derive(Debug, Deserialize, Serialize)]
enum ActionType {
FlushMetrics,
InstanceStart,
SendCtrlAltDel,
}
#[derive(Debug, Deserialize, Serialize)]
#[serde(deny_unknown_fields)]
struct ActionBody {
action_type: ActionType,
}
解析成功后,每个动作被映射为一条 VmmAction 并封装为同步请求(ParsedRequest::new_sync),跨线程发给 VMM 主循环处理:
| action_type | 映射的 VmmAction | 说明 |
|---|---|---|
FlushMetrics |
VmmAction::FlushMetrics |
立即写出指标 |
InstanceStart |
VmmAction::StartMicroVm |
启动 microVM |
SendCtrlAltDel |
VmmAction::SendCtrlAltDel |
仅 x86_64 支持 |
这里有两处值得注意的实现细节:
- 架构限制:在解析阶段,
SendCtrlAltDel在 aarch64 目标上直接被拒绝,返回 400 错误"SendCtrlAltDel does not supported on aarch64."。这与源码中 [#[cfg(target_arch = "x86_64")]条件编译一致——i8042/AT 键盘模拟是 x86_64 的 ISA 特性,ARM 架构上不存在对应硬件。 - 请求级指标:每次
PUT /actions都会递增put_api_requests.actions_count,反序列化失败时再递增actions_fails。这些计数本身可通过后文的FlushMetrics动作落盘观测。
InstanceStart:一次性点亮 microVM
InstanceStart 动作用于给 microVM 上电(power on)并启动 guest OS。它有两个硬性约束:
- 没有 payload:请求体中只需要
action_type字段; - 只能成功调用一次:它是 pre-boot 阶段的收尾动作,一旦执行成功,Firecracker 进程就从“配置阶段”转入“运行阶段”,此后该动作不再可用。
curl --unix-socket ${socket} -i \
-X PUT "http://localhost/actions" \
-d '{ "action_type": "InstanceStart" }'
底层实现:start_microvm 与 pre-boot 阶段终结
在 rpc_interface.rs 中,pre-boot 控制器对 StartMicroVm 的处理是:
// On success, this command will end the pre-boot stage and this controller
// will be replaced by a runtime controller.
fn start_microvm(&mut self) -> Result<VmmData, VmmActionError> {
build_and_boot_microvm(
&self.instance_info,
self.vm_resources,
self.event_manager,
self.seccomp_filters,
)
.map(|vmm| {
self.built_vmm = Some(vmm);
VmmData::Empty
})
.map_err(VmmActionError::StartMicrovm)
}
源码注释明确说明:该命令成功后会终结 pre-boot 阶段,pre-boot 控制器被运行时(runtime)控制器替换。这解释了“只能成功调用一次”的语义来源——第二次调用时,运行时控制器会把 StartMicroVm 归入不支持的操作组,请求将失败。
这一设计与 Firecracker 的启动流程完全对应:先通过其余 API 端点(boot-source、machine-config、drives、network-interfaces 等)完成配置,最后用 InstanceStart 一次性触发 build_and_boot_microvm 构建并启动 microVM。动作成功执行后,可通过 GET /(返回 InstanceInfo)观察到实例状态从 Not started 变为 Running(状态枚举定义见 swagger 中的 InstanceInfo.state)。
FlushMetrics:按需立即写出指标
FlushMetrics 动作用于在用户需要时立即把 Firecracker 内部累计的指标(metrics)写出。
curl --unix-socket /tmp/firecracker.socket -i \
-X PUT "http://localhost/actions" \
-d '{ "action_type": "FlushMetrics" }'
底层实现:METRICS 全局状态落盘
运行时控制器对该动作的处理非常直接(见 rpc_interface.rs):
/// Write the metrics on user demand (flush). We use the word `flush` here to highlight the fact
/// that the metrics will be written immediately.
fn flush_metrics(&mut self) -> Result<VmmData, VmmActionError> {
// FIXME: we're losing the bool saying whether metrics were actually written.
METRICS
.write()
.map(|_| VmmData::Empty)
.map_err(super::VmmError::Metrics)
.map_err(VmmActionError::InternalVmm)
}
即直接调用全局 METRICS 的 write(),把当前累计的计数器、直方图等指标立即序列化写入指标输出位置。源码中的注释也解释了命名意图:用 flush 强调“指标立即写出”,而非等待后台周期性刷新。
使用前提:该动作要求 metrics 已经配置(见 VmmAction 的文档注释:“This action can only be called after the logger has been configured”,metrics 通过 boot-args 或 /metrics 端点在 pre-boot 阶段配置)。指标体系本身的字段格式与含义,可参考 metrics 文档。
SendCtrlAltDel:模拟 Ctrl+Alt+Del 触发干净关机
SendCtrlAltDel 动作(仅 Intel 和 AMD 平台)向 microVM 注入 CTRL+ALT+DEL 按键序列。按照惯例,该序列用于触发软重启(soft reboot):大多数 Linux 发行版收到该键盘输入后会执行有序关机并重置系统。由于 Firecracker 在 CPU reset 时会退出进程,因此 SendCtrlAltDel 可以被用来触发 microVM 的干净(clean)关机——guest 内部完成正常的关机流程,而非宿主直接杀死进程。
curl --unix-socket /tmp/firecracker.socket -i \
-X PUT "http://localhost/actions" \
-d '{ "action_type": "SendCtrlAltDel" }'
设备模型:i8042 控制器 + 标准 AT 键盘
要理解这个动作为何有 guest 侧依赖,需要看它的实现链。VMM 主入口在 Vmm::send_ctrl_alt_del:
/// Injects CTRL+ALT+DEL keystroke combo in the i8042 device.
#[cfg(target_arch = "x86_64")]
pub fn send_ctrl_alt_del(&mut self) -> Result<(), VmmError> {
self.device_manager
.legacy_devices
.as_ref()
.ok_or(VmmError::NotSupported)
.i8042
.lock()
.expect("i8042 lock was poisoned")
.trigger_ctrl_alt_del()
.map_err(VmmError::I8042Error)
}
可以看到:
- 该函数带有
#[cfg(target_arch = "x86_64")],印证了文档中“Intel and AMD only”的平台限定; - 它通过设备管理器访问 legacy 设备组中的 i8042 设备,最终调用 i8042 模拟的
trigger_ctrl_alt_del()。
也就是说,Firecracker 在此动作中模拟的是一套“经由 i8042 控制器连接的标准 AT 键盘”。因此 guest OS 必须同时具备这两个设备的驱动支持:对 Linux 而言,guest 内核需要开启:
CONFIG_SERIO_I8042
CONFIG_KEYBOARD_ATKBD
若 guest 内核缺少这些配置,注入的按键序列不会被 guest 解释,动作虽能执行(API 返回 204)却不会引起 guest 关机。i8042 设备模型(包括键盘端口读写、状态/命令字节、键盘中断 kbd_interrupt_evt 等)及其单元测试见 i8042.rs,其中 test_i8042_kbd 等测试覆盖了 trigger_ctrl_alt_del() 的成功路径与键盘中断被 guest 禁用时的失败路径。
加速 guest 内核探测 i8042 的启动参数
官方文档给出了一条性能提示:Linux 的 i8042 驱动在开机时会花费数十毫秒探测设备,可通过以下内核命令行参数关闭多余探测:
i8042.noaux i8042.nomux i8042.nopnp i8042.dumbkbd
这些参数可通过 Firecracker 启动时的 --boot-args(或 pre-boot 阶段的 boot-source 配置)传入 guest 内核。对于需要频繁冷启动的 serverless 场景,省下这段探测时间是可观的。
阶段限制:只能在运行时调用
从 rpc_interface.rs 的 pre-boot 控制器匹配分支可以看出,SendCtrlAltDel 在 pre-boot 阶段会直接返回 OperationNotSupportedPreBoot 错误——microVM 尚未上电时,i8042 设备尚无意义。该动作的有效窗口是 microVM 已启动(Running)之后。
三种动作的边界与适用阶段速查
| 动作 | 请求 payload | 适用架构 | 适用阶段 | 是否可重复 | 典型用途 |
|---|---|---|---|---|---|
InstanceStart |
无 | x86_64 / aarch64 | 仅 pre-boot(配置完成后) | 否,成功仅一次 | 上电启动 microVM |
FlushMetrics |
无 | x86_64 / aarch64 | pre-boot / 运行时(metrics 已配置后) | 是 | 立即写出指标 |
SendCtrlAltDel |
无 | 仅 x86_64 | 仅运行时 | 是(每次触发一次按键序列) | 触发 guest 干净关机 |
实操中的几个常见要点:
- 配置顺序:所有设备与机器配置必须在
InstanceStart之前完成;InstanceStart成功意味着 pre-boot 阶段结束,此后再配置 boot-source 等资源会失败。 - 架构自检:如果部署环境包含 aarch64 节点,自动化脚本在发送
SendCtrlAltDel前应先判断架构,否则会收到 400 错误。 - 干净关机链路:
SendCtrlAltDel生效的完整链路是 i8042 模拟 → guest 内 AT 键盘驱动(需CONFIG_SERIO_I8042+CONFIG_KEYBOARD_ATKBD)→ guest 执行 orderly shutdown → CPU reset → Firecracker 进程退出。任何一环缺失(如 guest 内核缺驱动),都不会产生预期效果。 - 可观测性:
PUT /actions的调用与失败计数(actions_count/actions_fails)本身就是 metrics 的一部分,可通过FlushMetrics落盘后验证接口调用情况。
进一步阅读
- actions 官方文档:本文的主体来源;
- swagger 定义:所有 API 端点与 schema 的权威定义,
InstanceActionInfo、InstanceInfo等字段均可在此查证; - API 请求解析:
action_type到VmmAction的映射、未知字段拒绝与 aarch64 限制的实现; - RPC 接口:pre-boot / runtime 两个控制器对
VmmAction的分发逻辑与阶段约束; - Vmm 主体 与 i8042 设备:
send_ctrl_alt_del的底层设备模型; - getting-started:从零构建 kernel/rootfs 并启动 microVM 的完整流程,
InstanceStart是其中的收尾一步; - metrics 文档:
FlushMetrics所刷新的指标体系说明。
atomcodeClaude Code 的开源替代方案。连接任意大模型,编辑代码,运行命令,自动验证 — 全自动执行。用 Rust 构建,极致性能。 | An open-source alternative to Claude Code. Connect any LLM, edit code, run commands, and verify changes — autonomously. Built in Rust for speed. Get StartedRust0623
Hy4-previewHy4 preview 是由腾讯混元团队研发的新一代混合专家(MoE)旗舰模型。模型总参数量 770B,每个 token 激活 49B,主干共包含78层,第一层采用标准 FFN,其余 77 层均为 MoE 结构,每层包含 256 个路由专家与 1 个共享专家,每个 token 激活 top-8 路由专家及共享专家。主干之外原生内置 1 层 MTP(总参数量 10B,激活 0.7B)以支持投机解码。Python00
GLM-5.3GLM-5.3 与 GLM-5.2 使用相同的基座模型——所有提升均来自后训练。与 GLM-5.2 相比,它在复杂编程和长程任务上的表现显著提升。Jinja00
GLM-5.3-FlashGLM-5.3-Flash (320B-A18B),是GLM-5系列的首个原生多模态模型。320B总参数,能力超过GLM-5.2Jinja00
Spark-X2.5-4BSpark-X2.5-4B 旨在让强大的 AI 更实用、更高效、更易获得。在广泛日常任务中表现强劲,涵盖对话、写作、翻译、推理、编码、工具调用以及智能体工作流,并在同等规模的开源模型中取得领先成绩。Spark-X2.5 将面向效率的架构与最高 1M tokens 的原生上下文窗口相结合,并支持 200 多种语言。Python00
Spark-X2.5-1.7BSpark-X2.5-1.7B 旨在让强大的 AI 更加实用、高效且易于获取。这些模型在广泛的日常任务中表现出色,涵盖对话、写作、翻译、推理、编程、工具调用和智能体工作流,并在同等规模的开源模型中取得领先结果。Spark-X2.5 将面向效率的架构与最高 1M tokens 的原生上下文窗口相结合,并支持 200 多种语言。Python00