runtimeClassName: k7 run inside k7d microVMs instead of plain containers. Four steps register the runtime on a k3s node.
The release installer does all four steps for you:
sudo ./install.sh --with-k3s. The manual steps below are for understanding what it does, or for non-k3s containerd setups.1
Install and start the daemon
The shim is a thin client: sandbox The guest pair is required: the daemon is the only process that decides which guest a VM boots, and without
Create calls the daemon over /run/k7d/k7d.sock and fails loudly if it is not running.K7D_KERNEL / K7D_INITRD it refuses to create a VM rather than guessing. LimitNOFILE matters as soon as you fork clusters — the 1024 soft default runs out fast.2
Install the shim binary
io.containerd.k7.v1 → containerd-shim-k7-v1).3
Register the runtime in containerd
Add to Two things matter here:
/var/lib/rancher/k3s/agent/etc/containerd/config-v3.toml.tmpl:pod_annotationsforwards thek7d.katakate.org/*pod annotations (cluster-id,fork-vm-index, …) into the sandbox OCI spec so the shim can see them — required for cluster-mode pods deployed via kubectl.- Do not add an
[options]section withBinaryName— the option value leaks into the cgroup path and breaks shim startup.
4
Restart k3s and create the RuntimeClass
kubectl get runtimeclass k7 — it should show HANDLER: k7.Using it
kubectl logs, kubectl exec (including -it with PTY, resize, Ctrl-C, detach), pod IPs, Services, DNS, ConfigMaps/Secrets, emptyDir/hostPath/PVC volumes, memory/CPU limits, init containers, natural exit / restartPolicy, and multi-vCPU guests all work — see the feature matrix for the full support table and what’s still to come (hostNetwork, NetworkPolicy, IPv6, cross-node fork).
CPU limits and vCPUs: the shim derives the guest’s vCPU count from the pod’s CPU limit (
cpu: "2" boots a 2-vCPU guest), and the limit is additionally enforced on the host via a CFS quota on the VM’s vCPU threads. Fork and snapshot preserve multi-vCPU state.Sizing writable storage
A container’s writes go to an overlay upper on the sandbox’s scratch disk — a sparse ext4 image on the host, attached as a read-write virtio-blk device — not to guest RAM. Writable capacity is therefore independent of the pod’s memory limit, and filling it gives the writing process an ordinaryENOSPC rather than guest-wide memory pressure.
Size it per pod (default 8 GiB):
name=size list over container names:
ENOSPC while siblings keep writing. Containers you don’t name go on sharing the pod’s scratch disk.
Per-container scratch is opt-in for two reasons: each image spends one of the VM’s virtio-MMIO device slots, and a pod that uses it is served by a fork rather than from the warm pool. A warm fork gets a reflink-CoW copy of every image, so a fork’s writes — and its usage numbers — are isolated from its parent and its siblings.
resources.limits.ephemeral-storage never reaches the runtime and these annotations are the only sizing input. Usage is measured inside the guest and surfaced in the shim log, not in kubectl top.
Persistent data disks
Scratch dies with the pod. For state that must outlive the VM — a storage node’s replica directory, a database’s data dir — ask for named disks:id:size:guest-mount entry attaches an ext4 image data/<id>.img on the daemon’s reflink filesystem, created and formatted on first use and reused as-is on every later attach. Sandbox teardown leaves it in place; only the daemon’s delete_data_disk op removes it. A size that disagrees with an existing image is an error, not a resize. A warm fork gets a reflink-CoW copy, so a fork’s writes diverge from the source’s without a byte copy. Like per-container scratch, every disk spends one virtio-blk device slot, which is why it is opt-in.
Annotation reference
All values fail loud on a malformed entry — a pod that asked for a disk and silently did not get one would lose its data with the VM, which is the failure the annotations exist to prevent.
Because VMs outlive shims
The daemon owns the VMs, so a containerd restart or shim crash does not kill your workloads: a freshly respawned shim resolves its sandbox back to the still-running VM via the daemon’sreattach_sandbox operation, which also verifies the guest agent still answers before handing the VM back.
The daemon also exposes pause_vm / resume_vm for a sandbox VM: vCPU threads are stopped and device workers parked while guest memory, devices, and the vsock CID stay put. This is what K7’s k7 pause uses against the k7d backend.