How do you run untrusted code in Kubernetes: gVisor, Kata or Firecracker?

To run untrusted code safely in Kubernetes, put it in a sandboxed runtime, because standard containers share the node’s Linux kernel and a single kernel or runtime bug can let code escape to the host. gVisor answers system calls with its own user-space kernel, and Kata Containers runs each Pod inside a lightweight virtual machine with a dedicated guest kernel. Firecracker is a virtual machine monitor that Kata can use, not a Kubernetes runtime on its own.

Why a container is not a security boundary

A container is a normal Linux process that namespaces and cgroups restrict. Every container on a node makes system calls to the same kernel, so the kernel and the container runtime are one shared attack surface. The Kubernetes multi-tenancy guide says containers “offer a weaker isolation boundary than virtual machines that utilize hardware-based virtualization.”

Real escapes show the risk:

  • CVE-2019-5736: a malicious container could overwrite the host’s runc binary through /proc/self/exe and run code as root on the host the next time runc started.
  • CVE-2024-21626 (“Leaky Vessels”): a leaked file descriptor let a container’s working directory point into the host filesystem. It affected runc from 1.0.0-rc93 and was fixed in 1.1.12 in January 2024.
  • CVE-2025-31133, CVE-2025-52565 and CVE-2025-52881: three runc flaws disclosed in November 2025, involving masked paths, /dev/console mounts and security-module bypasses, fixed in runc 1.2.8, 1.3.3 and 1.4.0-rc.3.

That risk is acceptable for code you wrote and reviewed. It is not acceptable for code you do not control: output from AI agents and code interpreters, customer-submitted jobs, plugins, CI builds of external pull requests, or parsers that handle hostile files. For the general difference between the two isolation models, see containers vs virtual machines.

The options compared

Standard runtime (runc) gVisor Kata Containers
Isolation boundary Shared host kernel User-space application kernel (Sentry) in front of the host kernel Hardware virtualization, one VM per Pod
Kernel serving the workload Host kernel gVisor’s Sentry Guest kernel inside the VM
Node requirement None None; the KVM platform runs best on bare metal Hardware virtualization: bare metal or nested virtualization
Compatibility Full Not every system call or /proc and /sys file is implemented High; host devices, hostPath and privileged mode do not fit the model
Main cost None Higher per-system-call overhead Guest kernel and hypervisor process per Pod
GPUs Yes NVIDIA through nvproxy, on supported drivers Depends on the hypervisor; QEMU is the upstream option for NVIDIA GPUs

How gVisor works

gVisor is an application kernel written in Go. Its main component, the Sentry, implements system calls, signals, memory management and threading in user space, and it does not pass system calls through to the host kernel. File access outside the sandbox goes through a separate Gofer process. The OCI runtime is called runsc.

How the Sentry intercepts system calls depends on the platform. Systrap is the default and works inside ordinary virtual machines. KVM runs best on bare metal. That makes gVisor easy to adopt on cloud instances without nested virtualization.

The trade-off is in gVisor’s own documentation: higher per-system-call overhead, “poor performance for system call heavy workloads”, and reduced compatibility because not every Linux interface is implemented. Benchmark I/O-heavy and network-heavy workloads before you commit.

How Kata Containers works

Kata Containers starts a lightweight VM for each Pod. All containers of the Pod run inside that VM, which has its own minimal guest kernel. A process that compromises its container, and even the guest kernel, still faces the hardware virtualization boundary before it reaches the node.

Kata supports several hypervisors: QEMU, Cloud Hypervisor, Firecracker, Dragonball and StratoVirt. QEMU has the broadest device support and is the upstream choice for NVIDIA GPUs and confidential computing. The Rust-based monitors, Cloud Hypervisor and Firecracker among them, have a smaller code base and fewer devices.

Kata needs hardware virtualization on the node. Bare-metal servers have it. A cloud virtual machine has it only if the instance type supports nested virtualization, and many instance types do not. Check this before you plan capacity.

Where the microVM monitor fits

Firecracker is a virtual machine monitor that uses Linux KVM to create microVMs. AWS built it for Lambda, and its project page claims boot times under 125 ms and less than 5 MiB of memory overhead per VM. Firecracker does not understand Pods or container images. In Kubernetes you use it through Kata Containers (as the hypervisor) or through firecracker-containerd. The question “Kata or Firecracker” is therefore a choice of hypervisor inside Kata, not a choice between two runtimes.

How to wire a sandbox into Kubernetes

A RuntimeClass maps a name to a runtime handler configured on the nodes, and a Pod selects it with runtimeClassName. RuntimeClass has been stable since Kubernetes 1.20. Two of its fields matter for sandboxes:

  • scheduling adds a node selector and tolerations, so sandboxed Pods land only on nodes that have the runtime installed.
  • overhead declares the extra CPU and memory each sandboxed Pod uses, such as the guest kernel and hypervisor, so the scheduler and resource quotas account for it.

Run sandboxed workloads on a dedicated node pool, separate from trusted platform services, so that resource exhaustion also stays contained.

Defense in depth around the sandbox

A sandbox protects the kernel. Anything the sandboxed code can reach is still exposed, so combine it with these controls:

  • Set automountServiceAccountToken: false, so the code holds no Kubernetes credentials.
  • Apply the Restricted Pod Security Standard: run as non-root, drop all capabilities, keep the RuntimeDefault seccomp profile, disable privilege escalation.
  • Start with default-deny network policies and allow only the endpoints the workload needs. Block the cloud metadata address 169.254.169.254.
  • Set CPU and memory limits on every sandboxed container.

For running many tenants side by side, the sandbox is one rung of a larger ladder covered in Kubernetes multi-tenancy.

Running sandboxed workloads on Cloudfleet

Cloudfleet Kubernetes Engine (CFKE) offers Kata Containers with Cloud Hypervisor as a managed runtime, which a Pod selects with runtimeClassName: kata on bare-metal or nested-virtualization nodes. For AI agents, Agent Sandbox adds pre-warmed sandbox pools on top of it.

On this page