Every CI cluster you have ever inherited runs the kubelet as root. Sit with that for a second. The daemon whose entire job is to launch other people's binaries, in other people's images, from other people's registries, is doing so with the full authority of uid 0 on the node. This week that stopped being the only option Kubernetes ships.
What v1.37 flipped
Kubernetes v1.37 promotes the KubeletInUserNamespace feature gate to beta. With the gate on, every node component that used to demand root can run inside a Linux user namespace as an ordinary user: kubelet, the CRI and OCI runtimes it drives, the CNI plugins, and kube-proxy. The community calls the configuration "rootless mode".
Rootless is not a new idea in this codebase. The work started as an experiment back in 2018 and shipped as alpha in Kubernetes v1.22 in 2021, tracked as KEP-2033. It has been usable but off-by-default since then, while the maintainers ground down the pointy edges. Beta means the flag stays opt-in, but the promise is that the shape of the API will not change under you before GA.
One thing to keep straight. This is a different lever from the pod-level user namespace work, hostUsers: false and the UserNamespacesSupport gate that graduated to GA in v1.36. That one puts each pod in its own uid mapping. This one puts the entire kubelet stack in one. You can combine them, which is how projects like KinD and Usernetes nest Kubernetes inside Kubernetes without asking for privileged: true.
Why the CI/CD desk should care
If you run ephemeral Kubernetes for pipeline workloads, and half the industry now does, the blast radius of a container escape has always been the node. A misconfigured seccomp profile, a runc CVE, a mount trick, and the workload lands with root on the host. From there the runner secrets, the shared cache volume and the neighbour tenants are all in scope.
Rootless does not make container escapes go away. It changes what an escape gets you. Break out of a rootless pod on a rootless node and you land as an unprivileged uid, inside a user namespace, with none of the host capabilities you were counting on. It is the same hardening logic that made Docker and Podman ship rootless daemons a few releases in.
For anyone building a shared CI cluster, that is the difference between a security incident and a security scare.
Turning it on
The mechanics are not glamorous. You enable the feature gate on the kubelet, run the kubelet under a regular user account with a subuid and subgid range allocated, use a rootless-capable container runtime (containerd and CRI-O both support it), and switch to a CNI plugin that does not assume it can open raw sockets on the host. The upstream docs walk through the Usernetes reference setup and the systemd unit changes.
Two constraints you will hit early. The host kernel needs cgroup v2 to give the unprivileged kubelet a delegated cgroup subtree, so ancient distros are out. And features that reach past the pod boundary, host networking, hostPID, hostIPC, privileged containers, are either restricted or unusable, because the whole point is that the kubelet no longer holds the capabilities they need. If a workload of yours quietly relies on any of those, rootless will tell you loudly.
How other stacks got here
Container runtimes crossed this bridge years ago. Docker ships a rootless install path. Podman treats rootless as the default posture and has done since it existed. LXC has had unprivileged containers for the best part of a decade. Kubernetes is the last of the big cluster runtimes to make it a first-class option, largely because the kubelet talks to more of the host than a single-node runtime ever needs to.
The interesting comparison is not with the runtimes but with the managed control planes. EKS, GKE and AKS all run their kubelets as root on nodes you do not administer, and that is unlikely to change soon. Rootless mode is a self-hosted concern, and the crowd that will benefit first is the CI platform teams running their own node pools for build isolation.
The verdict
Beta, not GA, and still opt-in. If you own the nodes your pipelines run on, this is worth a proof of concept before the next quarter starts. If you rent them from a hyperscaler, keep the KEP number in a tab and wait.
Root by default was a shortcut Kubernetes took in 2014 because the runtimes of the day left it no choice. Twelve years later the shortcut is finally optional. Take it while your threat model still lets you.
Top comments (0)