Warm pool 与 snapshot-fork

定义

Warm pool(预热池)是一组已经完成冷启动、处于空闲可领取状态的 MicroVM。调用方执行 run 时,若请求匹配池中的模板,产品层可以租出一台现成实例,而不必再走完整的内核启动与 rootfs 挂载。

snapshot-fork 是更进一步的加速:把一台已启动虚拟机的内存与设备状态做成写时复制快照,再从该快照分叉出多个子实例。子实例共享未改动的内存页,因此比各自冷启动更省时间和内存。Box 将 libkrun 内存 snapshot-fork 列为可选的 Linux x86_64/KVM 能力。

问题背景

MicroVM 的冷启动已经快于完整虚拟机,但仍包含:创建地址空间、进入客户机内核、运行 init、执行入口前的就绪探测。对频繁、短寿命的任务(评测、一次性工具、函数式工作负载),这段固定成本会占满整个生命周期。预热与快照把固定成本挪到「第一次」或「模板准备」阶段。

机制说明

池的对象

池不是「若干个 docker run 在后台空转」的松散集合。它需要:

  • 模板:镜像、资源、网络与隔离都已确定;
  • 空闲实例:已启动但未交给用户命令;
  • 租约:领取、归还、过期与销毁的记录;
  • 守护进程:在独立套接字上接受 pool run,并在信号到达时有界并发地排空。

Box 在 SIGTERM / SIGINT / pool stop 时排空空闲 VM 与租约;销毁失败则尽力回收孤儿,覆盖空闲、租约释放、一次性 pool run、补充中途与模板拆除。即使构建状态为 Failing 或 Unavailable,也会移除快照模板目录(~/.a3s/pool/tpl-*)。

snapshot-fork 的资格

写时复制快照依赖 hypervisor 与内核支持。不支持的主机必须在产生镜像、内存、box 或 rootfs 副作用之前拒绝显式请求。warm pool 在这种主机上只能冷启动补充,不得假装已经快照。设计文档见 docs/cow-snapshot-fork-design.mddocs/native-snapshot-fork-feasibility.md

为何 Sandbox 拒绝

共享内核路径没有客户机物理内存可供快照,也没有与 libkrun 模板对等的「空闲 VM」。若在 Sandbox 上接受 pool 或 snapshot-fork 参数,只能改写语义(例如预创建进程),从而破坏「同一标志同一含义」。Box 选择拒绝。

在 Box 中的位置

  • 实现:src/runtime/src/pool/
  • CLI:src/cli/src/commands/pool.rsrun 可通过 --pool 或环境变量中的池套接字走 execute_pool_run
  • a3s-box info 报告 warm pool daemon 是否在约定套接字上运行。

验证命令

a3s-box info
a3s-box pool --help

在未启动 pool daemon 的主机上,info 应报告 daemon 未运行。不要在未阅读 pool 子命令帮助与主机资格之前,把生产流量指向池套接字。

相关与易混

  • 相关:MicroVM快照、commit、diff 与 export
  • 易混:文件系统 snapshot(停止后的 ext4 / 目录检查点)与内存 snapshot-fork 不是同一操作。前者保存磁盘状态;后者复制运行中的虚拟机内存。warm pool 也不是 Kubernetes 的副本池:它只作用于本机 MicroVM。