Skip to content

surajkumar/Ignition

Repository files navigation

Ignition

A Firecracker-based microVM platform in Java 25: boot VMs, snapshot them, and fork running state in milliseconds. Content-addressed snapshot storage, per-VM host networking, a vsock guest agent, a REST daemon, and a CLI, built without web frameworks on the JDK's own HTTP server with virtual threads.

Measured performance

Verified end to end against real Firecracker (KVM, 1 vCPU, 128MiB guests, Ubuntu 22.04 rootfs with the agent JVM inside):

Path Time What it includes
Cold boot to healthy agent 2083 ms Kernel boot (~150ms), systemd, agent JVM startup in the guest
Snapshot restore to healthy agent 91 ms Memory restored with the JVM already warm; 23x faster than cold boot

The restore path is the point of the platform: forking N copies of a running VM costs ~91ms each plus a disk copy, and concurrent forks of one snapshot are exercised both live (3 forks) and in the stub suite (50 forks on virtual threads, all unique IPs, all RUNNING within 5s).

Architecture

   ignitionctl (CLI, Picocli)    ignition-sdk (images + typed client)
                  \                    /
                   |       HTTP       |
                   v                  v
   ignition-api: IgnitionDaemon (JDK HttpServer, virtual threads)
     VmService / SnapshotService    problem+json, /metrics, state.json
        |                |                          |
        v                v                          v
 ignition-firecracker  ignition-registry      ignition-network
   FirecrackerHttpClient  SHA-256 blob store     IPAM (SQLite)
   VmLifecycleService     SQLite metadata        TAP + NAT via ip/iptables
   VsockServer            push/pull/fork/GC      rollback + teardown
        |                                            |
        v          all modules share                 v
   firecracker  <- ignition-domain (pure model) ->  host bridge
   processes        MicroVm, Snapshot, VmStatus
        |           lineage, NetworkConfig
        v  vsock
 ignition-agent (in-guest, Java 21, JNA, 2.6MB jar)
Module Role Details
ignition-domain Pure domain model, zero dependencies State machine, lineage resolution, validated records
ignition-firecracker VMM adapter HTTP/1.1 over Unix sockets, process launcher + disk staging, lifecycle orchestration, vsock client
ignition-registry Snapshot storage Content-addressed blobs, SQLite metadata, reference-counted GC
ignition-network Host networking IPAM, TAP devices, NAT, transactional setup
ignition-api Daemon + CLI REST API, services, config, graceful shutdown, ignitionctl
ignition-agent Guest agent vsock listener inside the VM, network/env/exec/health
ignition-sdk Deployment SDK Code-first ext4 image building (debugfs, no root), typed REST client
ignition-examples Runnable SDK examples Deploy loop, image init as code (python-base), fork farm

How to set up

Starting from a blank server (VirtualBox VM, cloud instance, bare metal)? One command sets up everything, KVM check to running daemon:

curl -fsSL https://raw.githubusercontent.com/surajkumar/Ignition/main/scripts/install.sh | sudo bash

docs/GETTING-STARTED.md explains what it does and walks the same path by hand: KVM/nested virtualization, assets, the ignition-base image (stock rootfs + Java runtime + guest agent, built without root by scripts/build-base-image.sh), the host bridge, the daemon, and a first deployed application. The sections below assume a working dev machine.

Prerequisites

  • JDK 25+ (the build targets --release 25; the agent targets 21)
  • Linux for anything that touches real VMs; the build and the 244-test suite run anywhere

Build and test

./gradlew build          # compile everything, run all 244 tests
./gradlew :ignition-api:ctlJar         # standalone ignitionctl jar
./gradlew :ignition-agent:fatJar       # guest agent jar (2.6MB)
./gradlew :ignition-sdk:sdkJar         # self-contained deployment SDK jar

No root, KVM, or Firecracker needed for any of the above: the entire platform is testable against in-memory stubs.

Run the daemon

./gradlew :ignition-api:run
# or build a distribution with start scripts:
./gradlew :ignition-api:installDist
ignition-api/build/install/ignition-api/bin/ignition-api

It binds 127.0.0.1:7777. Configure via system properties or an application.properties file (data dir, subnet, bridge, kernel and rootfs paths, Firecracker retry/timeout, shutdown grace); every key is documented in IgnitionConfig. Production use needs root (TAP/NAT), a host bridge, Firecracker on PATH, and a kernel plus agent-equipped rootfs, exactly as in the live test setup below.

Use the CLI

alias ignitionctl='java -jar ignition-api/build/libs/ignitionctl-1.0-SNAPSHOT.jar'

ignitionctl deploy --name billing --artifact app.jar --env APP_ENV=prod --run
ignitionctl ps
ignitionctl logs <vm-id> --unit billing
ignitionctl exec <vm-id> systemctl status billing
ignitionctl snapshot <vm-id> --name checkpoint
ignitionctl fork --vm <vm-id> --name clone-1
ignitionctl apps
ignitionctl push --mem vm.mem --disk vm.disk --name golden
ignitionctl run --snapshot golden --name worker-1
ignitionctl images --tree
ignitionctl pull <snapshot-id> --dest ./backups
ignitionctl kill <vm-id>                 # stop; record kept
ignitionctl rm <vm-id>                   # remove entirely (record + workspace)

Point it at a remote daemon with IGNITION_HOST=host:port.

Run the live tests (real Firecracker)

Requires Linux, KVM (/dev/kvm), and root. Three steps:

# 1. Fetch firecracker, a kernel, and a rootfs (idempotent, checksummed)
./scripts/download-test-assets.sh

# 2. Bake the guest agent + a jlink Java runtime into the rootfs
#    (exact validated commands in scripts/README.md)

# 3. Run
sudo JAVA_HOME=$JAVA_HOME ./gradlew liveTest

If anything is missing, the tests skip and print the exact fix. The suite cold-boots a VM, verifies the agent over vsock, snapshots, restores, forks concurrently, and proves host-to-guest networking, then cleans up TAPs, processes, and addresses even on failure. Full details in scripts/README.md.

Testing

  • 244 unit and integration tests run without root, KVM, or Firecracker (./gradlew test): wire-level VMM and vsock protocol tests against fake Unix-socket servers, full REST lifecycle over real HTTP, a 50-VM fork storm, registry round-trips, IPAM persistence, graceful shutdown, and SDK ext4 image round-trips via e2fsprogs (those two skip cleanly where it is not installed)
  • 3 live tests against real Firecracker (./gradlew liveTest), which caught a real bug the stubs could not: Firecracker ignores Connection: close and sends 204 without Content-Length, so a naive read-to-EOF hangs

Design notes

  • No Spring, no Quarkus: the daemon is com.sun.net.httpserver plus Jackson, one virtual thread per request
  • Errors are RFC 9457 problem+json; logs are structured JSON with vmId/snapshotId MDC; /metrics serves Prometheus text
  • Snapshots are content-addressed (SHA-256), so forks share blobs and deletion garbage-collects only unreferenced content
  • Each VM gets a working directory with cwd-relative disk and vsock paths, which is what lets many forks restore from one snapshot without the jailer
  • The guest agent avoids reflection and frameworks entirely to keep startup negligible and the jar at 2.6MB

About

No description, website, or topics provided.

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors