This episode integrates Cloud Hypervisor into Kubernetes via Kata Containers: the kata-clh RuntimeClass that runs each pod inside a VM, setup with the kata-deploy Helm chart, and the containerd shimv2 → Cloud Hypervisor → guest kernel → agent flow. You'll understand full pod isolation with container agility.

This is the episode that answers the most frequently asked question about Cloud Hypervisor: what is it actually used for in the real world? The answer is in Kata Containers. Kata Containers is an OCI runtime that wraps every container in a lightweight VM — and Cloud Hypervisor is one of the main backends of the kata-clh runtime.
Imagine an apartment (a Kubernetes node) where each room (pod) is surrounded by concrete walls (a VM) that other rooms can't breach — even if the neighboring room has been broken into by thieves (a compromised container). In episode 18 we build that: installing Kata Containers with kata-clh, defining the RuntimeClass, and understanding the pod flow from containerd all the way into the VM.
Kata Containers combines VM security with container agility. Each pod runs inside its own VM powered by Cloud Hypervisor (or QEMU for the kata-qemu runtime). The results:
Pod execution uses the shim v2:
kubelet → containerd → shimv2 (kata) → Cloud Hypervisor (VM)
↓
guest kernel + rootfs pod
↓
agent di dalam VM → menjalankan containerkata-clh RuntimeClass and calls Kata's shim v2.From Kubernetes' point of view, this is transparent — the pod runs as usual; only the runtime behind it differs.
The easiest install method is the kata-deploy Helm chart, which deploys the Kata Containers daemonset to all nodes:
helm repo add kata-containers https://kata-containers.github.io/kata-containers
helm repo updatehelm install kata-deploy kata-containers/kata-containers \
--namespace kube-system \
--create-namespace \
--set runtimeClass.create=true \
--set runtimeClass.snapshotter=overlayfs \
--set defaultRuntimeClassName=kata-clh \
--set shims.v2.default=true \
--set shims.v2.enableAllShims=false \
--set kataImage.registry="ghcr.io/kata-containers/kata-deploy"The key config to understand:
shims.v2.default=true: the shim v2 is installed as the default, and the backend used is kata-clh (Cloud Hypervisor).runtimeClass.create=true: the kata-clh RuntimeClass is created automatically.runtimeClass.snapshotter=overlayfs: uses the overlayfs snapshotter so the container rootfs can be used inside the VM.kubectl -n kube-system get ds kata-deploy
kubectl get runtimeclass kata-clh
kubectl get runtimeclass kata-clh -o jsonpath='{.handler}'kubectl get runtimeclass kata-clh must show a RuntimeClass with the handler kata-clh.
Once the RuntimeClass is available, run a pod with runtimeClassName: kata-clh:
apiVersion: v1
kind: Pod
metadata:
name: secure-app
spec:
runtimeClassName: kata-clh
containers:
- name: app
image: nginx:latest
resources:
requests:
memory: "256Mi"
cpu: "250m"kubectl apply -f pod-kata.yaml
kubectl get pod secure-app -wHere's how to prove a pod runs inside a Cloud Hypervisor VM, not on the host:
kubectl exec secure-app -- uname -rA kernel version different from the host kernel is strong proof the pod is in a separate VM:
uname -rOn the node where the pod runs, check the host processes:
pgrep -af cloud-hypervisorThere should be one cloud-hypervisor process per kata pod — proof of active VM isolation.
Warning
Pods behind kata-clh don't share the host kernel — everyone must understand this consequence: kernel modules a workload needs (e.g., ones loading special drivers) must be available inside the Kata guest kernel, not the host kernel. Read the Kata Containers documentation for the list of provided modules.
Container state and filesystems inside the VM are synced to the host via virtio-fs and the shim. A pod crash = the VM is stopped, the containers inside stop too, and kubelet reschedules. There's no "hanging VM" behind a pod — the operational model remains pure Kubernetes.
Pod resources (requests/limits) are translated into VM memory and CPU. For workloads needing large resources, set reasonable requests/limits — the VM is created to that size. Remember: 1 pod = 1 VM — VM boot adds startup overhead, so kata-clh pods suit workloads that need high security and are long-lived, not ultra-frequent ephemeral functions.
Everything we've learned applies here: guest memory uses shared=on (snapshot/migration), virtio-fs for rootfs (episode 6), and per-VM TAPs for network isolation (episode 13). Kata Containers automates that configuration — you choose it through the RuntimeClass.
Tip
For multi-tenant workloads that need strong isolation on a shared node (e.g., running code belonging to different users), kata-clh is a far safer answer than a regular container sandbox. This is the same role as serverless microVMs — now with full Kubernetes agility.
runtimeClass.create=true was set at helm install.Key takeaways:
kata-clh backend.kata-deploy Helm chart and set shims.v2.default=true for kata-clh.runtimeClassName: kata-clh.uname -r inside a pod proves kernel isolation from the host.In the next episode, episode 19, we'll cover nested virtualization & EC2 — AWS EC2 supporting nested virtualization (C8i/M8i/R8i, February 2026) lets you run KVM and Cloud Hypervisor on regular instances, plus deployments on bare-metal and edge nodes. Kubernetes microVMs in the public cloud become real.