The generated initramfs is compatible with rust-vmm based hypervisors.
- Build the initramfs
initramfs-builder build python:3.12-alpine \
--inject ./agent:/usr/bin/agent \
--init ./init.sh \
--platform-arch amd64 \
-o python.cpio.gz- Get a compatible kernel
For Firecracker, use their provided kernel or build a minimal one:
# Firecracker kernel (x86_64)
curl -L -o vmlinux \
https://s3.amazonaws.com/spec.ccfc.min/firecracker-ci/v1.10/x86_64/vmlinux-6.1.102
# Alpine kernel (arm64)
curl -L -o vmlinux \
https://dl-cdn.alpinelinux.org/alpine/v3.21/releases/aarch64/netboot/vmlinuz-lts- Boot the VM
// Simplified rust-vmm example
let vm = VmBuilder::new()
.kernel_path("vmlinux")
.initramfs_path("python.cpio.gz")
.kernel_cmdline("console=ttyS0 rdinit=/init")
.memory_mb(256)
.build()?;
vm.start()?;Typically done via vsock (virtio socket):
┌─────────────────┐ vsock ┌─────────────────┐
│ Hypervisor │◄──────────────────────►│ VM (agent) │
│ │ CID:3, Port:5000 │ │
└─────────────────┘ └─────────────────┘
Example init script for vsock agent:
#!/bin/sh
mount -t proc proc /proc
mount -t sysfs sysfs /sys
mount -t devtmpfs devtmpfs /dev
# Agent listens on vsock port 5000
exec /usr/bin/agent --vsock-port 5000Quick test without setting up rust-vmm:
# Build for arm64 (Apple Silicon)
initramfs-builder build alpine:latest \
--platform-arch arm64 \
-o test.cpio.gz
# Download kernel
curl -L -o vmlinuz \
https://dl-cdn.alpinelinux.org/alpine/v3.21/releases/aarch64/netboot/vmlinuz-lts
# Boot with QEMU
qemu-system-aarch64 \
-M virt \
-cpu cortex-a72 \
-m 256M \
-kernel vmlinuz \
-initrd test.cpio.gz \
-append "console=ttyAMA0 rdinit=/init" \
-nographicFor x86_64:
initramfs-builder build alpine:latest \
--platform-arch amd64 \
-o test.cpio.gz
qemu-system-x86_64 \
-m 256M \
-kernel vmlinuz \
-initrd test.cpio.gz \
-append "console=ttyS0 rdinit=/init" \
-nographic# x86_64 (Intel/AMD, AWS EC2)
initramfs-builder build python:alpine --platform-arch amd64
# arm64 (Apple Silicon, AWS Graviton)
initramfs-builder build python:alpine --platform-arch arm64# Exclude unnecessary files
initramfs-builder build python:3.12-alpine \
--exclude "/usr/share/doc/*" \
--exclude "/usr/share/man/*" \
--exclude "/var/cache/*" \
--exclude "*.pyc" \
--exclude "__pycache__" \
-o python-slim.cpio.gzuse rusty_initramfs_builder::{InitramfsBuilder, Compression};
#[tokio::main]
async fn main() -> anyhow::Result<()> {
InitramfsBuilder::new()
.image("python:3.12-alpine")
.inject("./agent", "/usr/bin/agent")
.init_script("./init.sh")
.exclude(&["/usr/share/doc/*", "*.pyc"])
.compression(Compression::Gzip)
.platform("linux", "amd64")
.build("output.cpio.gz")
.await?;
Ok(())
}- Check kernel and initramfs architectures match
- Verify
/initexists and is executable - Use
rdinit=/initin kernel cmdline (notinit=/init)
The kernel can't find /init. Make sure:
- You used
--initto provide an init script, OR - The base image has
/initor/sbin/init
Check vsock is enabled in hypervisor config and the agent is listening on the correct CID/port.