Firecracker is a virtual machine monitor that leverages KVM to rapidly launch Linux guest VMs. Its key advantage is its ability to quickly start up VMs.
Firecracker was created by AWS with the aim of boosting the speed and efficiency of AWS services such as AWS Lambda and AWS Fargate. Written in Rust, Firecracker is licensed under the Apache version 2.0.
Firecracker is an open source virtualization technology that is purpose-built for creating and managing secure, multi-tenant container and function-based services that provide serverless operational models
Install firecracker
$ pacman -S firecracker
Check the github repository for other method of installation.
Create a Kernel Image
Get the tarball of the kernel you want from https://kernel.org or git clone the repository from https://git.kernel.org and checkout the Linux version you want to build.
The linux kernel need to be configured and Firecracker has a recommended x86 config. Copy the config file to .config
under the Linux source directory and launch make
. After a successful build, the kernel image can be located under ./vmlinux
.
Create Arch rootfs
Create a new disk image.
$ qemu-img create -f raw arch-rootfs.ext4 800M
Formatting 'arch-rootfs.ext4', fmt=raw size=838860800
Format the disk image to ext4
$ mkfs.ext4 arch-rootfs.ext4
mke2fs 1.47.0 (5-Feb-2023)
Discarding device blocks: done
Creating filesystem with 204800 4k blocks and 51296 inodes
Filesystem UUID: 48349973-58f1-4a8d-bb78-770e97590c2b
Superblock backups stored on blocks:
32768, 98304, 163840
Allocating group tables: done
Writing inode tables: done
Creating journal (4096 blocks): done
Writing superblocks and filesystem accounting information: done
Create the directory to mount the disk image.
$ mkdir /tmp/rootfs
$ mount arch-rootfs.ext4 /tmp/rootfs
Use mkarchroot
to create an Arch Linux chroot at directory archrtfs
with the base
package.
$ cd /tmp/my-rootfs
$ mkarchroot archrtfs base
==> Creating install root at /tmp/qemu/ar
==> Installing packages to /tmp/qemu/ar
:: Synchronizing package databases...
core 154.0 KiB 642 KiB/s 00:00 [#############################################################################] 100%
extra 1762.9 KiB 7.58 MiB/s 00:00 [#############################################################################] 100%
community 7.2 MiB 2.38 MiB/s 00:03 [#############################################################################] 100%
resolving dependencies...
looking for conflicting packages...
Packages (113) acl-2.3.1-3 archlinux-keyring-20230320-1 argon2-20190702-4 attr-2.5.1-3 audit-3.1-1 bash-5.1.016-3 brotli-1.0.9-10 bzip2-1.0.8-5 ca-certificates-20220905-1 ca-certificates-mozilla-3.89-1
ca-certificates-utils-20220905-1 coreutils-9.2-3 cryptsetup-2.6.1-3 curl-8.0.1-1 dbus-1.14.6-2 device-mapper-2.03.20-1 e2fsprogs-1.47.0-1 expat-2.5.0-1 file-5.44-3 filesystem-2023.01.31-1
findutils-4.9.0-3 gawk-5.2.1-2 gcc-libs-12.2.1-2 gdbm-1.23-2 gettext-0.21.1-5 glib2-2.76.1-1 glibc-2.37-2 gmp-6.2.1-2 gnupg-2.2.41-1 gnutls-3.8.0-1 gpgme-1.19.0-3 grep-3.10-1
gzip-1.12-2 hwdata-0.369-1 iana-etc-20230405-1 icu-72.1-2 iproute2-6.2.0-2 iptables-1:1.8.9-1 iputils-20221126-1 json-c-0.16-1 kbd-2.5.1-1 keyutils-1.6.3-1 kmod-30-3 krb5-1.20.1-1
less-1:608-2 libarchive-3.6.2-2 libassuan-2.5.5-2 libbpf-1.1.0-1 libcap-2.68-1 libcap-ng-0.8.3-1 libelf-0.189-1 libevent-2.1.12-4 libffi-3.4.4-1 libgcrypt-1.10.1-2 libgpg-error-1.46-2
libidn2-2.3.4-3 libksba-1.6.3-1 libldap-2.6.4-1 libmnl-1.0.5-1 libnetfilter_conntrack-1.0.9-1 libnfnetlink-1.0.2-1 libnftnl-1.2.5-1 libnghttp2-1.52.0-2 libnl-3.7.0-3 libp11-kit-0.24.1-1
libpcap-1.10.3-1 libpsl-0.21.2-1 libsasl-2.1.28-4 libseccomp-2.5.4-1 libsecret-0.20.5-2 libssh2-1.10.0-3 libsysprof-capture-3.48.0-1 libtasn1-4.19.0-1 libtirpc-1.3.3-2 libunistring-1.1-2
libverto-0.3.2-4 libxcrypt-4.4.33-1 libxml2-2.10.3-2 licenses-20220125-2 linux-api-headers-6.1.9-1 lz4-1:1.9.4-1 mpfr-4.2.0-3 ncurses-6.4-1 nettle-3.8.1-1 npth-1.6-4 openssl-3.0.8-1
p11-kit-0.24.1-1 pacman-6.0.2-6 pacman-mirrorlist-20230410-1 pam-1.5.2-1 pambase-20221020-1 pciutils-3.9.0-2 pcre2-10.42-2 pinentry-1.2.1-1 popt-1.19-1 procps-ng-3.3.17-1 psmisc-23.6-1
readline-8.2.001-2 sed-4.9-3 shadow-4.13-2 sqlite-3.41.2-1 systemd-253.3-1 systemd-libs-253.3-1 systemd-sysvcompat-253.3-1 tar-1.34-2 tpm2-tss-3.2.0-3 tzdata-2023c-1 util-linux-2.38.1-3
util-linux-libs-2.38.1-3 xz-5.4.2-1 zlib-1:1.2.13-2 zstd-1.5.4-1 base-3-1
Total Download Size: 0.40 MiB
Total Installed Size: 493.18 MiB
:: Proceed with installation? [Y/n]
:: Retrieving packages...
Copy the filesystem from the temporary directory.
$ cp -r ar/* .
$ rm ar ar.lock -rf
Remove the root password.
$ arch-chroot /mnt/rootfs passwd -d root
Unmount the disk image and remove the directory.
$ umount /tmp/rootfs
$ rm -rf /tmp/rootfs
Move the kernel image and the filesystem to a new directory.
Start the MicroVM
Firecracker VMs can be started using the socket interface or configuration file.
We will use the configuration file method for better clarity. You can check the getting started instruction to create the API socket and feed data to it.
The configuration file is a JSON file.
{
"boot-source": {
"kernel_image_path": "vmlinux",
"boot_args": "console=ttyS0 reboot=k panic=1 pci=off"
},
"drives": [
{
"drive_id": "rootfs",
"path_on_host": "arch-rootfs.ext4",
"is_root_device": true,
"is_read_only": false
}
],
"machine-config": {
"vcpu_count": 2,
"mem_size_mib": 1024
}
}
Starting the VM without an API socket and voila!
$ firecracker --no-api --config-file vm-config.json
[ 0.000000] Linux version 5.10.177 (zain@code-lyoko) (gcc (GCC) 12.2.1 20230201, GNU ld (GNU Binutils) 2.40) #1 SMP Mon Apr 10 16:43:03 +04 2023
[ 0.000000] Command line: console=ttyS0 reboot=k panic=1 pci=off root=/dev/vda rw virtio_mmio.device=4K@0xd0000000:5
[ 0.000000] x86/fpu: Supporting XSAVE feature 0x001: 'x87 floating point registers'
[ 0.000000] x86/fpu: Supporting XSAVE feature 0x002: 'SSE registers'
[ 0.000000] x86/fpu: Supporting XSAVE feature 0x004: 'AVX registers'
...
...
...
[ OK ] Reached target Basic System.
Starting D-Bus System Message Bus...
Starting User Login Management...
Starting Permit User Sessions...
[ OK ] Finished Permit User Sessions.
[ OK ] Started Getty on tty1.
[ OK ] Started D-Bus System Message Bus.
[ OK ] Found device /dev/ttyS0.
[ OK ] Started Serial Getty on ttyS0.
[ OK ] Reached target Login Prompts.
[ OK ] Started User Login Management.
[ OK ] Reached target Multi-User System.
[ OK ] Reached target Graphical Interface.
Arch Linux 5.10.177 (ttyS0)
archlinux login: root
Last login: Mon Apr 10 20:33:32 on ttyS0
[root@archlinux ~]# systemd-analyze
Startup finished in 2.427s (kernel) + 2.017s (userspace) = 4.444s
graphical.target reached after 2.009s in userspace.
[root@archlinux ~]# ip a
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000
link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
inet 127.0.0.1/8 scope host lo
valid_lft forever preferred_lft forever
inet6 ::1/128 scope host
valid_lft forever preferred_lft forever
[root@archlinux ~]#
We have focus on getting the initial setup of our system up and running. However, at this point in time, we won’t have any network connectivity. Not to worry though, as we’ll cover how to configure the network in our upcoming blog series.
Resources
https://github.com/firecracker-microvm/firecracker
https://jvns.ca/blog/2021/01/23/firecracker--start-a-vm-in-less-than-a-second/
https://blog.herecura.eu/blog/2020-05-21-toying-around-with-firecracker/