Skip to content

Firecracker microVM

Converting Docker Containers to VM Images

API

  1. assume proper network setup, and hardcoded IP
  2. turn make firecracker into a function call
  3. add a function call to kill the vm
  4. 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.

Terminal window
# Create a clean bridge
sudo ip link del br0 type bridge 2>/dev/null
sudo ip link add br0 type bridge
# Attach enp1s0 to br0
sudo ip addr flush dev enp1s0
sudo ip link set enp1s0 down
sudo ip link set enp1s0 master br0
# Bring them up
sudo ip link set enp1s0 up
sudo ip link set br0 up
# Manually assign IP to br0
sudo ip addr add 192.168.1.200/24 dev br0
# Set default route
sudo 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 2048

Create a new tap device for VM and add it to the bridge.

Terminal window
# create a new tap device
sudo ip link del firetap0 2>/dev/null
sudo ip tuntap add firetap0 mode tap
# Attach it to br0
sudo ip link set dev firetap0 master br0
sudo ip link set firetap0 up

Test Bridge Connectivity.

Terminal window
ping google.com -I br0 -4
ping google.com -I br0 -6

Test VM Connectivity.

Terminal window
ping 1.1.1.1
curl icanhazip.com

IP 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
# Variables
ROUTER_IPv4=192.168.1.1
ROUTER_IPv6=fe80::1
FTAP_INTERFACE=firetap0
WLAN_INTERFACE=wlan0
# Remove older firecracker network interface
sudo ip link delete $FTAP_INTERFACE 2>/dev/null || true
# Add a tap device to act as a bridge between the microVM and the host
sudo ip tuntap add dev $FTAP_INTERFACE mode tap
# Set up IP addressing for the host on firetap0
sudo ip addr add 172.16.0.1/24 dev $FTAP_INTERFACE
sudo ip -6 addr add 2001:face::1/64 dev $FTAP_INTERFACE
sudo ip link set $FTAP_INTERFACE up
ip addr show dev $FTAP_INTERFACE
# Enable IP forwarding
sudo sysctl -w net.ipv4.ip_forward=1
sudo sysctl -w net.ipv4.conf.all.forwarding=1
sudo sysctl -w net.ipv6.conf.all.forwarding=1
# Set up routing rules
# Add route for the VMs' subnet via the router
sudo ip route add 172.16.0.0/24 via $ROUTER_IPv4 dev $WLAN_INTERFACE
sudo ip -6 route add 2001:face::/64 via $ROUTER_IPv6 dev $WLAN_INTERFACE
# Configure firewall to allow traffic between VMs and the router
sudo iptables -A FORWARD -i $FTAP_INTERFACE -o $WLAN_INTERFACE -j ACCEPT
sudo iptables -A FORWARD -i $WLAN_INTERFACE -o $FTAP_INTERFACE -j ACCEPT
sudo ip6tables -A FORWARD -i $FTAP_INTERFACE -o $WLAN_INTERFACE -j ACCEPT
sudo ip6tables -A FORWARD -i $WLAN_INTERFACE -o $FTAP_INTERFACE -j ACCEPT

Doing Stupid Things

  • Running Docker inside Docker inside Firecracker inside Docker (inside QEMU)

References