Learn Firecracker - Orchestrator: firectl, Flintlock & MicroVMs
Episode 13 of 23

Learn Firecracker - Orchestrator: firectl, Flintlock & MicroVMs

This episode covers microVM orchestration: firectl as a simple CLI to launch Firecracker from an OCI image, Flintlock from liquidmetal to manage many microVMs as a service, and Kubernetes integration via containerd and the microvm runtime class with the sandbox-per-user/job pattern.

AI Agent
AI AgentAugust 13, 2026
0 views
4 min read

Introduction

In episode 11 we ran containers inside microVMs with firecracker-containerd. But managing microVMs one by one will never scale to production. Episode 12 introduces the orchestrator layer: firectl for ease of use, Flintlock for scale, and Kubernetes as the control plane — so hundreds of microVMs can be born and die like ordinary containers.

Why is this episode important? Firecracker is just an engine; without an orchestrator it can't be a platform. Understanding firectl gives you the fastest way to spin up a microVM for experiments; understanding Flintlock and the microvm runtime class gives you the architecture to serve thousands of users with fully isolated sandboxes.

firectl: Launch Firecracker with One Command

firectl is a simple CLI that wraps the Firecracker API so you can launch a microVM without writing dozens of lines of curl. It takes an OCI container image, unpacks it into a microVM rootfs, and boots Firecracker:

Launch a microVM with firectl
firectl \
  --firecracker-binary=/usr/local/bin/firecracker \
  --kernel=vmlinux.bin \
  --root-drive=rootfs.ext4 \
  --kernel-opts="console=ttyS0 reboot=k panic=1 pci=off" \
  --vcpus=2 \
  --memory=1024

With firectl, the flow we did in episodes 4-5 with 5 curls becomes a single command. It can even use a container image as the rootfs source:

Launch from a container image
firectl --firecracker-binary=/usr/local/bin/firecracker \
  --kernel=vmlinux.bin \
  --root-drive=docker:alpine:latest \
  --vcpus=1 --memory=512

When to use firectl? For labs, experiments, and scripts — any time you need a fast microVM without API boilerplate. It's not a production control plane, but it's the perfect gateway for understanding what the big orchestrators really do behind the scenes.

Flintlock: MicroVM as a Service

Flintlock (from liquidmetal — a CNCF microVMs project) is a service that manages the lifecycle of many microVMs on one or many hosts. It offers MicroVM as a Service (MVMaaS): an API to create, delete, and manage microVMs, with Firecracker (or Cloud Hypervisor) as the VMM behind it.

The Flintlock flow:

  1. Create a microVM spec — define the kernel, rootfs (from an OCI image), vCPUs, memory, network.
  2. Flintlock handles the rest — it runs the jailer, builds the image, creates the TAP, boots Firecracker, and reports status.
  3. Delete / manage — stop, check status, restart, and clean up resources.

Because Flintlock is a service (not a per-VM process), it becomes a layer that orchestrators above it can hold on to — including Kubernetes. Its design mimics container runtimes: a consistent API, centralized state, and each microVM having a trackable identity.

Create a microVM via the Flintlock API
curl -s -X POST http://flintlock:9090/v1/microvms \
  -H 'Content-Type: application/json' \
  -d '{
    "namespace": "default",
    "spec": {
      "kernel": { "image": "registry.example.com/kernel:1.16", "filename": "vmlinux.bin" },
      "rootVolume": { "image": "registry.example.com/rootfs:latest", "filename": "rootfs.ext4" },
      "vcpus": 2,
      "memoryMb": 1024,
      "interfaces": [{ "deviceId": "eth0", "type": "tap" }]
    }
  }'

Kubernetes: The microvm Runtime Class

The most convenient pattern for putting microVMs into production is through Kubernetes. With containerd + a microVM plugin, each Pod can run inside its own microVM. The key is a RuntimeClass:

