Skip to main content
The kata-qemu-longhorn backend supports disk-level snapshots of running sandboxes via Longhorn’s CSI VolumeSnapshot API. This unlocks three workflows:
  • Pause — scale to 0 and (optionally) snapshot the disk for safekeeping.
  • Resume — scale back to 1; the same disk re-attaches.
  • Fork — clone a sandbox’s disk into a brand-new sandbox with its own pod, IP, and lifecycle.
These commands require the kata-qemu-longhorn backend. The kata-firecracker-devmapper backend uses ephemeral devmapper LVs and doesn’t support persistent snapshots.
Looking for memory-faithful or whole-cluster forking? That’s the k7d runtime, not k7’s Longhorn-based fork. k7d warm-forks a running VM in ~5 ms (memory, disk, processes, and network identity all survive) and can fork an entire live Kubernetes cluster in ~100 ms — see CoW fork and Cluster mode. The fork described on this page is disk-only: the clone boots fresh from a copy of the source’s disk.

Anatomy of a kata-qemu-longhorn sandbox

When you create a kata-qemu-longhorn sandbox, k7 provisions:
  • A Longhorn PVC named <sandbox>-root-lh, sized via --root-disk-size (default 10Gi).
  • A Deployment with one replica, mounting the PVC at /mnt/state (with persistence wrapper bind-mounts).
  • An ingress-deny NetworkPolicy and an egress policy (CIDR or FQDN).
  • An optional Secret from env_file.
State written to /mnt/state (and to the rootfs via the bind-mount overlay) survives pod restarts because it lives on the PVC.

Pause

Optional flags:
  • --pvc PVC_NAME — explicit PVC to snapshot. Defaults to <sandbox>-root-lh.
  • --snapshot-class CLASSVolumeSnapshotClass. Defaults to longhorn (created by the playbook).
The snapshot is crash-consistent: it captures the disk state at the moment of the snapshot, not the in-memory process state. The sandbox process is then terminated as the Deployment scales to 0. The snapshot is stored as a VolumeSnapshot object in the same namespace and persists until you delete it (kubectl delete volumesnapshot <name>).

Resume

Scales the Deployment back to 1. The pod re-attaches to the same PVC; data on /mnt/state is exactly as it was at pause time. If the pause took a snapshot, the snapshot remains available — useful for rollback if the resumed workload corrupts something.

Fork

Fork takes a snapshot of the source sandbox’s PVC, clones it into a new PVC, and creates a new Deployment pointing at the cloned PVC. Implementation steps:
  1. Create a VolumeSnapshot of <source>-root-lh (auto-named or --snapshot).
  2. Wait for readyToUse: true on the snapshot.
  3. Create a new PVC <new>-root-lh from the snapshot via dataSource.
  4. Create a Deployment for the new sandbox using the cloned PVC.
  5. Wait for the new pod to be Ready.
  6. Delete the temporary snapshot (the cloned PVC is independent of it).
Scope: disk only. Fork does not clone:
  • Memory state (the new sandbox boots fresh)
  • CPU registers / process state
  • Network identity (the fork gets a new pod IP and is subject to its own NetworkPolicy)

Observed performance

Measured on a single Hetzner dedicated node (3× NVMe, Ubuntu 24.04, Longhorn replicas=1) — see PERFORMANCE.md: Fork is roughly 3× slower than a cold create today — most of the time is the cloned PVC’s first attach (Longhorn replays cloned data).

Example: a parallel exploration with fork

A common AI workflow is to set up a heavy environment once, then explore many branches from it.
Or from the CLI on a node with API access:
Each exp-N boots from a clone of base’s disk — the heavy pip install doesn’t run again.

Cleanup

k7 delete demo removes the Deployment, the PVC, and any pause/fork snapshots associated with the sandbox. To inspect what’s still around:
Integration tests under tests/integration/ exercise pause/resume/fork end-to-end and detect orphaned Longhorn replicas or stuck PVCs.

Reference