Two ways to get a cluster tree
1. Create one from scratch — tree_create_cluster
vm_count member VMs on a tree-owned bridge and roots a cluster snapshot tree at them. The fork engine is N-node — there is no hard-coded 3. The per-member config is a regular VmConfig (its network field must be omitted: the tree creates and owns its own cluster network).
Practical sizing: at ~3.2 GiB per k3s node, a 20-node base alone is ~64 GiB. The limit is host RAM, not the API — shrink guest memory or use a bigger box, and a 20-node cluster forks the same way the 3-node one does.
2. Adopt live VMs — tree_adopt_cluster
cluster-id annotation) and converts them into a cluster tree root. The VMs must already share one cluster bridge — same cluster_id, distinct vm_indexes covering 0..N-1.
Adoption fails loud on any half-wired state (missing VM, mixed bridges, non-contiguous indices, already tree-owned). Validation failures put the VMs back untouched; a failure after extraction tears everything down — no half-adopted state survives.
Setting up a k3s cluster inside the VMs is your scenario’s job (boot k3s server + agents, wait for Ready). k7d gives you the fork; the integration tests and the demo show a working 3-node k3s fixture end to end.
Forking, suspending, resuming a cluster
Once rooted, a cluster tree uses the same verbs as a single-VM tree — every operation applies to all members as one unit:guest_cids entry per member (ordered by vm_index), so your harness can dial each member’s agent. Batch cluster forks run sequential warm forks — each branch gets its own bridge.
The fork_memory_full_copy flags in fork responses tell you whether each member forked CoW (false, the expected fast path) or had to fall back to a full memory copy (true — happens only for virtiofs-backed sources, e.g. pods with read-write hostPath mounts).
What the numbers look like
Methodology and reproduction commands: Benchmarks. What works inside a forked cluster today (CoreDNS, Ingress, NetworkPolicy, …): Feature matrix.