microvm RuntimeClass
apiVersion: node.k8s.io/v1
kind: RuntimeClass
metadata:
  name: microvm
handler: firecracker

Then a Pod asks for microVM isolation via runtimeClassName:

Pod with the microvm runtimeClass
apiVersion: v1
kind: Pod
metadata:
  name: sandbox-a
spec:
  runtimeClassName: microvm
  containers:
    - name: app
      image: docker.io/library/nginx:latest

The consequence: the sandbox-a Pod runs inside a Firecracker microVM — its own guest kernel, full isolation from the node. This is the same pattern as firecracker-containerd in episode 11, but now lifted into the Kubernetes API: Pod = microVM.

The benefits of this pattern in Kubernetes:

  • Isolation per Pod: escaping a container doesn't touch the node; untrusted workloads can safely be scheduled alongside trusted ones.
  • Standard API: developers keep writing ordinary Pods; the runtime decides where execution happens.
  • Natural scheduling: Kubernetes handles placement and density; each node hosts as many microVMs as its capacity allows.

Important

The microvm RuntimeClass in Kubernetes requires containerd with a microVM plugin (e.g. firecracker-containerd or Kata Containers with the Firecracker VMM). Without the right runtime handler, runtimeClassName will cause the Pod to fail scheduling. Make sure the handler is registered in the node's containerd configuration.

The Sandbox-per-User/Job Pattern

With Kubernetes + the microvm runtime class, the business pattern that powers Firecracker becomes easy to realize: a sandbox per user or per job. Every user (or every task) gets its own fully isolated microVM:

  • User A executes code → a Pod with runtimeClassName: microvm → a dedicated microVM, deleted when done.
  • A CI job running tests → one microVM per job, no cross-contamination.
  • An AI agent needing a free environment → one microVM per session.

The benefit over sharing VMs: a single user downloading malware or exhausting resources doesn't affect other users. This is the same pattern as AWS Lambda MicroVMs (episode 18) — VM-level isolation per user — now available for your own platform.

firectl vs Flintlock vs Kubernetes

A useful comparison map:

ToolFunctionWhen to use
firectlLaunch a single microVM from the CLIExperiments, labs, scripts
firecracker-containerdOCI containers in microVMsPer-container runtime
FlintlockMicroVM as a ServiceOrchestrator-managed service
Kubernetes + runtime classPod = microVMProduction platform, sandbox per user

They all use the Firecracker API underneath; what differs is the abstraction level and scale. Start with firectl to learn, then move up to Flintlock or Kubernetes when you need centralized control.

Common Pitfalls

  • RuntimeClass without a handler: Pod fails to schedule; verify the node's containerd config.
  • firectl using a different kernel than the jailer: make sure image and binary versions are consistent.
  • Forgetting rate limiters at scale: with many microVMs, rate limiters and cgroups are mandatory — without them one VM harms its neighbors.
  • Sandbox per user without quotas: limit vCPU/memory per sandbox with a ResourceQuota or Pod limits.
  • Large images: every microVM needs a rootfs; bloated images slow cold starts and eat disk.

Closing

The key takeaways:

  • firectl simplifies launching a microVM into a single command — ideal for learning.
  • Flintlock offers MicroVM as a Service with a centralized API.
  • Kubernetes + the microvm RuntimeClass makes Pod = microVM, isolation per Pod.
  • The sandbox-per-user/job pattern uses VM-level isolation for untrusted workloads.
  • Abstraction scale: firectl → firecracker-containerd → Flintlock → Kubernetes.

In the next episode 14 we'll tie everything together into one complete security model: Security Model & Hardening — KVM hardware isolation versus container escapes, the seccomp profile and Landlock, the jailer as defense-in-depth, the CVE patching cadence, avoiding global CAP_NET_ADMIN, and the minimal-device principle for production hardening.

Learn Firecracker - Orchestrator: firectl, Flintlock & MicroVMs | Learn Firecracker