Skip to main content

Requirements#

  • Linux amd64 / x86_64 host with KVM — same ISA (amd64 is the Debian name; release tarballs use x86_64). /dev/kvm must exist. Bare metal or a cloud instance with nested virtualization both work. k7d does not build or run on macOS / Windows / ARM.
  • /dev/vhost-vsock, /dev/net/tun, and cgroup v2 — the daemon talks to guest agents over vsock, gives each VM a TAP, and jails each tree in a cgroup.
  • root — the daemon manages TAP devices, bridges, nftables, and /run/k7d/.
  • Optional: k3s, if you want pods scheduled as k7d microVMs via runtimeClassName: k7.
  • Optional: the pinned Firecracker + jailer (utils/install-firecracker.sh, v1.16.2, sha-verified) if you want the k7-fc backend.

k7d doctor runs exactly these checks without starting a daemon:

Exit code is non-zero on any FAIL.

The same report is available on the socket as {"op":"doctor"} — see the Daemon API.

Five-minute quickstart#

From a clone or a clean box:

The script doctor-checks the host, fetches the release tarball and guest artifacts if they are not already present, starts k7d, boots a busybox 3-node tree, forks 4 branches, and prints the wall-clocks next to both rows of the two-clocks table. k7d doctor and k7d quickstart are the same verbs on an already-installed binary:

Overrides: K7D_RELEASE_URL (tarball), K7D_PREFIX (default /usr/local), K7D_SOCKET (default /run/k7d/k7d.sock).

Install from a release tarball#

Each release ships a self-contained tarball with the daemon, the containerd shim, the guest kernel, the guest initramfs, the guest docker payload, and an installer.

The installer:

  • copies k7d and containerd-shim-k7-v1 to /usr/local/bin (override with --prefix DIR) and the shim’s static runc.amd64 to /opt/k7d,
  • copies the guest kernel (vmlinux), initramfs, and docker payload to /usr/local/share/k7d (payload under docker/),
  • writes a k7d.service systemd unit that points K7D_KERNEL / K7D_INITRD at those assets, sets RUST_LOG=info, and raises LimitNOFILE to 524288 (the 1024 soft default is far too low for multi-cluster forks),
  • starts the daemon and waits for the control socket.

Verify:

Note

k7d --version and k7d --help answer and exit without touching the running daemon. The daemon also refuses to start if a live listener already owns the socket path — it never displaces a running instance.

Registering with k3s#

If the host runs k3s and you want runtimeClassName: k7 (and k7-fc), add --with-k3s:

This registers the k7 and k7-fc runtimes in the k3s containerd config template (the latter through ConfigPath = /etc/k7d/shim-k7-fc.toml), restarts k3s, and applies both RuntimeClasses (k7-fc with its 32Mi / 50m PodOverhead). It refuses to continue if either block carries BinaryName. The RuntimeClass guide explains each step if you prefer to do it by hand. k7-fc pods additionally need the pinned Firecracker binaries:

Note

k7d 0.9.0 is the current tarball: warm-forked pod sandboxes keep their network, one network namespace per host bridge (a fork and its live source both have egress), set_dilation_policy and live per-VM CPU for k7view. 0.8.0 brought pre-copied cluster keyframes, keyframe refresh, a per-tree dilation policy, opt-in KSM, adopted-VM teardown and the fake-GPU fixture extensions; 0.7.0 was privilege separation, Intel warm-fork CET/XSS, and Firecracker jail integrity. The agent-sandbox integration and kubectl port-forward landed on main after 0.9.0. The k7 playbook still pins 0.7.0 by default; pass k7 install --k7d-artifact for a newer tarball. The Firecracker engine and in-guest Docker service first shipped in 0.6.0 — do not use 0.5.0. Intel hosts that installed the dilation patch from 0.7.0 should rebuild it (Time warp).

Build from source#

You need Rust and Docker (the guest rootfs is built in a container).

make release produces the same tarball layout under dist/k7d-v<version>-x86_64-linux/ (daemon, shim, vmlinux, initramfs.cpio.gz, runc.amd64, docker/, install.sh, quickstart.sh) plus the .tar.gz — run sudo ./install.sh from there, or start the daemon directly for a quick look:

The daemon is the only process that chooses a guest kernel and initramfs. Without K7D_KERNEL / K7D_INITRD it refuses to create a VM rather than guessing. HACKING.md covers the remote-node development loop, the verification suite, and the kubectl integration tests.

What else ships in the tree#

Since 0.5.0 the public repository also carries gym/ (the RL gym — lease, fork, prepare, score, scenario packs with a scripted runtime; see GRPO) and utils/kvm-dilation/ (the carried KVM continuous ×N dilation patch with install/revert scripts; see Time warp). make helm-pin installs the pinned helm v3.16.4 used for Ubuntu Cilium/Tetragon bring-up.

Ubuntu node images#

The tarball’s guest is the minimal busybox initramfs. To run stock Ubuntu 24.04 guests (k3s + Cilium + Tetragon + Longhorn, the ~1.1 s fork clock), build a node image once with guest/ubuntu/build-node-image.sh — see Ubuntu nodes.

Fork your first cluster#

k7d quickstart is the shortest path. The repository also ships a demo that boots a live 3-VM k3s cluster once, then forks it into parallel branches, scores them, keeps the winner, and prunes the rest — printing the fork wall-clock as it goes.

Everything the demo does goes through the JSON-lines protocol on /run/k7d/k7d.sock — the same verbs your own trainer would call. See the daemon API for the full verb list and the GRPO guide for wiring it into a training loop.

Next steps#