firecracker-shim Operations Guide
This guide covers the deployment, configuration, troubleshooting, and maintenance of the firecracker-shim runtime in production environments.
Architecture Overview
The runtime operates as a containerd shim (io.containerd.firecracker.v2). When Kubernetes creates a pod, the following happens:
- kubelet calls containerd (via CRI) to create a PodSandbox.
- containerd spawns a new instance of containerd-shim-fc-v2.
- The shim acquires a Firecracker microVM (from pool or new).
- Inside the VM, fc-agent starts and listens on vsock.
- Container operations (create, start, exec) are proxied to the agent.
Deployment Requirements
Host Requirements
- OS: Linux (kernel 4.14+)
- Virtualization: KVM enabled (
/dev/kvmaccessible) - vsock:
vhost_vsockkernel module loaded - containerd: Version 1.7+
- CNI Plugins: Standard plugins installed (
bridge,ptp,host-local, etc.)
Sizing Recommendations
| Component | CPU | Memory | Disk |
|---|---|---|---|
| Shim process | < 1% core | ~10MB | Negligible |
| Firecracker VMM | < 1% core (idle) | ~5MB | Negligible |
| Guest VM | 1+ vCPU | 64MB+ (configurable) | Rootfs size |
Recommended Host Config:
- Enable hugepages for better VM memory performance (optional)
- Use
mq-deadlineornoneI/O scheduler for backing files
Configuration
Configuration is loaded from /etc/fc-cri/config.toml.
VM Sizing
Adjust based on your workload needs:
[vm]
# Default vCPUs per VM
vcpu_count = 2
# Default memory per VM in MB
memory_mb = 256
# Minimum memory (if requested via pod resources)
min_memory_mb = 64
# Maximum memory cap
max_memory_mb = 4096
VM Pool Tuning
The pool significantly reduces cold start latency. Tuning depends on your pod churn rate.
[pool]
enabled = true
# Max VMs to keep warm (memory cost: ~size * memory_mb)
max_size = 20
# Min VMs to always have ready
min_size = 5
# Concurrency for warming (limit to avoid CPU spikes)
warm_concurrency = 4
Networking
The runtime supports standard CNI. The default setup uses a bridge.
Important: Ensure the subnet doesn't overlap with your host or pod network.
Security (Jailer)
For production, always enable the jailer.
[runtime]
enable_jailer = true
jailer_binary = "/usr/bin/jailer"
# UID/GID to run Firecracker as (must exist)
uid = 1000
gid = 1000
Prerequisites for Jailer:
- User
1000:1000exists /srv/jailerdirectory exists and is owned byroot:root- Cgroup v2 is recommended
Troubleshooting
Tools
The fcctl CLI is your primary troubleshooting tool.
# Check runtime health
sudo fcctl health
# List all sandboxes
sudo fcctl list
# Inspect specific sandbox
sudo fcctl inspect <sandbox-id>
Common Issues
1. Pods stuck in ContainerCreating
Symptoms: Pod status stays in ContainerCreating for >30s.
Checks:
- Check runtime health:
fcctl health - Check shim logs:
journalctl -u containerdor/var/lib/containerd/io.containerd.runtime.v2.task/.../log - Verify VM started:
fcctl list - Check agent connection:
fcctl inspect <id>
Possible Causes:
- KVM missing: Ensure
/dev/kvmexists and is accessible. - Kernel/Rootfs missing: Verify
/var/lib/fc-cri/vmlinuxexists. - vsock failure: Ensure
vhost_vsockmodule is loaded.
2. Network Connectivity Issues
Symptoms: Container cannot reach external network or other pods.
Checks:
- Check CNI bridge:
ip addr show fc-br0 - Check VM IP:
fcctl inspect <id> - Test from inside:
fcctl exec <id> ping 8.8.8.8
Possible Causes:
- IP exhaustion: Check CNI subnet size vs number of pods.
- Firewall: Ensure
iptablesallows forwarding onfc-br0.
3. High Host Memory Usage
Symptoms: Host OOM killer active.
Checks:
- Check pool size:
fcctl pool status - Check active VMs:
fcctl list | wc -l
Mitigation:
- Reduce pool size.
- Reduce default VM memory in
config.toml. - Enable memory overcommitment (ensure swap is available).
Monitoring
Prometheus Metrics
The runtime exposes metrics at :9090/metrics.
Key Metrics to Alert On:
| Metric | Condition | Severity | Description |
|---|---|---|---|
fc_cri_vm_create_errors_total |
rate > 0 | High | VM creation failing |
fc_cri_agent_connect_errors_total |
rate > 0 | High | Agent unreachable |
fc_cri_pool_available |
== 0 | Warning | Pool exhausted (latency impact) |
fc_cri_start_latency_p95_ms |
> 500ms | Warning | Slow startup |
Logging
Logs are written to stdout (captured by containerd) or a file.
Log Levels:
info: Normal operations (VM start/stop)warn: Retryable errors, resource pressureerror: Operational failures requiring attentiondebug: Detailed trace (verbose!)
Change level via environment variable for specific pods:
Upgrades
- Drain node:
kubectl drain <node> --ignore-daemonsets - Stop containerd:
systemctl stop containerd - Install new binaries:
make install - Update config: Check
config.tomlfor new options. - Start containerd:
systemctl start containerd - Uncordon node:
kubectl uncordon <node>
Note: Upgrading the shim binary does not affect running VMs. Only new pods will use the new shim version.
Disaster Recovery
Cleaning Orphaned Resources
If the shim crashes hard, it might leave VMs running or files on disk.
recovering from Bad State
If the runtime is completely stuck:
- Stop containerd:
systemctl stop containerd - Kill all Firecracker processes:
pkill firecracker - Remove runtime state:
rm -rf /run/fc-cri/* - Start containerd:
systemctl start containerd
Warning: This will kill all running pods on the node.
Advanced: Using a Custom Kernel
The default minimal kernel (~5MB) is optimized for speed and supports standard container workloads. However, it lacks support for advanced filesystems (XFS, ZFS), complex networking protocols (SCTP), or specific hardware drivers.
If your workload fails due to missing kernel features, you can swap in a standard kernel.
Steps:
- Obtain a Kernel: Compile your own or download an AWS Firecracker-compatible kernel (e.g., from the Firecracker CI artifacts or Amazon Linux 2 kernel).
- Place on Host: Copy the
vmlinuxfile to/var/lib/fc-cri/custom-vmlinux. - Update Config:
Edit
/etc/fc-cri/config.toml: - Restart: New pods will use the new kernel immediately. Existing pods (and pooled VMs) must be recycled.