docs/how-to/how-to-use-template-in-runtime-rs.md
VM templating is a Kata Containers feature that enables new VM creation using a cloning technique. When enabled, new VMs are created by cloning from a pre-created template VM, and they will share the same initramfs, kernel and agent memory in readonly mode. It is very much like a process fork done by the kernel but here we fork VMs.
For more details on VM templating, refer to the What is VM templating and how do I use it article.
VM templating can be enabled by changing your Kata Containers config file (/opt/kata/share/defaults/kata-containers/runtime-rs/configuration.toml, overridden by /etc/kata-containers/configuration.toml if provided) such that:
qemu version v4.1.0 or above is specified in hypervisor.qemu->path sectionenable_template = truetemplate_path = "/run/vc/vm/template" (default value, can be customized as needed)initrd = is setimage = option is commented out or removedshared_fs = option is commented out or removeddefault_memory = should be set to more than 256MBThen you can create a VM template for later usage by calling:
The factory init command creates a VM template by launching a new VM, initializing the Kata Agent, then pausing and saving its state (memory and device snapshots) to the template directory. This saved template is used to rapidly clone new VMs using QEMU's memory sharing capabilities.
sudo kata-ctl factory init
The factory status command checks whether a VM template currently exists by verifying the presence of template files (memory snapshot and device state). It will output "VM factory is on" if the template exists, or "VM factory is off" otherwise.
sudo kata-ctl factory status
The factory destroy command removes the VM template by remove the tmpfs filesystem and deleting the template directory along with all its contents.
sudo kata-ctl factory destroy
In the Go version of Kata Containers, the VM templating mechanism is implemented using virtio-9p (9pfs). However, 9pfs is not supported in runtime-rs due to its poor performance, limited cache coherence, and security risks. Instead, runtime-rs adopts VirtioFS as the default mechanism to provide rootfs for containers and VMs.
Yet, when enabling the VM template mechanism, VirtioFS introduces conflicts in memory sharing because its DAX-based shared memory mapping overlaps with the template's page-sharing design. To resolve these conflicts and ensure strict isolation between cloned VMs, runtime-rs replaces VirtioFS with the snapshotter approach — specifically, the blockfile snapshotter.
The blockfile snapshotter is used in runtime-rs because it provides each VM with an independent block-based root filesystem, ensuring strong isolation and full compatibility with the VM templating mechanism.
Blockfile Snapshotter is Availablectr plugins ls | grep blockfile
If not available, continue with the following steps:
dd if=/dev/zero of=/opt/containerd/blockfile bs=1M count=500
sudo mkfs.ext4 /opt/containerd/blockfile
Edit the containerd configuration file:
sudo vim /etc/containerd/config.toml
Add or modify the following configuration for the blockfile snapshotter:
[plugins."io.containerd.snapshotter.v1.blockfile"]
scratch_file = "/opt/containerd/blockfile"
root_path = ""
fs_type = "ext4"
mount_options = []
recreate_scratch = true
After modifying the configuration, restart containerd to apply changes:
sudo systemctl restart containerd
blockfile SnapshotterAfter the VM template is created, you can pull an image and run a container using the blockfile snapshotter:
ctr run --rm -t --snapshotter blockfile docker.io/library/busybox:latest template sh
We can verify whether a VM was launched from a template or started normally by checking the launch parameters — if the parameters contain incoming, it indicates that the VM was started from a template rather than created directly.
The comparative experiment between template-based VM creation and direct VM creation showed that the template-based approach achieved a ≈ 73.2% reduction in startup latency (average launch time of 0.6s vs. 0.82s) and a ≈ 79.8% reduction in memory usage (average memory usage of 178.2 MiB vs. 223.2 MiB), demonstrating significant improvements in VM startup efficiency and resource utilization.
The test script is as follows:
# Clear the page cache, dentries, and inodes to free up memory
echo 3 | sudo tee /proc/sys/vm/drop_caches
# Display the current memory usage
free -h
# Create 100 normal VMs and template-based VMs, and track the time
time for I in $(seq 100); do
echo -n " ${I}th" # Display the iteration number
ctr run -d --runtime io.containerd.kata.v2 --snapshotter blockfile docker.io/library/busybox:latest normal/template${I}
done
# Display the memory usage again after running the test
free -h