Firecracker 如何用 virtio-pmem 设备作为 rootfs 启动 microVM 并启用 DAX
Firecracker 如何用 virtio-pmem 设备作为 rootfs 启动 microVM 并启用 DAX【免费下载链接】firecrackerSecure and fast microVMs for serverless computing.项目地址: https://gitcode.com/GitHub_Trending/fi/firecracker本文的任务是用 Firecracker 的virtio-pmem设备代替 virtio-block 作为 root 设备启动 microVM并通过 DAX 让 guest 直接访问 backing file 对应的 host 内存页避免数据在 guest page cache 中产生一份拷贝。适用前提是 guest 内核编译时启用了virtio-pmem与DAX所需的配置项见 docs/pmem.md并且已按 docs/getting-started.md 准备好 Firecracker 二进制、内核镜像和 rootfs 文件系统镜像。virtio-pmem 与 DAX 的作用virtio-pmem是一种不需要 host 上存在物理 NVDIMM 的持久内存设备它在 host 侧由一个 mmap 的文件作 backing在 guest 物理内存中暴露为一个 regionguest 可以直接 load/store 访问 host 内存页无需 guest 驱动与 VMM 交互。从 guest 用户态看它呈现为/dev/pmem0、/dev/pmem1这样的普通块设备因此可以作为 rootfs 设备让 VM 从中启动。由于virtio-pmem完全驻留在内存中按文档的说法用它作块设备时不需要 guest page cache 参与读写这一行为通过内核的DAX特性开启。文档给出的两个入口挂载设备时使用 DAX给mount命令添加--optionsdax文档原文如此让根设备启用 DAX在内核启动参数boot args中追加rootflagsdax。注意DAX支持并非所有文件系统都具备具体支持情况需查内核 DAX 文档确认。准备条件guest 内核配置要使用virtio-pmemguest 内核必须编译进对应支持。docs/pmem.md 给出的完整配置清单# Needed for DAX on aarch64. Will be ignored on x86_64 CONFIG_ARM64_PMEMy CONFIG_DEVICE_MIGRATIONy CONFIG_ZONE_DEVICEy CONFIG_VIRTIO_PMEMy CONFIG_LIBNVDIMMy CONFIG_BLK_DEV_PMEMy CONFIG_ND_CLAIMy CONFIG_ND_BTTy CONFIG_BTTy CONFIG_ND_PFNy CONFIG_NVDIMM_PFNy CONFIG_NVDIMM_DAXy CONFIG_OF_PMEMy CONFIG_NVDIMM_KEYSy CONFIG_DAXy CONFIG_DEV_DAXy CONFIG_DEV_DAX_PMEMy CONFIG_DEV_DAX_KMEMy CONFIG_FS_DAXy CONFIG_FS_DAX_PMDy内核镜像的构建方式x86_64 出vmlinux、aarch64 出Image可参考 docs/rootfs-and-kernel-setup.md 的手动编译流程或用仓库自带的 recipe./tools/devtool build_ci_artifacts kernels支持的内核版本为5.10、5.10-no-acpi和6.1构建产物与对应 KConfig 存放在resources/$(uname -m)下。rootfs 镜像backing filevirtio-pmem的 backing file 就是承载根文件系统的镜像文件。rootfs 的两种获取方式手动构建ddmkfs.ext4建一个 ext4 镜像文件再用 Docker 容器把 Alpine/OpenRC 等内容拷入详见 docs/rootfs-and-kernel-setup.md使用提供的 recipe 生成 Ubuntu 22.04 精简 rootfs./tools/devtool build_ci_artifacts rootfs执行后得到ubuntu-22.04.ext4可直接用作 Firecracker 的 rootfs也可以直接沿用 docs/getting-started.md 中从 CI 下载内核与 rootfs 的脚本得到vmlinux-*与*.ext4文件。运行环境按 docs/getting-started.md 的要求系统需有 KVM 模块且当前用户对/dev/kvm有读写权限可用[ -r /dev/kvm ] [ -w /dev/kvm ] echo OK || echo FAIL检查也可以用firecracker/tools/devtool checkenv检查系统是否满足要求。执行步骤API 方式整个流程需要两个终端一个运行 Firecracker 进程一个发 API 请求。以下命令中的KERNEL指向内核镜像文件ROOTFS指向准备好的 rootfs 镜像文件即 pmem 的 backing file。1. 启动 FirecrackerAPI_SOCKET/tmp/firecracker.socket # Remove API unix socket sudo rm -f $API_SOCKET # Run firecracker sudo ./firecracker --api-sock ${API_SOCKET} --enable-pci--enable-pci让 Firecracker 使用 PCI VirtIO 传输文档建议启用以获得更高吞吐和更低延迟不传该参数则使用 legacy MMIO 传输。2. 配置 boot-source在 boot args 中追加rootflagsdaxDAX 是通过根设备启用而不是通过设备配置项开启的所以这一步的关键是把rootflagsdax加进boot_argsKERNEL./$(ls vmlinux* | tail -1) KERNEL_BOOT_ARGSconsolettyS0 rebootk panic1 rootflagsdax ARCH$(uname -m) if [ ${ARCH} aarch64 ]; then KERNEL_BOOT_ARGSkeep_bootcon ${KERNEL_BOOT_ARGS} fi sudo curl -X PUT --unix-socket ${API_SOCKET} \ --data { \kernel_image_path\: \${KERNEL}\, \boot_args\: \${KERNEL_BOOT_ARGS}\ } \ http://localhost/boot-source注意这里不再配置drivesroot 设备将由 pmem 提供root_device: true的 pmem 设备会在内核参数中被标记为rw若同时read_only: true则标记为ro。3. 配置 virtio-pmem 根设备ROOTFS./$(ls *.ext4 | tail -1) sudo curl --unix-socket $API_SOCKET -i \ -X PUT http://localhost/pmem/pmem0 \ -H Accept: application/json \ -H Content-Type: application/json \ -d { \id\: \pmem0\, \path_on_host\: \${ROOTFS}\, \root_device\: true, \read_only\: false }四个配置字段的含义见 docs/pmem.mdid设备内部标识这里同时也是 URL 路径的一部分path_on_hostbacking 文件在 host 上的路径root_device置true表示用该设备启动 VMread_onlytrue时 Firecracker 以只读模式 mmap backing 文件。设备在 guest 中按配置顺序命名先配置的拿到/dev/pmem0其后是/dev/pmem1等。4. 启动 microVM# API requests are handled asynchronously, it is important the configuration is # set, before InstanceStart. sleep 0.015s sudo curl -X PUT --unix-socket ${API_SOCKET} \ --data { \action_type\: \InstanceStart\ } \ http://localhost/actions验证结果进入 guest 后通过串口或 SSH网络配置沿用 docs/getting-started.md 的做法可以做两类检查这与仓库功能测试 tests/integration_tests/functional/test_pmem.py 中的校验方式一致确认设备节点存在ls /dev/pmem0确认根文件系统确实挂载在 pmem 设备上且为读写模式。mount输出中应出现类似下面的行文档示例字段值以你的实际文件系统类型为准/dev/pmem0 on / type ext4 (rw, ...)测试代码中对这一输出的判断是非只读时匹配/dev/pmem0 on / type ext4 (rw只读时匹配... (ro。如果这里看到的是 virtio-block 设备而不是/dev/pmem0说明root_device没有生效回到第 2、3 步检查请求是否都发生在InstanceStart之前。另外仓库的性能测试 tests/integration_tests/performance/test_pmem.py 展示了 DAX 生效的观察方式以带rootflagsdax的 boot args 从 pmem 启动后比较 guest 内的 buffer cache 用量与 host 侧 RSSDAX 启用时 pmem 路径的缓存占用应明显低于 virtio-block 路径。替代路径用 config file 一次配置不经过 API socket 也可以启动给 Firecracker 进程传--config-file指向一个包含全部 pre-boot 配置的 JSON 文件必须包含 guest kernel 与 rootfs 配置其余资源可选并会直接启动 microVM。pmem段是顶层数组例如sudo ./firecracker --api-sock /tmp/firecracker.socket --config-file /path/to/config.jsonpmem: [ { id: pmem0, path_on_host: ./some_file, root_device: true, read_only: false } ]字段名与 API 请求一致资源命名可参考 src/firecracker/swagger/firecracker.yaml完整结构示例见 tests/framework/vm_config.json。Pmem结构中id与path_on_host为必填字段。限制与注意事项2MB 对齐guest 暴露的内存 region 要求 2MB 对齐该要求传递到 backing 文件上。backing 文件可以是任意大小Firecracker 会用PRIVATE | ANONYMOUS空页填充到 2MB 边界这段内存间隙不会与 backing 文件同步read-only模式下则无此问题。只读模式的写行为guest 视角下virtio-pmem永远是可写的把设备设为read_only: true后任何写入尝试都会导致 VM 被关闭——x86_64 上 KVM 解码出的写指令会被丢弃并打印 warning 日志aarch64 上写指令触发 KVM 内部错误以ENOSYS形式返回使 Firecracker 停止 VM。只在确实需要保证底层文件绝不被写时才使用。DAX 文件系统支持DAX支持在所有文件系统上并不一致选用 rootfs 文件系统前需确认。安全文档不推荐多个 VM 共用同一个 backing file因为相同物理页会映射到不同 VM可能被利用为 side channel确有共享内存需求时按自身威胁模型评估。内存与性能virtio-pmem驻留 host 内存会使 VM 最大内存用量上升VM RAM 之外还能访问全部 pmem 内存文档强烈建议用 DAX 模式避免数据在 guest page cache 中重复。文档给出的示例数据128MB 内存的 VM 从virtio-pmem启动时无 DAX 的 RSS 约 120MB启用 DAX 后约 96MB接近用 virtio-block 启动的 VM。由于 backing 文件是MAP_SHARED映射页可能被 host 换出可用vmtouch等工具锁定首次访问每页会有 KVM page fault 开销文档建议用 huge pages开启 THP 的 tmpfs或内存共享场景用 hugetlbfs减少 page fault 次数。快照virtio-pmem支持快照恢复时 Firecracker 会尝试打开当初配置的同一 backing 文件因此恢复时该文件必须在与首次配置相同的位置。如果 guest 启动后无法登录或怀疑是 API 请求问题docs/getting-started.md 末尾给出了 API socket 的排查方法确认curl与 Firecracker 进程权限一致ss -a | grep /tmp/firecracker.socket确认 socket 已打开必要时用socat - UNIX-CONNECT:/tmp/firecracker.socket验证连通性。【免费下载链接】firecrackerSecure and fast microVMs for serverless computing.项目地址: https://gitcode.com/GitHub_Trending/fi/firecracker创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考