Host Deployment and Native Smoke Testing¶
This guide first downloads artifacts on a networked workstation, then transfers them to an isolated Linux node. The commands in this document deliberately do not depend on any specific jump host, cluster name, image registry, or code repository.
1. Environment Requirements¶
The host must be Linux running on x86_64 or aarch64, with KVM enabled, and read/write access to /dev/kvm. Network testing also requires /dev/net/tun.
Run the following checks on the host:
uname -m
uname -r
getconf PAGESIZE
systemd-detect-virt || true
ls -l /dev/kvm /dev/net/tun
awk -F: '/^flags/ {
if ($2 ~ /(^| )vmx( |$)/) print "virtualization=vmx"
else if ($2 ~ /(^| )svm( |$)/) print "virtualization=svm"
else print "virtualization=missing"
exit
}' /proc/cpuinfo
Expected results include x86_64 or aarch64, an existing /dev/kvm, and vmx or svm. Firecracker explicitly requires read/write access to /dev/kvm.
2. Download on a Networked Workstation¶
Pin a specific version; do not follow an unversioned latest URL:
FC_VERSION=v1.16.1
FC_ARCH=x86_64
WORK_DIR=/tmp/firecracker-download
mkdir -p "${WORK_DIR}"
curl -fL --retry 3 \
-o "${WORK_DIR}/firecracker-${FC_VERSION}-${FC_ARCH}.tgz" \
"https://github.com/firecracker-microvm/firecracker/releases/download/${FC_VERSION}/firecracker-${FC_VERSION}-${FC_ARCH}.tgz"
curl -fL --retry 3 \
-o "${WORK_DIR}/firecracker-${FC_VERSION}-${FC_ARCH}.tgz.sha256.txt" \
"https://github.com/firecracker-microvm/firecracker/releases/download/${FC_VERSION}/firecracker-${FC_VERSION}-${FC_ARCH}.tgz.sha256.txt"
cd "${WORK_DIR}"
sha256sum -c "firecracker-${FC_VERSION}-${FC_ARCH}.tgz.sha256.txt"
The Firecracker project provides quick-start artifacts suitable for one-off smoke testing:
curl -fL --retry 10 --retry-all-errors \
-o "${WORK_DIR}/vmlinux.bin" \
https://s3.amazonaws.com/spec.ccfc.min/img/quickstart_guide/x86_64/kernels/vmlinux.bin
curl -fL --retry 10 --retry-all-errors \
-o "${WORK_DIR}/rootfs.ext4" \
https://s3.amazonaws.com/spec.ccfc.min/img/quickstart_guide/x86_64/rootfs/bionic.rootfs.ext4
sha256sum "${WORK_DIR}/vmlinux.bin" "${WORK_DIR}/rootfs.ext4"
The quick-start guest is older and is only used to prove that the VMM path works. Before production use, build and continuously patch a maintained guest kernel and root filesystem.
3. Transfer to the Isolated Node¶
Use whatever transfer method is available in the environment. Standard scp through a jump host is sufficient; if only the Kubernetes API can reach the node, use the bundled artifact transfer Pod:
- In
manifests/artifact-transfer.yaml, replaceworker-firecracker. - Confirm that the referenced small container image is already cached or synced to the internal network.
- Apply the manifest and stream the files through the Kubernetes API.
kubectl apply -f manifests/artifact-transfer.yaml
kubectl wait --for=condition=Ready \
pod/firecracker-artifact-transfer -n kube-system --timeout=90s
kubectl exec -n kube-system firecracker-artifact-transfer -- \
mkdir -p /host-lab/artifacts
kubectl cp "${WORK_DIR}/firecracker-${FC_VERSION}-${FC_ARCH}.tgz" \
kube-system/firecracker-artifact-transfer:/host-lab/
kubectl cp "${WORK_DIR}/firecracker-${FC_VERSION}-${FC_ARCH}.tgz.sha256.txt" \
kube-system/firecracker-artifact-transfer:/host-lab/
kubectl cp "${WORK_DIR}/vmlinux.bin" \
kube-system/firecracker-artifact-transfer:/host-lab/artifacts/vmlinux.bin
kubectl cp "${WORK_DIR}/rootfs.ext4" \
kube-system/firecracker-artifact-transfer:/host-lab/artifacts/rootfs.ext4
kubectl delete pod firecracker-artifact-transfer \
-n kube-system --wait=true
Although the transfer Pod does not set securityContext.privileged, it should still be treated as a privileged workload because of its node placement and hostPath access. Delete it immediately after the copy completes.
4. Install to an Isolated Experiment Directory¶
Run on the node:
FC_VERSION=v1.16.1
FC_ARCH=x86_64
LAB_DIR=/opt/firecracker-lab
sudo mkdir -p "${LAB_DIR}/bin" "${LAB_DIR}/artifacts" \
"${LAB_DIR}/run" "${LAB_DIR}/results"
cd "${LAB_DIR}"
sha256sum -c "firecracker-${FC_VERSION}-${FC_ARCH}.tgz.sha256.txt"
tar -xzf "firecracker-${FC_VERSION}-${FC_ARCH}.tgz"
sudo install -m 0755 \
"release-${FC_VERSION}-${FC_ARCH}/firecracker-${FC_VERSION}-${FC_ARCH}" \
"${LAB_DIR}/bin/firecracker"
sudo install -m 0755 \
"release-${FC_VERSION}-${FC_ARCH}/jailer-${FC_VERSION}-${FC_ARCH}" \
"${LAB_DIR}/bin/jailer"
"${LAB_DIR}/bin/firecracker" --version
"${LAB_DIR}/bin/jailer" --version
sudo e2fsck -fn "${LAB_DIR}/artifacts/rootfs.ext4"
Keep the VMM, images, mutable disks, and results in separate locations. Never start the base rootfs in writable mode; always make a copy for each test.
5. Native Boot and API Testing¶
Copy configs/native-smoke.json to /opt/firecracker-lab/run/smoke-config.json, then run:
LAB_DIR=/opt/firecracker-lab
cd "${LAB_DIR}"
cp --reflink=auto --sparse=always \
artifacts/rootfs.ext4 run/rootfs-smoke.ext4
bin/firecracker \
--api-sock "${LAB_DIR}/run/firecracker.socket" \
--config-file "${LAB_DIR}/run/smoke-config.json" \
>"${LAB_DIR}/results/native-console.log" 2>&1 &
curl --unix-socket "${LAB_DIR}/run/firecracker.socket" \
http://localhost/version
curl --unix-socket "${LAB_DIR}/run/firecracker.socket" \
http://localhost/
tail -40 "${LAB_DIR}/results/native-console.log"
Successful output should include state: Running, followed by the guest login prompt. Request a graceful shutdown through the API:
curl -X PUT \
--unix-socket /opt/firecracker-lab/run/firecracker.socket \
-H 'Content-Type: application/json' \
-d '{"action_type":"SendCtrlAltDel"}' \
http://localhost/actions
An HTTP 204 response and the VMM process exiting indicate a graceful shutdown.
6. TAP Network Testing¶
Copy configs/network-smoke.json to the experiment run directory. The example rootfs maps MAC 06:00:AC:10:00:02 to guest address 172.16.0.2.
sudo ip tuntap add dev fc-tap0 mode tap
sudo ip addr add 172.16.0.1/30 dev fc-tap0
sudo ip link set dev fc-tap0 up
cp --reflink=auto --sparse=always \
/opt/firecracker-lab/artifacts/rootfs.ext4 \
/opt/firecracker-lab/run/rootfs-network.ext4
/opt/firecracker-lab/bin/firecracker \
--api-sock /opt/firecracker-lab/run/firecracker-network.socket \
--config-file /opt/firecracker-lab/run/network-config.json \
>/opt/firecracker-lab/results/network-console.log 2>&1 &
ping -c 3 172.16.0.2
timeout 2 bash -c '</dev/tcp/172.16.0.2/22'
This only verifies host-to-guest networking. Guest access to external networks additionally requires explicit forwarding/NAT or routed network policy configuration. Do not silently modify the host's global forwarding or firewall defaults for the sake of a smoke test.
After shutdown, delete only the interfaces created by this experiment:
7. Gaps Compared to Production¶
For observability, the smoke test commands run the VMM directly. A production design must invoke the version-matched jailer, use dedicated non-privileged UID/GID, prevent non-privileged users from writing to the jail input, restrict cgroups and resources, and fully manage network namespaces and disk cleanup. See the official production host configuration guide.