Skip to content

Commit 9261a62

Browse files
committed
update firecracker
1 parent 25b1710 commit 9261a62

2 files changed

Lines changed: 681 additions & 1 deletion

File tree

virtualization/README.md

Lines changed: 309 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1005,6 +1005,8 @@ AWS needed a solution that offered the hardware-level security of a VM with the
10051005
10061006
#### 5.2.2. How Firecracker works
10071007
1008+
Source: <https://github.com/firecracker-microvm/firecracker/blob/main/docs/design.md>
1009+
10081010
Firecracker aims to provide VM-level isolation guarantees and solve three challenges associated with virtualization. These are:
10091011
10101012
1. VMM and the kernel have high CPU and memory overhead for VMs.
@@ -1018,18 +1020,324 @@ AWS solves the challenges by keeping Linux KVM, but swapping QEMU with a super l
10181020
- Device emulation for disk, networking, and serial console (keyboard)
10191021
- REST based configuration API to configure, manage, start and stop MicroVMs. This replaces some of the functionality offered by libvirt.
10201022
- Rate limiting for network and disk. Can configure throughput and request rates. For this Firecracker implements its own solution for simplicity, rather than using cgroups
1021-
- Firecracker also provides a metadata service that securely shares configuration information between the host and guest operating system.
1023+
- Firecracker also provides a metadata service - MicroVM-Metadata Service (MMDS) that securely shares configuration information between the host and guest operating system.
10221024
10231025
![](https://firecracker-microvm.github.io/img/diagram-desktop@3x.png)
10241026
10251027
For network and block devices, Firecracker uses `virtio` (specifically virtio-net for networking, virtio-block for storage, and virtio-vsock for socket communication). Virtio provides an open API for exposing emulated devices from hypervisors. Virtio is simple, scalable, and offers good performance through its use of paravirtualization.
10261028
1029+
![firacracker host integration](https://github.com/firecracker-microvm/firecracker/blob/main/docs/images/firecracker_host_integration.png?raw=true)
1030+
10271031
On the networking side, Firecracker uses a TAP virtual network interface and encapsulates the guest OS (and the TAP device) inside their own network namespace.
10281032
10291033
For storage, AWS chooses to support block devices, rather than filesystem passthrough, as a security consideration. Filesystems are large and complex code bases, and providing only block IO to the guest protects a substantial part of the host kernel surface area.
10301034
10311035
Finally, Firecracker also has a jailer around it to provide an additional level of protection against unwanted VMM behavior (such as a bug). The jailer implements a restrictive sandbox around the guest by using a set of Linux primitives. These include chroot, pid, and network namespaces. The jailer also uses seccomp-bpf to whitelist the set of system calls that can drop to the host. This, rather than using libvirt as the jailer, also diverges from Red Hat’s architecture.
10321036
1037+
**Threat containment**
1038+
1039+
From a security perspective, all vCPU threads are considered to be running malicious code as soon as they have been started; these malicious threads need to be contained. Containment is achieved by nesting several trust zones which increment from least trusted or least safe (guest vCPU threads) to most trusted or safest (host). These trusted zones are separated by barriers that enforce aspects of Firecracker security. For example, all outbound network traffic data is copied by the Firecracker I/O thread from the emulated network interface to the backing host TAP device, and I/O rate limiting is applied at this point. These barriers are marked in the diagram below.
1040+
1041+
![firecracker threat containment](https://github.com/firecracker-microvm/firecracker/raw/main/docs/images/firecracker_threat_containment.png?raw=true)
1042+
1043+
#### 5.2.3. Hands-on guide
1044+
1045+
Source: <https://github.com/firecracker-microvm/firecracker/blob/main/docs/getting-started.md>
1046+
1047+
To fully master Firecracker, you must understand both the user-space operations (interacting with its REST API) and the host-space operations (how KVM and the Linux kernel partition resources).
1048+
1049+
This guide provides a comprehensive, production-style walkthrough to configure, network, boot, and analyze a Firecracker microVM using the exact assets and versions from the official repository. It is taken from Firecracker getting started guide
1050+
1051+
**Step 1: Environment Verification & Hardware Virtualization**
1052+
1053+
Firecracker relies on the Linux Kernel-based Virtual Machine (KVM) subsystem. It uses hardware execution blocks (Intel VT-x or AMD-V) to run guest code directly on the host CPU.
1054+
1055+
```sh
1056+
#!/bin/bash
1057+
set -euo pipefail
1058+
1059+
echo "==> Verifying KVM virtualization support..."
1060+
if ! lsmod | grep -q kvm; then
1061+
echo "ERROR: KVM kernel module is not loaded. Ensure hardware virtualization is enabled in BIOS." >&2
1062+
exit 1
1063+
fi
1064+
1065+
echo "==> Configuring permissions for /dev/kvm..."
1066+
# Check if current user has RW access to KVM character device
1067+
if [ ! -r /dev/kvm ] || [ ! -w /dev/kvm ]; then
1068+
echo "Current user lacks permissions for /dev/kvm. Adjusting via group management..."
1069+
if [ "$(stat -c "%G" /dev/kvm)" = "kvm" ]; then
1070+
sudo usermod -aG kvm "${USER}"
1071+
echo "SUCCESS: User added to 'kvm' group. Please log out and back in for changes to apply."
1072+
else
1073+
echo "Fallback: Granting access via Access Control Lists (ACL)..."
1074+
sudo setfacl -m u:${USER}:rw /dev/kvm
1075+
fi
1076+
else
1077+
echo "KVM Permissions: OK"
1078+
fi
1079+
```
1080+
1081+
When the KVM module is active, it exposes `/dev/kvm`. Firecracker uses this file descriptor to perform setup actions via ioctl system calls. When a microVM runs, the physical CPU core transitions out of host execution mode (Root Mode) into guest execution mode (Non-Root Mode). The guest OS runs at ring 0 inside its isolated hardware execution context.
1082+
1083+
**Step 2: Asset Provisioning & Rootfs Construction**
1084+
1085+
Instead of multi-gigabyte ISO files or complex disk partition maps, Firecracker requires exactly two raw components: an uncompressed raw Linux kernel image (vmlinux) and a linear ext4 filesystem image.
1086+
1087+
Execute this script to download the exact latest binaries from the Firecracker CI pipeline, generate custom SSH keys, and provision a mountable loop device to inject credentials directly into the root filesystem:
1088+
1089+
```sh
1090+
#!/bin/bash
1091+
set -euo pipefail
1092+
1093+
ARCH="$(uname -m)"
1094+
RELEASE_URL="https://github.com/firecracker-microvm/firecracker/releases"
1095+
LATEST_TAG=$(basename "$(curl -fsSLI -o /dev/null -w "%{url_effective}" ${RELEASE_URL}/latest)")
1096+
CI_VERSION=${LATEST_TAG%.*}
1097+
1098+
echo "==> Downloading Firecracker ${LATEST_TAG} binary..."
1099+
curl -L "${RELEASE_URL}/download/${LATEST_TAG}/firecracker-${LATEST_TAG}-${ARCH}.tgz" | tar -xz
1100+
mv "release-${LATEST_TAG}-${ARCH}/firecracker-${LATEST_TAG}-${ARCH}" firecracker
1101+
rm -rf "release-${LATEST_TAG}-${ARCH}"
1102+
chmod +x firecracker
1103+
1104+
echo "==> Fetching latest compatible upstream guest kernel image..."
1105+
KERNEL_KEY=$(curl -s "http://spec.ccfc.min.s3.amazonaws.com/?prefix=firecracker-ci/$CI_VERSION/$ARCH/vmlinux-&list-type=2" \
1106+
| grep -oP "(?<=<Key>)(firecracker-ci/$CI_VERSION/$ARCH/vmlinux-[0-9]+\.[0-9]+\.[0-9]{1,3})(?=</Key>)" \
1107+
| sort -V | tail -1)
1108+
wget -O vmlinux "https://s3.amazonaws.com/spec.ccfc.min/${KERNEL_KEY}"
1109+
1110+
echo "==> Fetching guest Ubuntu rootfs container..."
1111+
UBUNTU_KEY=$(curl -s "http://spec.ccfc.min.s3.amazonaws.com/?prefix=firecracker-ci/$CI_VERSION/$ARCH/ubuntu-&list-type=2" \
1112+
| grep -oP "(?<=<Key>)(firecracker-ci/$CI_VERSION/$ARCH/ubuntu-[0-9]+\.[0-9]+\.squashfs)(?=</Key>)" \
1113+
| sort -V | tail -1)
1114+
UBUNTU_VER=$(basename "$UBUNTU_KEY" .squashfs | grep -oE '[0-9]+\.[0-9]+')
1115+
wget -O "ubuntu-${UBUNTU_VER}.squashfs.upstream" "https://s3.amazonaws.com/spec.ccfc.min/${UBUNTU_KEY}"
1116+
1117+
echo "==> Unpacking filesystem and inject credentials..."
1118+
rm -rf squashfs-root
1119+
unsquashfs "ubuntu-${UBUNTU_VER}.squashfs.upstream"
1120+
1121+
# Generate non-interactive SSH Key pair
1122+
rm -f microvm_key*
1123+
ssh-keygen -f microvm_key -N "" -t rsa -b 4096
1124+
mkdir -p squashfs-root/root/.ssh
1125+
cp microvm_key.pub squashfs-root/root/.ssh/authorized_keys
1126+
chmod 700 squashfs-root/root/.ssh
1127+
chmod 600 squashfs-root/root/.ssh/authorized_keys
1128+
1129+
echo "==> Compiling optimized raw ext4 filesystem disk block..."
1130+
sudo chown -R root:root squashfs-root
1131+
truncate -s 1G rootfs.ext4
1132+
sudo mkfs.ext4 -d squashfs-root -F rootfs.ext4
1133+
sudo chown "${USER}:${USER}" rootfs.ext4
1134+
1135+
echo "==> Cleanup intermediate directories..."
1136+
sudo rm -rf squashfs-root
1137+
echo "Assets prepared successfully."
1138+
```
1139+
1140+
**Step 3: Configuring Host-Side Networking**
1141+
1142+
Firecracker does not implement a virtual network switch. It relies on a paravirtualized network layer (`virtio-net`) linked directly to a Linux TAP interface on the host machine.
1143+
1144+
Run the following configuration block to create the network tunnel, establish a network bridge space, and set up network address translation (NAT) to route the guest's outbound Internet traffic through your primary network card:
1145+
1146+
```sh
1147+
#!/bin/bash
1148+
set -euo pipefail
1149+
1150+
TAP_DEV="tap0"
1151+
TAP_IP="172.16.0.1"
1152+
GUEST_IP="172.16.0.2"
1153+
NETMASK_SHORT="/30"
1154+
1155+
echo "==> Tearing down old interface states if present..."
1156+
sudo ip link del "$TAP_DEV" 2>/dev/null || true
1157+
1158+
echo "==> Initializing virtual TAP interface..."
1159+
sudo ip tuntap add dev "$TAP_DEV" mode tap
1160+
sudo ip addr add "${TAP_IP}${NETMASK_SHORT}" dev "$TAP_DEV"
1161+
sudo ip link set dev "$TAP_DEV" up
1162+
1163+
echo "==> Provisioning Host Kernel routing matrices..."
1164+
sudo sh -c "echo 1 > /proc/sys/net/ipv4/ip_forward"
1165+
1166+
# Clear conflicting old rules and establish NAT Masquerading
1167+
HOST_INTERFACE=$(ip -j route list default | grep -oP '(?<="dev":")[^"]+')
1168+
sudo iptables -P FORWARD ACCEPT
1169+
sudo iptables -t nat -D POSTROUTING -o "$HOST_INTERFACE" -j MASQUERADE 2>/dev/null || true
1170+
sudo iptables -t nat -A POSTROUTING -o "$HOST_INTERFACE" -j MASQUERADE
1171+
1172+
echo "Host Network Matrix Initialized. Topology: Host [${TAP_IP}] <---> Guest [${GUEST_IP}]"
1173+
```
1174+
1175+
**Step 4: The REST API Interactive Bootstrap Guide**
1176+
1177+
With your assets compiled and network tunnels listening, you can configure your MicroVM. Firecracker acts as an HTTP server bound to a local Unix Domain Socket file descriptor.
1178+
1179+
To visualize how these configuration inputs assemble your execution state, use the interactive panel below to select resources, view real-time API schema updates, and track the internal VMM state transitions.
1180+
1181+
**Step 5: Manual Orchestration and Connection**
1182+
1183+
If you want to spin up the machine manually using individual API endpoints, execute the following shell script. It pipes sequential configuration parameters directly into Firecracker's listening socket file descriptor:
1184+
1185+
```sh
1186+
#!/bin/bash
1187+
set -euo pipefail
1188+
1189+
SOCKET="/tmp/firecracker.socket"
1190+
sudo rm -f "$SOCKET"
1191+
1192+
echo "==> Initializing Firecracker core listener process in background..."
1193+
sudo ./firecracker --api-sock "$SOCKET" > firecracker.log 2>&1 &
1194+
FIRECRACKER_PID=$!
1195+
1196+
# Ensure cleanup on terminal termination
1197+
trap 'sudo kill -9 $FIRECRACKER_PID 2>/dev/null || true' EXIT
1198+
1199+
echo "==> Waiting for socket allocation..."
1200+
while [ ! -S "$SOCKET" ]; do sleep 0.1; done
1201+
1202+
echo "==> 1. Binding Guest Compute Engine configuration..."
1203+
sudo curl -X PUT --unix-socket "$SOCKET" \
1204+
--data '{
1205+
"vcpu_count": 2,
1206+
"mem_size_mib": 512
1207+
}' "http://localhost/machine-config"
1208+
1209+
echo "==> 2. Registering Uncompressed Kernel Image payload..."
1210+
sudo curl -X PUT --unix-socket "$SOCKET" \
1211+
--data '{
1212+
"kernel_image_path": "vmlinux",
1213+
"boot_args": "console=ttyS0 reboot=k panic=1 pci=off"
1214+
}' "http://localhost/boot-source"
1215+
1216+
echo "==> 3. Mapping raw ext4 linear block root storage drive..."
1217+
sudo curl -X PUT --unix-socket "$SOCKET" \
1218+
--data '{
1219+
"drive_id": "rootfs",
1220+
"path_on_host": "rootfs.ext4",
1221+
"is_root_device": true,
1222+
"is_read_only": false
1223+
}' "http://localhost/drives/rootfs"
1224+
1225+
echo "==> 4. Linking paravirtualized network abstraction boundary..."
1226+
sudo curl -X PUT --unix-socket "$SOCKET" \
1227+
--data '{
1228+
"iface_id": "net1",
1229+
"guest_mac": "06:00:AC:10:00:02",
1230+
"host_dev_name": "tap0"
1231+
}' "http://localhost/network-interfaces/net1"
1232+
1233+
echo "==> 5. Instantiating MicroVM (Triggering KVM Hardware Execution)..."
1234+
sudo curl -X PUT --unix-socket "$SOCKET" \
1235+
--data '{
1236+
"action_type": "InstanceStart"
1237+
}' "http://localhost/actions"
1238+
1239+
echo "==> VM execution initiated. Establishing SSH control connection..."
1240+
sleep 1.5
1241+
1242+
# Provision network address and gateway inside guest space via automated SSH injections
1243+
sudo ssh -i microvm_key -o StrictHostKeyChecking=no root@172.16.0.2 "ip route add default via 172.16.0.1 dev eth0; echo 'nameserver 8.8.8.8' > /etc/resolv.conf"
1244+
1245+
echo "==> Connecting to interactive session. Type 'reboot' to terminate microVM securely."
1246+
sudo ssh -i microvm_key -o StrictHostKeyChecking=no root@172.16.0.2
1247+
```
1248+
1249+
When configuring and running your microVM, Firecracker performs several key memory and input/output (I/O) setup actions behind the scenes:
1250+
1251+
```text
1252+
+-----------------------------------------------------------------------+
1253+
| HOST MACHINE |
1254+
| |
1255+
| +---------------------------+ +-----------------------------+ |
1256+
| | Firecracker Process | | Host Linux Kernel | |
1257+
| | (User Space, Rust) | | (Kernel Space) | |
1258+
| | | | | |
1259+
| | +---------------------+ | | +-----------------------+ | |
1260+
| | | API Listener Thread | | | | KVM Subsystem | | |
1261+
| | +---------------------+ | | +-----------------------+ | |
1262+
| | | | ^ | |
1263+
| | +---------------------+ | | | | |
1264+
| | | VMM Thread |--|-------|--------------+ | |
1265+
| | +---------------------+ | | ioctl system calls | |
1266+
| | | | | |
1267+
| | +---------------------+ | | +-----------------------+ | |
1268+
| | | vCPU Threads |--|-------|--|--> KVM_RUN | | |
1269+
| | +---------------------+ | | +-----------------------+ | |
1270+
| +--|------------------------+ +-----------------------------+ |
1271+
| | |
1272+
| | mmap() |
1273+
| v |
1274+
| +-----------------------------------------------------------------+ |
1275+
| | Host RAM (Allocated Address Space) | |
1276+
| | | |
1277+
| | +-----------------------------------------------------------+ | |
1278+
| | | GUEST MICROVM | | |
1279+
| | | | | |
1280+
| | | +----------------------+ +----------------------+ | | |
1281+
| | | | Guest OS Kernel | | Shared Memory | | | |
1282+
| | | | (Direct Kernel Boot) | | Virtqueues | | | |
1283+
| | | +----------------------+ +----------------------+ | | |
1284+
| | +-----------------------------------------------------------+ | |
1285+
| +-----------------------------------------------------------------+ |
1286+
+-----------------------------------------------------------------------+
1287+
```
1288+
1289+
- Memory mapping via `mmap`:
1290+
- When the `mem_size_mib` value is parsed from your JSON configuration, Firecracker calls `mmap` to allocate that exact amount of continuous virtual memory from the host system.
1291+
- This entire block is registered with KVM using the `KVM_SET_USER_MEMORY_REGION` system call. The guest operating system treats this mapped address space as its raw physical memory layout.
1292+
- Zero-copy storage and ring buffers: Firecracker avoids the overhead of traditional hardware storage emulation. Instead, it uses VirtIO shared-memory ring buffers (Virtqueues). When the guest operating system writes data to disk:
1293+
- The guest kernel writes the data block into a memory page shared with the host.
1294+
- The guest registers the write request inside the descriptor ring buffer.
1295+
- The guest vCPU signals Firecracker by executing an I/O instruction, which triggers a hardware-level exit (VMExit).
1296+
- The host KVM module catches the exit event and passes control to the Firecracker VMM thread using a fast Linux `eventfd` notification.
1297+
- Firecracker reads the data directly out of host memory and writes it to the backing file (`rootfs.ext4`) on the host filesystem. This process bypasses complex emulation code layers, maximizing I/O performance.
1298+
1299+
**Step 6: Production Scaling (Using Declarative Blueprints)**
1300+
1301+
To scale workloads, bypassing individual HTTP calls avoids network overhead. Firecracker can process a single declarative configuration file during startup.
1302+
1303+
Save this file as `vm_config.json`:
1304+
1305+
```json
1306+
{
1307+
"boot-source": {
1308+
"kernel_image_path": "vmlinux",
1309+
"boot_args": "console=ttyS0 reboot=k panic=1 pci=off"
1310+
},
1311+
"drives": [
1312+
{
1313+
"drive_id": "rootfs",
1314+
"path_on_host": "rootfs.ext4",
1315+
"is_root_device": true,
1316+
"is_read_only": false
1317+
}
1318+
],
1319+
"network-interfaces": [
1320+
{
1321+
"iface_id": "net1",
1322+
"guest_mac": "06:00:AC:10:00:02",
1323+
"host_dev_name": "tap0"
1324+
}
1325+
],
1326+
"machine-config": {
1327+
"vcpu_count": 2,
1328+
"mem_size_mib": 512,
1329+
"smt": false
1330+
}
1331+
}
1332+
```
1333+
1334+
To execute this microVM using your configuration blueprint, simply run:
1335+
1336+
```sh
1337+
sudo rm -f /tmp/firecracker.socket
1338+
sudo ./firecracker --api-sock /tmp/firecracker.socket --config-file vm_config.json
1339+
```
1340+
10331341
### 5.3. Cloud hypervisor
10341342
10351343
---

0 commit comments

Comments
 (0)