Kubernetes v1.37’s Rootless Mode Turns Container Breakouts Into a Contained Blast Radius
Kubernetes v1.37 graduates rootless mode to beta, so five recent container-breakout CVEs on node components now land on a fake root user instead of the real one.
Kubernetes v1.37 promotes KubeletInUserNamespace, better known as rootless mode, from alpha to beta. The feature lets every node-level component, the kubelet itself, the CRI and OCI container runtimes, the CNI networking plugins, and kube-proxy, run as a non-root user on the host by placing them inside a Linux user namespace. It has sat in alpha since Kubernetes v1.22 in 2021, and the underlying experiment dates back to 2018. The Kubernetes project’s announcement, written by Akihiro Suda of NTT, the same engineer who filed the original 2018 proposal, frames the five-year graduation around a specific and recurring problem: node components keep shipping container-breakout bugs that hand an attacker real root on the host, and rootless mode is the mitigation that survives whichever one comes next.
Table Of Content
A different namespace than the one that already shipped
Kubernetes already has a rootless-adjacent feature, and it is easy to confuse with this one. User namespaces for pods, enabled with hostUsers: false and gated by the UserNamespacesSupport feature, went GA back in Kubernetes v1.36. That feature puts the containers inside a pod into a user namespace, so a process that believes it is root inside the container maps to an unprivileged UID on the host. It says nothing about the node components themselves: the kubelet, the container runtime, and kube-proxy still run as real root underneath.
KubeletInUserNamespace is the mirror image of that feature. It puts the node components in a user namespace instead of the pods. Per the announcement, the two do not conflict, and they can be combined: a cluster can run pod-level user namespaces and node-level rootless mode at the same time, which lets it nest a full Kubernetes cluster inside another Kubernetes cluster’s pods without resorting to the sweeping privileged: true flag that nested Kubernetes has traditionally required.
Five specific CVEs, not a hypothetical
The Kubernetes blog post does not argue for rootless mode in the abstract. It lists five real vulnerabilities, spanning 2022 to 2026, where a node component was tricked into acting with full host root:
- CVE-2022-0811 (“cr8escape”): CRI-O could be tricked into setting arbitrary sysctls, such as
kernel.core_pattern, resulting in arbitrary code execution as root on the host. - CVE-2023-27561: runc could be tricked into bypassing a container’s masked paths through a volume mount race, exposing the host’s own procfs files. It was a regression of an earlier bug, CVE-2019-19921.
- CVE-2024-10220: the kubelet could be made to execute arbitrary commands as root through
gitRepovolumes, echoing a nearly identicalgitRepoflaw from 2018 (CVE-2018-11235). - CVE-2025-31133: runc could be tricked into bind-mounting attacker-controlled paths and writing to sensitive host procfs entries, including
/proc/sysrq-trigger. - CVE-2026-53488: containerd could be tricked into executing arbitrary commands on the host through crafted labels embedded in a container image.
That is five CVEs across four components, since runc shows up twice, and five different root causes with one shared consequence: whoever controlled the exploit ended up with real root on the node. Rootless mode does not prevent any specific one of these bugs from existing. What it changes is what an attacker gets when one of them fires.
How a user namespace turns real root into fake root
A Linux kernel user namespace maps a host-level non-root user, say UID 1000, to what looks like root (UID 0) from inside the namespace. Processes inside the namespace that believe they are running as root are, from the host’s point of view, still running as UID 1000 with no elevated privileges outside that namespace’s boundary. That fake root is enough for most of what the node components actually need to do day to day: mounting volumes, creating cgroups, and configuring the network namespaces of pods.
The practical effect for the five CVEs above is that a node-component bug that would have handed an attacker real root now hands them fake root instead, capped at whatever UID 1000 (or whichever host user was chosen) is actually allowed to do. Per the announcement, an attacker in that position “cannot conceal their intrusion by modifying the kernel, the boot loader, or the firmware.” The announcement is careful to note the limits of that guarantee too: user namespaces do nothing to mitigate a vulnerability in the Linux kernel itself, so the project still recommends pairing rootless mode with traditional hardening like seccomp to keep containers from making system calls they don’t need.
Setting this up is not something Kubernetes does on its own. The user namespace has to be created outside of Kubernetes before the node components start, typically with RootlessKit, the same tool rootless Docker’s daemon is built on. It is a different Linux namespace mechanism than the network namespaces sxz.io has previously covered for building Kubernetes pod networking from scratch, but the two are frequently layered together on the same node. RootlessKit also picks the network stack the node components run on: slirp4netns is the security-preferred option, while lxc-user-nic, a SETUID helper binary, trades a bit of that isolation for meaningfully better network throughput.
What still needs real privilege, or doesn’t work at all
Fake root is not full root, and the KEP-2033 design document is direct about where that shows up:
- cgroup v2 and systemd are required. cgroup v1 is not supported, on security grounds. containerd has supported cgroup v2 in rootless mode since v1.4, and CRI-O picked it up around the same era.
- Block-device volumes and kernel-mode NFS don’t work, since a Linux user namespace only supports
tmpfs, bind mounts, and FUSE filesystems.emptyDir,hostPath,localvolumes, and the API-backed volume types (configMap,secret,downwardAPI) are all confirmed to work without modification, and FUSE-based CSI drivers can work too. - NodePorts under 1024 cannot be exposed by default, since binding low ports needs a real capability. The default
--service-node-port-range(30000 to 32767) is unaffected; clusters that need lower ports can grantCAP_NET_BIND_SERVICEas a file capability on therootlesskitbinary itself. - Network throughput takes a hit under the security-preferred
slirp4netnsdriver, the tradeoff for not needing a SETUID helper. Flannel over VXLAN is the CNI plugin the project has explicitly confirmed working; others may not. - Some workloads still need real root, and the beta release adds a way to keep them off rootless nodes on purpose (more on that below).
What actually changed between alpha and beta
The feature gate’s own code change is, in the announcement’s own words, “quite boring”: it lets the kubelet ignore permission errors it hits when setting a handful of sysctl values it cannot actually change from inside a user namespace, such as vm.overcommit_memory and kernel.panic, and when it tries to watch kernel messages through /dev/kmsg. Nearly everything else works unmodified.
Three things are new in the move to beta:
- The
KubeletInUserNamespacefeature gate is now enabled by default. This only unlocks the capability; it does not put any existing cluster’s kubelet into a user namespace automatically. Rootful clusters that do nothing differently see no change in v1.37. kubectl get nodes -o yamlnow reports whether a node is running in a user namespace, through a newrunningInUserNamespacefield onNodeSystemInfo.- Cluster administrators can read that field to apply node labels or taints, keeping workloads that genuinely need real root, some CNI plugin installers among them, off rootless nodes rather than letting them fail unpredictably.
Rootless mode is one of several node and workload-identity hardening features Kubernetes has shipped in the v1.37 cycle; sxz.io covered another, the move from bearer tokens to per-pod certificates, a few days earlier. Three ecosystem changes outside the feature gate itself also matter for anyone planning to nest clusters: Linux kernel v6.3 (2023) added idmapped tmpfs support, Kubernetes v1.33 (2025) turned on the UserNamespacesSupport feature gate by default so user-namespaced pods need no extra configuration, and containerd v2.1 (2025) added writable cgroups inside user namespaces. With all three in place, a Kubernetes cluster running KubeletInUserNamespace can now also be nested inside another cluster’s pods that use hostUsers: false.
Where to try it today
The announcement points to four ways to run a rootless cluster right now, and none of them require patching Kubernetes itself:
- kind, the SIG Testing project, is described as the easiest path: install rootless Docker with
dockerd-rootless-setuptool.sh install, then runkind create clusteras normal. minikube supports the identical rootless-Docker setup withminikube start --driver=docker. - Usernetes, a third-party project that predates the KEP itself (the work that became
KubeletInUserNamespacestarted as a Usernetes experiment in 2018), is explicitly called out as supporting something kind and minikube don’t: a genuine multi-node rootless cluster, connecting rootless Docker, Podman, or nerdctl nodes over VXLAN using Flannel. It also has experimental support for Kubernetes-in-Kubernetes. - k3s, a CNCF Sandbox project, ships its own rootless mode that, unlike the other three, does not depend on an external rootless container runtime at all.
The Kubernetes project’s own CI now runs its node conformance end-to-end suite against a rootless kind cluster (ci-kubernetes-e2e-kind-rootless), which is one of the concrete adoption signals the KEP’s beta graduation criteria asked for.
What’s next
Kubernetes plans to graduate KubeletInUserNamespace to General Availability in a future release, contingent on feedback and real-world adoption rather than a fixed date. Two related enhancement proposals are still being discussed that would smooth over some of the current rough edges around nesting: KEP-5474, which would enable writable cgroups for unprivileged containers more broadly, and KEP-5714, which would let operators specify whether to unshare cgroup namespaces. Feedback is being collected through issues on the kubernetes/kubernetes repository and the project’s public Slack.
The five-CVE list at the center of the announcement is really an argument about defense in depth rather than any single bug. Each of those flaws was already patched once found; rootless mode does not undo that work, and it is not a substitute for keeping runtimes current. What it changes is the ceiling on what the next undiscovered one is worth to an attacker, by making sure that even a fully successful container breakout on a node component lands on an unprivileged host user instead of root.








No Comment! Be the first one.