Getting Started with Firecracker and Firectl in Ubuntu
Get Firecracker
Get the latest firecracker binary from github
curl -LOJ https://github.com/firecracker-microvm/firecracker/releases/download/v0.13.0/firecracker-v0.13.0
mv firecracker-v0.13.0 firecracker
chmod +x firecracker
Copy to $PATH
sudo cp firecracker /usr/bin/
Set read/write access to KVM
sudo setfacl -m u:${USER}:rw /dev/kvm
Check if firecracker installed successfully
firecracker -V
Get Firectl
Build firectl binary
Currently firectl doesn’t have any release yet, so we need build it using go 1.11
Install Golang 1.11
sudo yum install -y git
git clone https://github.com/firecracker-microvm/firectl
cd firectl
make
Copy binary to $PATH
sudo cp firectl /usr/bin/
Check if firectl installed successfully
firectl -h
Start MicroVM
Download kernel and root filesystem in /tmp
curl -fsSL -o /tmp/hello-vmlinux.bin https://s3.amazonaws.com/spec.ccfc.min/img/hello/kernel/hello-vmlinux.bincurl -fsSL -o /tmp/hello-rootfs.ext4 https://s3.amazonaws.com/spec.ccfc.min/img/hello/fsfiles/hello-rootfs.ext4
Create microVM
firectl \
--kernel=/tmp/hello-vmlinux.bin \
--root-drive=/tmp/hello-rootfs.ext4 \
--kernel-opts="console=ttyS0 noapic reboot=k panic=1 pci=off nomodules rw"
Login to the microvm with username/password
roor/root
Stop microvm with reboot command
reboot
You have successfully installed, started and stopped a microVM.
Add external drive
Create a separate qcow2 image
qemu-img create -f qcow2 file.qcow2 100M
Use ext4 filesystem
sudo mkfs.ext4 file.qcow2
Add drive to the MicroVM when starting ( — add-drive)
firectl \
--kernel=/tmp/hello-vmlinux.bin \
--root-drive=/tmp/hello-rootfs.ext4 \
--kernel-opts="console=ttyS0 noapic reboot=k panic=1 pci=off nomodules rw" \
--add-drive=file.qcow2:rw
Validate inside guest vm
fdisk -l
it should print two virtual drive
Disk /dev/vda: 30 MiB, 31457280 bytes, 61440 sectors
Units: sectors of 1 * 512 = 512 bytes
Sector size (logical/physical): 512 bytes / 512 bytes
I/O size (minimum/optimal): 512 bytes / 512 bytesDisk /dev/vdb: 192 KiB, 196608 bytes, 384 sectors
Units: sectors of 1 * 512 = 512 bytes
Sector size (logical/physical): 512 bytes / 512 bytes
I/O size (minimum/optimal): 512 bytes / 512 bytes
Mount the 2nd drive
mount /dev/vdb /mnt
Setup network interface
Create a tap interface
sudo ip tuntap add tap0 mode tap # user $(id -u) group $(id -g)
sudo ip addr add 172.20.0.1/24 dev tap0
sudo ip link set tap0 up
Set your main interface device. If you have different name check it with ifconfig command
DEVICE_NAME=eth0
Provide iptables rules to enable packet forwarding
sudo sh -c "echo 1 > /proc/sys/net/ipv4/ip_forward"
sudo iptables -t nat -A POSTROUTING -o $DEVICE_NAME -j MASQUERADE
sudo iptables -A FORWARD -m conntrack --ctstate RELATED,ESTABLISHED -j ACCEPT
sudo iptables -A FORWARD -i tap0 -o $DEVICE_NAME -j ACCEPT
Get mac of the tap device
MAC="$(cat /sys/class/net/tap0/address)"
Provide interface to the MicroVM when starting ( — tap-device)
sudo firectl \
--kernel=/tmp/hello-vmlinux.bin \
--root-drive=/tmp/hello-rootfs.ext4 \
--kernel-opts="console=ttyS0 noapic reboot=k panic=1 pci=off nomodules rw" \
--add-drive=file.qcow2:rw \
--tap-device=tap0/$MAC
Validate inside the vm
ifconfig -aeth0 Link encap:Ethernet HWaddr E2:40:73:D5:72:44
BROADCAST MULTICAST MTU:1500 Metric:1
RX packets:0 errors:0 dropped:0 overruns:0 frame:0
TX packets:0 errors:0 dropped:0 overruns:0 carrier:0
collisions:0 txqueuelen:1000
RX bytes:0 (0.0 B) TX bytes:0 (0.0 B)lo Link encap:Local Loopback
LOOPBACK MTU:65536 Metric:1
RX packets:0 errors:0 dropped:0 overruns:0 frame:0
TX packets:0 errors:0 dropped:0 overruns:0 carrier:0
collisions:0 txqueuelen:1000
RX bytes:0 (0.0 B) TX bytes:0 (0.0 B)
Setup inside guest vm
ifconfig eth0 up && ip addr add dev eth0 172.20.0.2/24
ip route add default via 172.20.0.1 && echo "nameserver 8.8.8.8" > /etc/resolv.conf
Ping google.com from inside
ping google.com
Ping from outside
ping 172.20.0.2
If you enjoyed this article, spare me some claps