This episode covers how to run AI/ML workloads inside a microVM: VFIO GPU passthrough, the role of NRI (Node Resource Interface) for device plugins, and KEDA autoscaling integration. You'll also understand how resource limits are applied at the VM level.

Up to episode 9, all our workloads only used virtual CPU and memory. Episode 10 opens a different door: physical devices — especially GPUs. AI/ML workloads are the main reason many teams start considering microVM isolation: they want to run models and agents that execute unknown input, but still need GPU access for inference.
Kata Containers answers this need through VFIO passthrough: the GPU is released from the host and given directly to the microVM. This episode covers how passthrough works, the role of NRI for device management in Kubernetes, and how KEDA and resource limits work in a microVM environment.
Virtual GPUs (vGPU) have limited compatibility and overhead. For production AI/ML, teams prefer full passthrough: the physical GPU appears in the guest as a real device. Applications in the guest use CUDA/ROCm directly, as if running on bare metal.
The VFIO principle (from episode 8): the device is bound to the vfio-pci driver on the host, then attached to the microVM. The guest sees the GPU as a PCI device with full resources — GPU memory, compute units, everything.
Passthrough demands IOMMU support. Without IOMMU, devices can't be safely isolated for passthrough. Prepare the host:
# Di kernel boot params (GRUB): intel_iommu=on (Intel) / amd_iommu=on (AMD)
cat /proc/cmdline | grep iommu
ls /sys/kernel/iommu_groups/cat /proc/cmdline | grep iommu verifies IOMMU is active on the running kernel. ls /sys/kernel/iommu_groups/ shows the IOMMU groups — devices in the same group can't be passed through separately.
After IOMMU is active, bind the device to vfio-pci:
lspci -nn | grep -i nvidia
echo "10de 2684" > /sys/bus/pci/drivers/vfio-pci/new_idlspci -nn | grep -i nvidia finds the GPU's vendor/device ID. That ID is registered with vfio-pci so the device can be passed through.
Kubernetes provides GPUs through a device plugin that creates extended resources (for example nvidia.com/gpu). Pods requesting that resource are scheduled to nodes with GPUs. For Kata, the GPU is allocated to the microVM via VFIO. Example pod:
apiVersion: v1
kind: Pod
metadata:
name: kata-gpu
spec:
runtimeClassName: kata
containers:
- name: ml
image: nvidia/cuda:12.2-base
command: ["nvidia-smi"]
resources:
limits:
nvidia.com/gpu: 1nvidia.com/gpu: 1 requests one GPU. After the pod runs, nvidia-smi inside the guest should display the GPU — proof the passthrough worked.
NRI (Node Resource Interface) is a standard that connects container runtimes with device plugins and other node components. With NRI, plugins (for example the GPU plugin) can interact with the container lifecycle through callbacks — without modifying the runtime.
For Kata, NRI means device plugins don't need to understand microVM details. The plugin tells the runtime "this container needs this GPU", and the Kata layer translates it into a VFIO configuration for the microVM. This simplifies device integration in a Kata environment.
To enable NRI in containerd, add this to /etc/containerd/config.toml:
version = 2
[plugins."io.containerd.grpc.v1.cri"]
enable_nri = true
enable_unprivileged_ports = false
[plugins."io.containerd.nri.v1.nri"]
disable = false
socket_path = "/var/run/nri/nri.sock"enable_nri = true enables NRI integration. With NRI active, device plugins work seamlessly with Kata pods.
From episode 5 we know pod limits are translated into microVM allocation. In the context of GPUs and large workloads, this means:
Note this philosophical difference: with regular containers, cgroups throttle processes when they exceed limits. With Kata, limits determine the VM's size. This is firmer but less flexible — that's the price of isolation.
Warning
GPU passthrough sacrifices device-level isolation: the guest gets direct access to the physical GPU. For very sensitive multi-tenant workloads, consider GPU virtualization (MIG/SR-IOV) if the VMM supports it, or restrict nodes with GPUs to trusted workloads only.
KEDA (Kubernetes Event-Driven Autoscaling) is an event-based autoscaling tool. How does it interact with Kata? Because Kata pods look like regular pods in Kubernetes, KEDA works without changes — it scales Deployments based on metrics, and new pods are born as new microVMs.
What you need to watch is boot time: because every new pod waits for a microVM boot, Kata scale-up is a bit slower than runc. For workloads needing fast scaling, consider:
minReplicaCount) so microVMs are already warm.A simple KEDA trigger example:
apiVersion: keda.sh/v1alpha1
kind: ScaledObject
metadata:
name: kata-http-scaler
spec:
scaleTargetRef:
name: kata-app
minReplicaCount: 1
maxReplicaCount: 10
triggers:
- type: prometheus
metadata:
serverAddress: http://prometheus:9090
metricName: http_requests_total
threshold: "100"maxReplicaCount: 10 caps the maximum scale. Because every replica is a microVM, think about node capacity: ten replicas mean ten microVMs, each holding its own resources.
vfio-pci binding is lost after a reboot — use a udev rule or modprobe config.What you should take away:
nvidia-smi inside the guest proves GPU passthrough succeeded.In the next episode, episode 11, we'll cover Confidential Containers (CoCo) — encrypting workloads with TDX/SEV/SEV-SNP through the kata-qemu-coco-dev runtimeclass, the attestation and measurement process, and its use cases and limitations.