Firecracker microVM
Converting Docker Containers to VM Images
API
- assume proper network setup, and hardcoded IP
- turn
make firecrackerinto a function call - add a function call to kill the vm
- stream the output over websockets
Networking
There are two main ways to connect our VM to the outside world.
Bridging
Bridging does not work with wireless interfaces, use IP Forwarding instead. TODO: use isolated network namespaces, or docker container
Create a new bridge, attach the Ethernet interface to the bridge, give it an IP address.
# Create a clean bridgesudo ip link del br0 type bridge 2>/dev/nullsudo ip link add br0 type bridge
# Attach enp1s0 to br0sudo ip addr flush dev enp1s0sudo ip link set enp1s0 downsudo ip link set enp1s0 master br0
# Bring them upsudo ip link set enp1s0 upsudo ip link set br0 up
# Manually assign IP to br0sudo ip addr add 192.168.1.200/24 dev br0
# Set default routesudo ip route add default via 192.168.1.1 dev br0 metric 200#sudo ip -6 route add default via fe80::1 dev br0 metric 2048Create a new tap device for VM and add it to the bridge.
# create a new tap devicesudo ip link del firetap0 2>/dev/nullsudo ip tuntap add firetap0 mode tap
# Attach it to br0sudo ip link set dev firetap0 master br0sudo ip link set firetap0 upTest Bridge Connectivity.
ping google.com -I br0 -4ping google.com -I br0 -6Test VM Connectivity.
ping 1.1.1.1curl icanhazip.comIP Forwarding
In this scenario, the host acts as a router and forwards the requests to the correct VM.
#!/bin/bash# Run this once on the host, or upon reboot
# VariablesROUTER_IPv4=192.168.1.1ROUTER_IPv6=fe80::1FTAP_INTERFACE=firetap0WLAN_INTERFACE=wlan0
# Remove older firecracker network interfacesudo ip link delete $FTAP_INTERFACE 2>/dev/null || true
# Add a tap device to act as a bridge between the microVM and the hostsudo ip tuntap add dev $FTAP_INTERFACE mode tap
# Set up IP addressing for the host on firetap0sudo ip addr add 172.16.0.1/24 dev $FTAP_INTERFACEsudo ip -6 addr add 2001:face::1/64 dev $FTAP_INTERFACEsudo ip link set $FTAP_INTERFACE upip addr show dev $FTAP_INTERFACE
# Enable IP forwardingsudo sysctl -w net.ipv4.ip_forward=1sudo sysctl -w net.ipv4.conf.all.forwarding=1sudo sysctl -w net.ipv6.conf.all.forwarding=1
# Set up routing rules# Add route for the VMs' subnet via the routersudo ip route add 172.16.0.0/24 via $ROUTER_IPv4 dev $WLAN_INTERFACEsudo ip -6 route add 2001:face::/64 via $ROUTER_IPv6 dev $WLAN_INTERFACE
# Configure firewall to allow traffic between VMs and the routersudo iptables -A FORWARD -i $FTAP_INTERFACE -o $WLAN_INTERFACE -j ACCEPTsudo iptables -A FORWARD -i $WLAN_INTERFACE -o $FTAP_INTERFACE -j ACCEPTsudo ip6tables -A FORWARD -i $FTAP_INTERFACE -o $WLAN_INTERFACE -j ACCEPTsudo ip6tables -A FORWARD -i $WLAN_INTERFACE -o $FTAP_INTERFACE -j ACCEPTDoing Stupid Things
- Running Docker inside Docker inside Firecracker inside Docker (inside QEMU)
References
- https://github.com/alexellis/firecracker-init-lab
- https://jvns.ca/blog/2021/01/23/firecracker—start-a-vm-in-less-than-a-second
- https://some-natalie.dev/blog/stop-saying-just-use-firecracker
- https://gist.github.com/jvns/bb0a93e3b84a5e8344c6b24b57b2b490
- https://blog.0x74696d.com/posts/networking-firecracker-lab