Skip to content

Firecracker VMM

Experiments with https://github.com/firecracker-microvm/firecracker

Follow most of the steps from get-started to spin-up a minimal VM

to get-started with firecracker

to understand ip route

this is used for configuring networking inside VM

about drives

  • for all drives, a device-file under /dev is created in inside VM

    • only rootfs drive is mounted automatically at /,
    • rest of the drives are to be mounted manually
      • do lsblk to list all devices
  • path_on_host can be either

    • file-system image created using mkfs,
    • loop-device, or any device. [checkout]

run script

run.sh
#!/bin/bash

set -x

download-kernel() {
    ARCH="$(uname -m)"
    release_url="https://github.com/firecracker-microvm/firecracker/releases"
    latest_version=$(basename $(curl -fsSLI -o /dev/null -w %{url_effective} ${release_url}/latest))
    CI_VERSION=${latest_version%.*}
    latest_kernel_key=$(curl "http://spec.ccfc.min.s3.amazonaws.com/?prefix=firecracker-ci/$CI_VERSION/$ARCH/vmlinux-&list-type=2" |
        grep -oP "(?<=<Key>)(firecracker-ci/$CI_VERSION/$ARCH/vmlinux-[0-9]+\.[0-9]+\.[0-9]{1,3})(?=</Key>)" |
        sort -V | tail -1)

    # Download a linux kernel binary
    wget "https://s3.amazonaws.com/spec.ccfc.min/${latest_kernel_key}"

    latest_ubuntu_key=$(curl "http://spec.ccfc.min.s3.amazonaws.com/?prefix=firecracker-ci/$CI_VERSION/$ARCH/ubuntu-&list-type=2" |
        grep -oP "(?<=<Key>)(firecracker-ci/$CI_VERSION/$ARCH/ubuntu-[0-9]+\.[0-9]+\.squashfs)(?=</Key>)" |
        sort -V | tail -1)
    ubuntu_version=$(basename $latest_ubuntu_key .squashfs | grep -oE '[0-9]+\.[0-9]+')

    # Download a rootfs from Firecracker CI
    wget -O ubuntu-$ubuntu_version.squashfs.upstream "https://s3.amazonaws.com/spec.ccfc.min/$latest_ubuntu_key"
}

spin-vm() {
    sudo release-v1.13.1-x86_64/firecracker-v1.13.1-x86_64 --api-sock /tmp/firecracker.socket --config-file vm_template.json
}

setup-overlay() {

    local lower="./squashfs-root"
    local upper="./overlay-upper"
    local mount_point="./exp-overlay"

    sudo mount overlay -t overlay -olowerdir=$lower,upperdir=$upper,workdir=./work $mount_point

}

# run cmd
$1

vm template

below template is used with spin-vm command in run-script

vm_template.json
{
    "boot-source": {
        "kernel_image_path": "vmlinux-6.1.141",
        "boot_args": "console=ttyS0 reboot=k panic=1",
        "initrd_path": null
    },
    "drives": [
        {
            "drive_id": "rootfs",
            "partuuid": null,
            "is_root_device": true,
            "cache_type": "Unsafe",
            "is_read_only": false,
            "path_on_host": "ubuntu-24.04.ext4",
            "io_engine": "Sync",
            "rate_limiter": null,
            "socket": null
        },
        {
            "drive_id": "loop5_dev",
            "partuuid": null,
            "is_root_device": false,
            "cache_type": "Unsafe",
            "is_read_only": false,
            "path_on_host": "/tmp/exp1.img",
            "io_engine": "Sync",
            "rate_limiter": null,
            "socket": null
        }
    ],
    "machine-config": {
        "vcpu_count": 2,
        "mem_size_mib": 1024,
        "smt": false,
        "track_dirty_pages": false
    },
    "balloon": null,
    "network-interfaces": [
        {
            "iface_id": "1",
            "host_dev_name": "tap0",
            "guest_mac": "06:00:c0:a8:00:02",
            "rx_rate_limiter": null,
            "tx_rate_limiter": null
        }
    ],
    "vsock": null,
    "logger": null,
    "metrics": null,
    "mmds-config": {
        "network_interfaces": [
            "1"
        ],
        "ipv4_address": "169.254.169.250",
        "version": "V2",
        "imds_compat": true
    },
    "entropy": null
}