Firecracker Backend Installation¶
This guide covers the installation and setup of the Firecracker backend for shed. Firecracker is Linux-only and requires KVM.
Prerequisites¶
- Linux host with KVM support
- Root access (for network setup)
- Docker (for building rootfs)
- Go 1.24+ (for building shed-agent)
1. Check KVM Support¶
Firecracker requires hardware virtualization (KVM). Verify it's available:
# Check if KVM is available
ls -la /dev/kvm
# If not accessible, add your user to the kvm group
sudo usermod -aG kvm $USER
# Log out and back in for changes to take effect
2. Download Firecracker¶
Run the download script to get Firecracker and a compatible kernel:
This installs:
- /usr/local/bin/firecracker - Firecracker binary (v1.14.1)
- /var/lib/shed/firecracker/vmlinux.bin - CI 6.1 kernel (quick-start fallback)
For a Docker-capable kernel with full BPF/cgroup support, build a custom kernel:
This overwrites/var/lib/shed/firecracker/vmlinux.bin with the custom kernel. Requires ~2GB disk space and build tools (sudo apt install build-essential flex bison libelf-dev bc libssl-dev).
3. Build the Rootfs Image¶
Build the base rootfs image that VMs will use:
This creates:
- /var/lib/shed/firecracker/base-rootfs.ext4 - 20GB ext4 image with Ubuntu 24.04, Docker, and shed-agent
4. Set Up Bridge Network¶
Firecracker VMs need a bridge network for connectivity. This is a one-time setup.
Create the Bridge¶
# Create bridge
sudo ip link add shed-br0 type bridge
sudo ip addr add 172.30.0.1/24 dev shed-br0
sudo ip link set shed-br0 up
Enable IP Forwarding¶
# Enable IP forwarding (temporary)
echo 1 | sudo tee /proc/sys/net/ipv4/ip_forward
# Make permanent
echo "net.ipv4.ip_forward = 1" | sudo tee /etc/sysctl.d/99-ip-forward.conf
sudo sysctl -p /etc/sysctl.d/99-ip-forward.conf
Configure NAT for Internet Access¶
# Add NAT rule for outbound traffic
sudo iptables -t nat -A POSTROUTING -s 172.30.0.0/24 -j MASQUERADE
# Allow forwarding
sudo iptables -A FORWARD -i shed-br0 -j ACCEPT
sudo iptables -A FORWARD -o shed-br0 -j ACCEPT
Make Network Persistent (Optional)¶
To persist the bridge across reboots, create a systemd-networkd configuration:
# /etc/systemd/network/shed-br0.netdev
cat << 'EOF' | sudo tee /etc/systemd/network/shed-br0.netdev
[NetDev]
Name=shed-br0
Kind=bridge
EOF
# /etc/systemd/network/shed-br0.network
cat << 'EOF' | sudo tee /etc/systemd/network/shed-br0.network
[Match]
Name=shed-br0
[Network]
Address=172.30.0.1/24
ConfigureWithoutCarrier=yes
EOF
# Enable systemd-networkd
sudo systemctl enable systemd-networkd
sudo systemctl restart systemd-networkd
For iptables persistence, install iptables-persistent:
5. Configure shed-server¶
Update your server.yaml to enable the Firecracker backend:
name: shed-server
http_port: 8080
ssh_port: 2222
enabled_backends:
- docker
- firecracker
default_backend: firecracker
# Credentials are copied into VMs at create/start time
# (Firecracker doesn't support bind mounts like Docker)
credentials:
ssh:
source: ~/.ssh
target: /home/shed/.ssh
readonly: true
gitconfig:
source: ~/.gitconfig
target: /home/shed/.gitconfig
readonly: true
# Environment variables passed to git clone and provisioning hooks
env_file: ~/.shed/env
firecracker:
kernel_path: /var/lib/shed/firecracker/vmlinux.bin
base_rootfs: /var/lib/shed/firecracker/base-rootfs.ext4
instance_dir: /var/lib/shed/firecracker/instances
socket_dir: /var/run/shed/firecracker
default_cpus: 2
default_memory_mb: 4096
default_disk_gb: 20
vsock_base_cid: 100
console_port: 1024
health_port: 1025
start_timeout: 120s
stop_timeout: 10s
bridge_name: shed-br0
bridge_cidr: 172.30.0.1/24
tap_prefix: shed-tap
Configure SSH for Private Repos¶
To clone private repositories via SSH, create an env file with the GIT_SSH_COMMAND:
mkdir -p ~/.shed
cat > ~/.shed/env << 'EOF'
GIT_SSH_COMMAND=ssh -o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null -i /home/shed/.ssh/id_ed25519
EOF
Note: Adjust the SSH key path if you use a different key type (e.g., id_rsa).
6. Create Required Directories¶
sudo mkdir -p /var/lib/shed/firecracker/instances
sudo mkdir -p /var/run/shed/firecracker
sudo chown -R $USER:$USER /var/lib/shed/firecracker
sudo chown -R $USER:$USER /var/run/shed/firecracker
7. Set Capabilities (Alternative to Running as Root)¶
To run shed-server without sudo, grant capabilities to BOTH binaries:
# Both binaries need CAP_NET_ADMIN for TAP device creation
sudo setcap cap_net_admin+ep ./bin/shed-server
sudo setcap cap_net_admin+ep /usr/local/bin/firecracker
# Verify capabilities are set
getcap ./bin/shed-server /usr/local/bin/firecracker
Note: Firecracker is spawned as a child process, and Linux capabilities don't inherit to child processes. That's why both binaries need the capability set directly.
8. Start the Server¶
9. Create a Firecracker Shed¶
# Create a shed with the Firecracker backend
shed create myproject --backend=firecracker
# Or with custom resources
shed create myproject --backend=firecracker --cpus=4 --memory=8192
Troubleshooting¶
KVM Permission Denied¶
Solution: Add your user to the kvm group:
Bridge Not Found¶
Solution: Create the bridge network (see step 4).
TAP Device Creation Failed¶
or
Solution: Run shed-server as root or with CAP_NET_ADMIN capability on BOTH binaries:
sudo shed-server serve
# Or with capabilities (must set on BOTH binaries)
sudo setcap cap_net_admin+ep $(which shed-server)
sudo setcap cap_net_admin+ep $(which firecracker)
If you see "Resource busy", clean up stale TAP devices:
Vsock Address In Use¶
Cannot create backend for vsock device: UnixBind(Os { code: 98, kind: AddrInUse, message: "Address in use" })
Solution: Remove stale vsock socket files:
VM Timeout During Start¶
Possible causes:
1. Rootfs image is corrupted - rebuild with build-firecracker-rootfs.sh
2. Kernel is incompatible - try a different kernel version
3. shed-agent is not starting - check VM console output
4. Stale socket files - remove /var/run/shed/firecracker/*.sock and *.vsock
No Network Connectivity in VM¶
How network is configured: The VM's IP address is passed via kernel command line arguments using the kernel IP autoconfig format: ip=<client>::<gateway>:<netmask>::<device>:off. For example: ip=172.30.0.2::172.30.0.1:255.255.255.0::eth0:off. The kernel configures the network interface automatically during boot.
Verify:
1. Bridge is up: ip link show shed-br0
2. IP forwarding is enabled: cat /proc/sys/net/ipv4/ip_forward
3. NAT rules are in place: sudo iptables -t nat -L -n
4. TAP device is attached to bridge: ip link show
5. Check kernel args inside VM: shed exec myproject -- cat /proc/cmdline
6. Check network-setup ran: shed exec myproject -- systemctl status network-setup
7. Check interface is up: shed exec myproject -- ip addr show eth0
Docker Fails to Start in VM¶
Docker is configured with the vfs storage driver and cgroupfs driver for compatibility with the Firecracker kernel. If Docker fails to start:
# Check Docker daemon status
shed exec myproject -- systemctl status docker
# View Docker daemon logs
shed exec myproject -- journalctl -u docker
# Verify daemon.json exists
shed exec myproject -- cat /etc/docker/daemon.json
# Check cgroup support (kernel args should include cgroup_enable=memory)
shed exec myproject -- cat /proc/cmdline | grep cgroup
If you see cgroup errors, ensure the kernel args include cgroup_enable=memory cgroup_memory=1. This is set automatically by shed-server.
Docker Containers Fail to Start (BPF Error)¶
If you see errors like bpf_prog_query(BPF_CGROUP_DEVICE) failed:
runc create failed: unable to start container process: error during container init:
error setting cgroup config for procHooks process: bpf_prog_query(BPF_CGROUP_DEVICE)
failed: invalid argument
This means the kernel lacks BPF cgroup support. The custom 6.1 kernel built by build-firecracker-kernel.sh has full BPF support. If you're using the CI fallback kernel, build a custom kernel which includes:
- CONFIG_BPF=y
- CONFIG_BPF_SYSCALL=y
- CONFIG_CGROUP_BPF=y
To build and use the Docker-capable kernel:
Then ensure kernel_path in your server.yaml points to the built kernel:
Network Architecture¶
┌─────────────┐
│ Host │
│ eth0/wlan │
└──────┬──────┘
│ NAT (iptables MASQUERADE)
┌──────┴──────┐
│ shed-br0 │ 172.30.0.1/24
│ (bridge) │
└──────┬──────┘
┌────────────┼────────────┐
│ │ │
┌─────┴─────┐┌─────┴─────┐┌─────┴─────┐
│shed-tap-0 ││shed-tap-1 ││shed-tap-2 │
└─────┬─────┘└─────┬─────┘└─────┬─────┘
│ │ │
┌─────┴─────┐┌─────┴─────┐┌─────┴─────┐
│ VM 0 ││ VM 1 ││ VM 2 │
│172.30.0.2 ││172.30.0.3 ││172.30.0.4 │
└───────────┘└───────────┘└───────────┘
Each VM gets: - A dedicated TAP device attached to the bridge - A static IP in the 172.30.0.0/24 network - Internet access via NAT - vsock for communication with the host