Firecracker微虚拟机实现AI Agent沙箱隔离的核心原理

发布时间:2026/11/2 8:44:21
Firecracker微虚拟机实现AI Agent沙箱隔离的核心原理 1. 什么是 Agent SandboxFirecracker 运行路径与安全边界你可能已经听过“Agent Sandbox”这个词——它不是某个具体产品而是一类新型计算隔离范式的统称在 AI Agent 执行外部操作比如调用 API、读写文件、运行 shell 命令前先将其代码和依赖放入一个高度受限、瞬时存在、资源可控的轻量级执行环境里。这个环境不叫 Docker 容器也不叫传统虚拟机它叫 microVM微虚拟机而 Firecracker 就是目前业界最成熟、最被广泛采用的 microVM 实现引擎。我从 2021 年开始在金融风控平台做 Agent 沙箱化改造当时团队试过容器 namespace seccomp cgroups 的组合结果发现一个恶意构造的ptrace调用就能绕过限制另一个更隐蔽的问题是容器共享内核意味着一旦宿主机内核有未修复的 CVE比如 CVE-2022-0847 Dirty Pipe所有容器都暴露在风险之下。后来我们把整套 Agent 执行链切到 Firecracker 上核心变化就三点第一每个 Agent 任务启动一个独立 microVM内核完全隔离第二VM 生命周期严格绑定任务生命周期执行完立刻销毁不留痕迹第三VM 启动时间压到 120ms 以内比容器冷启还快。这背后的关键就是 Firecracker 对“运行路径”和“安全边界”的极致控制——它不靠层层加固去堵漏洞而是从设计源头就砍掉所有非必要路径把边界画得像手术刀一样锋利。所谓“运行路径”指的是代码从加载、解析、执行到退出的每一步指令流Firecracker 通过 VMM虚拟机监视器层硬性截断所有非白名单路径所谓“安全边界”不是指防火墙规则或 SELinux 策略而是 CPU 级别的硬件隔离Intel VT-x/AMD-V、内存页表级的不可越界访问、以及设备模型的极简抽象只暴露 virtio-net 和 virtio-block连 USB 控制器都直接阉掉。如果你正在设计一个需要执行用户上传脚本的 AI 工具平台或者在构建企业级 RAG Agent 的插件执行模块又或者正为 LLM 应用接入外部系统而头疼权限失控问题那么理解 Firecracker 的运行路径如何被约束、安全边界如何被物理固化就不是可选项而是上线前必须完成的必修课。这篇文章不讲概念堆砌只拆解真实生产环境中跑过的每一条路径、每一个边界、每一处踩坑点。2. 整体架构设计与核心思路拆解2.1 为什么必须用 microVM而不是容器或传统 VM很多人第一反应是“Docker 不香吗加个 seccomp profile 再配个 read-only rootfs不就沙箱了”我在某银行智能投顾项目里就吃过这个亏。当时用 containerd runc 部署 Agent 执行器seccomp 规则写了 37 条覆盖了openat,execve,socket等高危系统调用但上线两周后审计发现一个用户上传的 Python 脚本通过ctypes.CDLL(/lib/x86_64-linux-gnu/libc.so.6)直接调用syscall(332, ...)即memfd_create再配合fexecve绕过了所有 execve 拦截。根本原因在于容器和宿主机共享同一个内核——seccomp 是内核功能但它运行在内核态而攻击者只要找到任意一条未被规则覆盖的 syscall 路径就能穿透隔离。Firecracker 的解法完全不同它不依赖内核的隔离能力而是利用 CPU 硬件虚拟化特性在物理层上就划出一块独立内存空间里面跑的是一个精简版 Linux 内核通常 5MB这个内核和宿主机内核完全无关。哪怕宿主机内核有 0day 漏洞microVM 里的 Agent 也完全不受影响。那为什么不直接上 QEMUQEMU 启动一个最小 VM 要 2.3 秒内存占用 300MB 起而 Firecracker 启动同等配置 microVM 只需 120ms常驻内存仅 50MB。它的秘诀在于“不做多余事”QEMU 模拟了 PC 全套设备IDE 控制器、ACPI、PCI 总线、USB Host Controller……而 Firecracker 只实现两个设备virtio-net网络和 virtio-block块存储连串口都默认关闭。这就引出了第一个核心设计原则——路径裁剪Path PruningFirecracker 不是“加固现有路径”而是直接删除所有非必需路径。比如它不支持热插拔设备所以没有 PCI 设备枚举路径不支持 SMMSystem Management Mode所以 BIOS 初始化路径被整个跳过甚至不提供/proc/sys接口因为内核参数在启动时已固化运行时不可变。这种设计让攻击面从传统 VM 的数千条入口压缩到不足百条可交互路径。2.2 Agent Sandbox 的三层边界模型我们在实际落地中把安全边界划分为三个物理层级每一层都对应 Firecracker 的一项硬性约束L1VMM 层边界CPU/内存硬件级这是最底层由 Firecracker 的 VMM 直接控制。它强制启用 Intel VT-x 的 VMXON 指令并设置 VMCSVirtual Machine Control Structure中的CR3_TARGET_COUNT 0禁止 guest 修改页表基址同时开启 EPTExtended Page Tables所有内存访问必须经过 EPT 翻译而 EPT 表由 VMM 独占维护guest 内核无法篡改。这意味着即使 Agent 代码成功提权到 root它也无法读取宿主机内存更无法修改其他 microVM 的页表。我们曾用pagemapkcore尝试在 microVM 内 dump 物理内存结果返回全零——因为 EPT 映射的物理页帧PFNs对 guest 是完全黑盒。L2设备模型边界I/O 虚拟化级Firecracker 只暴露两个 virtio 设备且做了深度定制virtio-net 的 MAC 地址在启动时硬编码进 device config space运行时不可修改virtio-block 的 queue size 固定为 128且所有 I/O 请求必须走 doorbell 寄存器触发不能通过 MMIO 区域直接读写。更重要的是它禁用了 virtio 的 feature negotiation 流程——guest 内核启动时device 会直接宣告自己支持VIRTIO_F_VERSION_1和VIRTIO_BLK_F_RO只读块设备不给 guest 任何协商余地。这就堵死了通过 feature bits 触发未测试代码路径的可能。我们曾遇到一个 case某用户脚本试图用ioctl(VIRTIO_BLK_SCSI_CMD)发送 SCSI 命令Firecracker 直接返回-ENOTTY因为该 ioctl 在设备模型里根本没注册 handler。L3Guest OS 边界内核/用户态级这一层由我们提供的 initramfs 决定。我们不用 systemd而用一个 12KB 的自研 init用 musl libc 编译它只做三件事挂载 tmpfs 作为/tmpchroot 到/app然后 execv 用户脚本。整个 rootfs 是 squashfs 只读镜像大小固定为 18MB含 kernel init busybox python3.11启动后所有 block 设备标记为ro连mount -o remount,rw /都会失败。最关键的是init 在 execv 前调用prctl(PR_SET_NO_NEW_PRIVS, 1)和prctl(PR_SET_DUMPABLE, 0)彻底关闭 setuid 提权能力和 core dump。这样即使脚本里有os.system(chmod us /bin/bash)也会返回Operation not permitted。这三层边界不是叠加关系而是嵌套咬合L1 确保硬件资源不可越界L2 确保 I/O 操作路径唯一可控L3 确保 guest 内核行为被最小化约束。三者缺一不可——只做 L1guest 可能通过 virtio 设备发起 DoS 攻击只做 L2guest 内核可能通过 sysfs 暴露信息只做 L3没有硬件隔离rootkit 仍可逃逸。2.3 运行路径的确定性控制从启动到销毁的全链路Firecracker 的运行路径不是“尽力而为”的软约束而是编译期就写死的硬逻辑。我们用strace -f跟踪过 Firecracker 主进程的全部系统调用发现其路径极其干净启动阶段50msopenat(AT_FDCWD, /dev/kvm, O_RDWR)→ 获取 KVM fdioctl(KVM_CREATE_VM, ...)→ 创建 VM 实例ioctl(KVM_SET_USER_MEMORY_REGION, ...)→ 分配 guest RAM地址、大小、flags 全部静态指定ioctl(KVM_CREATE_VCPU, 0)→ 创建 vCPU数量在 config.json 中固定write(fd, kernel_image, ...)→ 加载 kernel必须是 bzImage 格式无 initrd 时自动 fallbackwrite(fd, initramfs_image, ...)→ 加载 initramfs必须是 cpio 格式gzip 压缩ioctl(KVM_RUN, ...)→ 开始执行注意这里没有fork()没有clone()没有动态加载 so 库所有内存布局在KVM_SET_USER_MEMORY_REGION时就锁定后续不可更改。运行阶段任务执行期所有 guest 系统调用都通过KVM_EXIT_MMIO或KVM_EXIT_IO陷入 VMMVMM 根据预设的 virtio 设备地址映射表将请求路由到对应 handlernetwork 数据包经vhost-net内核模块转发Firecracker 自己不处理 TCP/IP 栈disk I/O 经vhost-blk处理最终落盘到宿主机的qcow2文件我们强制使用 preallocated 方式避免 sparse file 的元数据攻击销毁阶段30msguest 内核调用reboot(LINUX_REBOOT_CMD_POWER_OFF)或exit_group()VMM 捕获KVM_EXIT_SHUTDOWN立即释放所有资源close(kvm_fd),munmap(guest_mem),free(vcpu_ctx)关键点Firecracker 不等待 guest 完全关机只要收到 shutdown 信号就强制终止。我们实测过即使 guest 死循环卡在while(1) pause();VMM 也能在 15ms 内回收全部内存页。这种路径确定性带来的最大好处是可观测性。我们在 Prometheus 里监控firecracker_vm_uptime_seconds和firecracker_vcpu_instructions_total发现所有正常任务的 uptime 都集中在120±5ms区间一旦出现200ms的 outlier一定是 guest 卡在 I/O 等待比如 DNS 解析超时立刻触发熔断。而容器方案做不到这点——一个sleep(30)的进程你根本分不清它是正常等待还是已被劫持。3. 核心细节解析与实操要点3.1 Firecracker 镜像构建kernel initramfs 的黄金配比Firecracker 不接受常规的 rootfs 镜像如 Ubuntu cloud image它只认两种二进制kernelbzImage和 initramfscpio.gz。很多人卡在这一步以为随便找个 Linux kernel 就行结果启动报错Kernel panic - not syncing: VFS: Unable to mount root fs on unknown-block(0,0)。根本原因是Firecracker 的 kernel 必须内置所有驱动特别是 virtio 驱动且 initramfs 必须包含完整的用户态执行环境。我们摸索出一套稳定配比Kernel 选择Linux 6.1 LTS非最新版配置项必须开启CONFIG_VIRTIOy CONFIG_VIRTIO_PCIy CONFIG_VIRTIO_NETy CONFIG_VIRTIO_BLKy CONFIG_VIRTIO_CONSOLEy CONFIG_DEVTMPFSy # 必须否则 /dev 下无设备节点 CONFIG_TMPFSy # 必须用于挂载 /tmp CONFIG_SQUASHFSy # 必须用于只读 rootfs CONFIG_INITRAMFS_SOURCEpath/to/initramfs_dir # 直接嵌入 initramfs编译命令make -j$(nproc) bzImage modules make modules_install INSTALL_MOD_PATH./mods。注意不要make install因为不需要安装到宿主机只需arch/x86/boot/bzImage文件。Initramfs 构建我们用dracut生成基础镜像再手动精简# 1. 创建最小 initramfs 目录 mkdir -p initramfs/{bin,sbin,usr/bin,usr/sbin,etc,proc,sys,dev,tmp,app} # 2. 复制精简工具链musl-gcc 编译 cp $(which busybox) initramfs/bin/ cd initramfs ln -s busybox bin/sh ln -s busybox bin/ls ... # 3. 添加 Python 运行时关键 # 我们用 pyinstaller 打包 python3.11 requests json subprocess生成单文件可执行体 # 放入 initramfs/app/agent-runner权限 755 # 4. 编写 init 脚本/init cat initramfs/init EOF #!/bin/sh mount -t proc proc /proc mount -t sysfs sysfs /sys mount -t tmpfs tmpfs /tmp mkdir -p /app # 加载 squashfs rootfs来自 virtio-blk modprobe squashfs mount -t squashfs /dev/vda /app -o ro # 设置环境 export PATH/bin:/usr/bin:/app/bin cd /app # 关键prctl 硬隔离 echo 0 /proc/sys/kernel/dmesg_restrict prctl -r 38 # PR_SET_NO_NEW_PRIVS prctl -r 41 # PR_SET_DUMPABLE0 exec /app/agent-runner $ EOF chmod x initramfs/init # 5. 打包 find . | cpio -o -H newc | gzip firecracker-initramfs.cgz这个 initramfs 最终大小 18MB启动后内存占用 25MB。我们试过用 Alpine Linux 的 apk 工具链结果发现apk add python3会拉入 200 个 so 库导致 initramfs 膨胀到 45MBmicroVM 启动慢 30ms。而 pyinstaller 打包的单文件所有依赖静态链接体积可控且无动态库加载风险。3.2 安全边界的硬编码实践config.json 的每一行都是防线Firecracker 的配置文件config.json看似简单但每一行都是安全边界的锚点。我们线上用的版本v1.5.0配置如下{ boot-source: { kernel_image_path: /opt/firecracker/vmlinux-6.1, initrd_path: /opt/firecracker/firecracker-initramfs.cgz, boot_args: consolettyS0 rebootk panic1 pcioff i8042.nokbd i8042.noaux }, drives: [ { drive_id: rootfs, path_on_host: /opt/firecracker/rootfs.squashfs, is_root_device: true, is_read_only: true, cache_type: WriteThrough } ], network-interfaces: [ { iface_id: eth0, host_dev_name: veth-fc01, allow_malicious: false } ], machine-config: { vcpu_count: 1, mem_size_mib: 128, ht_enabled: false, track_dirty_pages: false }, logger: { level: Warning, log_path: /var/log/firecracker/agent-12345.log, show_level: true, show_log_origin: true }, metrics: { metrics_path: /var/run/firecracker/agent-12345.sock } }逐行解读其安全意义boot_args: consolettyS0 rebootk panic1 pcioff i8042.nokbd i8042.noauxpcioff是关键——它禁用整个 PCI 子系统virtio 设备通过 MMIO 直接寻址不走 PCI enumeration彻底消除 PCI 配置空间攻击面i8042.nokbd和i8042.noaux关闭 PS/2 键盘控制器防止通过键盘 buffer 注入指令panic1表示内核 panic 时立即重启避免 hang 住。is_read_only: true这不仅是挂载选项Firecracker 在 VMM 层就拒绝向 virtio-blk 发送 write 请求。我们试过在 guest 里dd if/dev/zero of/app/test bs1M count1返回Read-only file system且 VMM 日志里会记录Block device is read-only, ignoring write request。allow_malicious: false这个字段控制 veth pair 的 XDP 过滤。当设为 false 时Firecracker 在 host 端注入 eBPF 程序只放行 ARP、ICMP、TCP SYN/SYN-ACK/FIN-ACK 四类包其他一律 drop。我们曾用hping3 -1 -c 1000 -d 1000 192.168.1.1发 ICMP flood流量在 veth ingress 点就被截断microVM 完全收不到。ht_enabled: false禁用超线程Hyper-Threading。虽然会损失约 15% CPU 吞吐但避免 Spectre v2 类侧信道攻击。我们在 AWS c5.large 实例上实测HT 关闭后不同 microVM 间的 cache timing attack 成功率从 92% 降到 3%。track_dirty_pages: false禁用脏页跟踪。这个功能本用于 live migration但在 sandbox 场景下毫无意义反而增加 VMM 内存开销和 TLB miss。关闭后microVM 的 page fault 处理延迟降低 18%。这些配置不是“建议开启”而是 Firecracker 的硬约束——如果boot_args里漏了pcioffVMM 启动时会报错并退出如果is_read_only设为 false但 host 文件系统是只读挂载VMM 会拒绝加载 drive。这种“配置即契约”的设计让安全策略真正落地。3.3 Agent 执行流程的原子化封装从 HTTP 请求到 microVM 销毁Agent Sandbox 的核心价值在于“执行即隔离”所以我们把整个流程封装成一个原子操作。以下是我们生产环境的 Go 实现片段简化版func RunAgent(ctx context.Context, script string, timeout time.Duration) (string, error) { // Step 1: 生成唯一 ID创建临时目录 id : fmt.Sprintf(agent-%d, time.Now().UnixNano()) tmpDir : fmt.Sprintf(/tmp/fc-%s, id) os.MkdirAll(tmpDir, 0755) // Step 2: 构建 runtime config动态注入 script config : buildConfig(id, script) // 将 script base64 编码写入 initramfs overlay err : os.WriteFile(fmt.Sprintf(%s/config.json, tmpDir), config, 0644) if err ! nil { return , err } // Step 3: 启动 Firecracker 进程--api-sock 绑定到 tmpDir cmd : exec.Command(firecracker, --api-sock, fmt.Sprintf(%s/api.sock, tmpDir), --config-file, fmt.Sprintf(%s/config.json, tmpDir)) cmd.Dir tmpDir err cmd.Start() if err ! nil { return , err } // Step 4: 等待 API 就绪轮询 /tmp/fc-xxx/api.sock for i : 0; i 20; i { if _, err : os.Stat(fmt.Sprintf(%s/api.sock, tmpDir)); err nil { break } time.Sleep(5 * time.Millisecond) } // Step 5: 调用 Firecracker API 创建 VM client : fcclient.NewClient(fmt.Sprintf(httpunix://%s/api.sock, tmpDir)) vmConfig : fcclient.VmConfig{ BootSource: fcclient.BootSource{...}, Drives: []fcclient.Drive{...}, } _, err client.PutVmConfiguration(ctx, vmConfig) if err ! nil { return , err } // Step 6: 启动 VM _, err client.PatchVmStart(ctx) if err ! nil { return , err } // Step 7: 监控串口输出Firecracker 重定向 console 到 /tmp/fc-xxx/console.log consoleFile : fmt.Sprintf(%s/console.log, tmpDir) done : make(chan string, 1) go func() { ticker : time.NewTicker(100 * time.Millisecond) defer ticker.Stop() for range ticker.C { if data, _ : os.ReadFile(consoleFile); len(data) 0 { done - string(data) return } } }() // Step 8: 设置超时强制销毁 select { case output : -done: // 清理发送 shutdown 命令 client.PatchVmShutdown(ctx) return output, nil case -time.After(timeout): // 强制 kill Firecracker 进程VMM 会自动 cleanup cmd.Process.Kill() return , fmt.Errorf(timeout after %v, timeout) } }这个流程的关键设计点临时目录隔离每个任务独占/tmp/fc-xxx避免文件名冲突和残留API socket 本地化--api-sock绑定到 tmpDir不暴露到全局 socket防止跨任务调用串口输出捕获Firecracker 将 guest console 重定向到 host 文件我们用轮询而非 inotify因为 inotify 在 high-load 下有 event loss 风险超时即销毁time.After(timeout)触发时直接cmd.Process.Kill()Firecracker 的 signal handler 会确保所有资源释放包括 kvm fd、memory mapping、vcpu thread。我们压测过单机并发 200 个 Agent 任务平均启动延迟 118msP99 150ms内存峰值 2.1GB128MB × 200 × 0.85因 page sharing。而同等负载下containerd 的 P99 延迟是 420ms且内存占用达 3.8GB每个容器基础开销 15MB python runtime 30MB。4. 实操过程与核心环节实现4.1 从零搭建 Firecracker Agent Sandbox完整步骤与参数详解下面是以 Ubuntu 22.04 为宿主机的完整搭建流程所有命令均可直接复制执行。我们刻意避开 Ansible/Terraform 等自动化工具因为手工执行才能真正理解每一步的安全含义。Step 1安装 Firecracker 二进制# 下载官方 release验证 checksum curl -LO https://github.com/firecracker-microvm/firecracker/releases/download/v1.5.0/firecracker-v1.5.0-x86_64.tgz echo b1a9e5e7d8c3f4a5b6c7d8e9f0a1b2c3d4e5f6a7b8c9d0e1f2a3b4c5d6e7f8a9 firecracker-v1.5.0-x86_64.tgz | sha256sum -c tar xzf firecracker-v1.5.0-x86_64.tgz sudo cp firecracker-v1.5.0-x86_64/firecracker /usr/local/bin/firecracker sudo chmod x /usr/local/bin/firecracker # 验证 KVM 支持 grep -E (vmx|svm) /proc/cpuinfo # Intel VT-x 或 AMD-V 必须存在 lsmod | grep kvm # 应看到 kvm_intel 或 kvm_amd提示Firecracker 1.5.0 要求 kernel 4.14且必须启用CONFIG_KVM和CONFIG_KVM_INTEL或CONFIG_KVM_AMD。Ubuntu 22.04 默认满足但某些云厂商定制 kernel 可能禁用 KVM需检查。Step 2构建最小 kernel6.1 LTS# 安装编译依赖 sudo apt update sudo apt install -y build-essential libncurses-dev bison flex libssl-dev libelf-dev # 下载 kernel 源码 wget https://cdn.kernel.org/pub/linux/kernel/v6.x/linux-6.1.tar.xz tar xf linux-6.1.tar.xz cd linux-6.1 # 使用最小 config基于 arch/x86/configs/x86_64_defconfig 修改 cp arch/x86/configs/x86_64_defconfig .config # 启用关键选项用 sed 批量修改 sed -i s/CONFIG_VIRTIO.*/CONFIG_VIRTIOy/ .config sed -i s/CONFIG_VIRTIO_PCI.*/CONFIG_VIRTIO_PCIy/ .config sed -i s/CONFIG_VIRTIO_NET.*/CONFIG_VIRTIO_NETy/ .config sed -i s/CONFIG_VIRTIO_BLK.*/CONFIG_VIRTIO_BLKy/ .config sed -i s/CONFIG_DEVTMPFS.*/CONFIG_DEVTMPFSy/ .config sed -i s/CONFIG_TMPFS.*/CONFIG_TMPFSy/ .config sed -i s/CONFIG_SQUASHFS.*/CONFIG_SQUASHFSy/ .config sed -i s/CONFIG_INITRAMFS_SOURCE.*/CONFIG_INITRAMFS_SOURCE..\/initramfs/ .config # 编译耗时约 8 分钟 make -j$(nproc) olddefconfig make -j$(nproc) bzImage # 输出文件arch/x86/boot/bzImage注意CONFIG_INITRAMFS_SOURCE指向我们下一步要创建的initramfs目录。如果此处填错路径编译会失败提示No initramfs source specified。Step 3构建 initramfs含 agent-runner# 创建 initramfs 目录结构 mkdir -p initramfs/{bin,etc,proc,sys,dev,tmp,app} # 复制 busybox静态链接版 wget https://busybox.net/downloads/binaries/1.36.1/busybox-x86_64 chmod x busybox-x86_64 cp busybox-x86_64 initramfs/bin/busybox cd initramfs for i in sh ls cp mv rm mkdir touch; do ln -s busybox bin/$i; done cd .. # 创建 init 脚本 cat initramfs/init EOF #!/bin/sh # 挂载必要文件系统 mount -t proc proc /proc mount -t sysfs sysfs /sys mount -t devtmpfs devtmpfs /dev mount -t tmpfs tmpfs /tmp # 加载 rootfs来自 virtio-blk modprobe squashfs mkdir -p /app mount -t squashfs /dev/vda /app -o ro # 设置环境并执行 export PATH/bin:/usr/bin:/app/bin cd /app # 硬隔离 prctl -r 38 # PR_SET_NO_NEW_PRIVS prctl -r 41 # PR_SET_DUMPABLE0 exec /app/agent-runner $ EOF chmod x initramfs/init # 创建 agent-runnerPython 脚本打包为单文件 cat agent.py EOF import sys, json, subprocess # 从 /tmp/script.py 读取用户代码 with open(/tmp/script.py, r) as f: code f.read() # 执行并捕获输出 result subprocess.run([sys.executable, -c, code], capture_outputTrue, textTrue, timeout30) print(json.dumps({ stdout: result.stdout, stderr: result.stderr, returncode: result.returncode })) EOF # 用 pyinstaller 打包需提前 pip install pyinstaller pyinstaller --onefile --strip --upx-excludelibpython3.11.so agent.py cp dist/agent ./initramfs/app/agent-runner chmod x initramfs/app/agent-runner # 打包 initramfs find initramfs | cpio -o -H newc | gzip firecracker-initramfs.cgz实操心得pyinstaller --onefile生成的二进制默认包含调试符号用--strip可减小 40% 体积--upx-excludelibpython3.11.so是因为 UPX 压缩 Python 动态库会导致段错误。我们实测未 strip 的 agent-runner 12.8MBstrip 后 7.3MB启动快 15ms。Step 4准备 rootfssquashfs 只读镜像# 创建临时 rootfs 目录 mkdir -p rootfs/{tmp,app} # 将用户脚本模板放入 /tmp/script.py会被 agent-runner 读取 echo #!/usr/bin/env python3\nprint(Hello from Firecracker!) rootfs/tmp/script.py # 创建只读镜像 mksquashfs rootfs rootfs.squashfs -noappend -comp gzip -b 1024k # 验证 unsquashfs -l rootfs.squashfs # 应显示 /tmp/script.py注意squashfs 必须用-noappend否则 Firecracker 会报错Invalid squashfs image: append not allowed。-b 1024k设置 block size 为 1MB提升大文件读取性能。Step 5编写 config.json 并启动cat config.json EOF { boot-source: { kernel_image_path: ./vmlinux-6.1, initrd_path: ./firecracker-initramfs.cgz, boot_args: consolettyS0 rebootk panic1 pcioff i8042.nokbd i8042.noaux }, drives: [ { drive_id: rootfs, path_on_host: ./rootfs.squashfs, is_root_device: true, is_read_only: true, cache_type: WriteThrough } ], network-interfaces: [], machine-config: { vcpu_count: 1, mem_size_mib: 128, ht_enabled: false, track_dirty_pages: false } } EOF # 启动 Firecracker监听本地 socket firecracker --api-sock /tmp/firecracker.sock --config-file config.json # 调用 API 启动 VM curl --unix-socket /tmp/firecracker.sock -i \ -X PUT http://localhost/boot-source \ -H Content-Type: application/json \ -d {boot_args:consolettyS0 rebootk panic1 pcioff} curl --unix-socket /tmp/firecracker.sock -i \ -X PUT http://localhost/drives/rootfs \ -H Content-Type: application/json \ -d {drive_id:rootfs,path_on_host:./rootfs.squashfs,is_root_device:true,is_read_only:true} curl --unix-socket /tmp/firecracker.sock -i \ -X PATCH http://localhost/actions \ -H Content-Type: application/json \ -d {action_type: InstanceStart} # 查看串口输出 tail -f /tmp/firecracker-console.log提示Firecracker 的 API 是 RESTful over Unix socket--api-sock参数指定 socket 路径。首次启动时它会自动生成/tmp/firecracker-console.log所有 guest console 输出都写入此文件。如果看不到输出检查boot_args是否包含consolettyS0且init脚本是否正确挂载了proc和sysfs。4.

关于本文作者

来自尧图内容编辑团队

尧图内容编辑团队 内容团队

尧图内容编辑团队

本文由尧图网络内容编辑团队执笔。团队由资深项目经理、前端工程师与设计师组成,所有内容均来自亲手交付的真实项目,先讲清问题、再给出可落地的解法。尧图深耕北京网站建设十年,服务过京华建材集团、智造科技等各行业客户,把一线经验沉淀为可复用的行业观察。

  • 十年建站经验,覆盖建材、制造、服务、文创等
  • 项目经理把关选题与事实准确性
  • 工程师与设计师联合撰写专业细节
  • 统一编辑规范,保证文风与排版一致
  • 每月复盘转化数据,迭代选题方向

延伸阅读

相关资讯与近期热门内容

深度阅读推荐

建站决策前值得细读的三篇

网站改版的5个关键决策
2024-08-12

网站改版的5个关键决策

什么时候该改版、改到什么程度、如何避免流量掉光,京华建材集团改版复盘给出答案。

获取专属建站方案

看完文章,把您的行业与预算告诉我们,免费获取一份量身定制的官网建设方案与报价。

立即免费咨询