✉️ In Today’s Edition

  • What are User Namespaces (New GA feature in 1.36)

  • How kernel does the root to non-root user mapping

  • What changes when you set hostUsers: false

  • Hands on deployment to understand User Namespace

  • User Namespace limitations

and more…

🎁 CKA, CKAD, CKS.. Discount (Up to 65% OFF)

Planning to take a Kubernetes certification this year? This is the best time to save on certification registration.

Use code MM26CCCT at kube.promo/devops to get flat 50% OFF certifications.

For 65% bundle discounts and other offers, check this GitHub repository.

Note: This special offer returns only in November. Grab the discount before it expires.

87% of container images still contain high or critical vulnerabilities in 2026, making Kubernetes workload isolation and runtime security more important than ever.

checkmarx.com

When you deploy a Pod, the container inside usually runs as root by default unless you set runAsUser in the securityContext.

This means UID 0 inside the container maps directly to UID 0 on the host kernel.

Containers are already isolated using Linux namespaces, cgroups, seccomp, capabilities, and container runtimes.

And these isolation layers get broken regularly by bugs in container runtimes that attackers use to break out of a container and land on the host. When that happens, the attacker may gain root-level access on the host.

It exposes,

  • Other Pods running on the node

  • Secrets mounted on the node

  • Host filesystem access

  • Cluster credentials and more..

This is where User namespace helps you. (Stable feature in k8s v1.36)

Instead of mapping container root to host root, Kubernetes maps the container user IDs to unprivileged user IDs on the host (Rootless Isolation).

So even if a container breakout happens, the attacker remains an unprivileged user without administrative power over the node.

Recent Security Incident

In November 2025, three new vulnerabilities were disclosed in runc. CVE-2025-31133, CVE-2025-52565, and CVE-2025-52881.

All three let attackers break out of a container and gain root on the host. The runc maintainers recommend enabling user namespaces for all containers as a defense against these CVEs.

Now lets look at how User namespace work.

What is a User namespace?

User Namespaces are a Linux kernel feature that creates an isolated mapping between the UIDs a process sees and the UIDs the kernel actually enforces on the host.

When a user namespace is created, the kernel stores the mapping in memory. You can view it through the /proc/[pid]/uid_map and /proc/[pid]/gid_map files.

To enable User Namespaces, you nee to set hostUsers: false in the Pod spec. Then the kubelet tells the kernel to map the container's UIDs (0–65535) to an unused range of host UIDs outside 0–65535.

So the UID mapping looks like the following.

Container UID 0      →  Host UID 667680768
Container UID 1      →  Host UID 667680769
Container UID 1000   →  Host UID 667681768
Container UID 65535  →  Host UID 667746303

Every other Pod on the same node gets a different range. No two Pods overlap. This means even Pods running on the same node cannot read each other's files, because their host UIDs do not overlap.

The following image illustrates it better.

How the kernel actually does the mapping

The kubelet allocates a unique UID/GID range for each Pod. The container runtime (such as containerd or CRI-O) configures the user namespace mappings with the Linux kernel.

The Linux kernel then performs this UID translation automatically whenever the process makes a syscall (open file, create process, mount, etc.)

So even if a hacker accesses the container, he will not be able to get access to the host.

Hands-on Example

Note: To test this feature you should have k8 version 1.36 and kernel version 6.3 or later. You can use this kubeadm guide to set up the latest Kubernetes cluster version.

Now lets understand this feature with a hands-on example.

To use the user namespace feature for pods, you need to set the hostUsers field to false. First, deploy the following Nginx deployment manifest that has hostUsers set to false.

cat <<EOF | kubectl apply -f -
apiVersion: apps/v1
kind: Deployment
metadata:
  name: nginx-userns
spec:
  replicas: 3
  selector:
    matchLabels:
      app: nginx-userns
  template:
    metadata:
      labels:
        app: nginx-userns
    spec:
      hostUsers: false
      containers:
      - name: nginx
        image: nginx:alpine
        ports:
        - containerPort: 80
EOF

Now, run the following command with any one of your pod names.

kubectl exec -it <POD-NAME> -- cat /proc/self/uid_map

You should see the container UID 0 mapped to a non-root host UID as given below.

0 3040542720      65536

To verify it further, SSH into the host node where the pods are running and run the following command.

ps -eo uid,pid,cmd | grep nginx

You can see that all pods get their own unique non-root host uid.

This is how the User namespace feature assigns each Pod a unique UID range. This reduces the impact of container escape vulnerabilities because container root is mapped to an unprivileged user on the host.

Important Note: Inside the container, the process still sees itself as UID 0 (root). That's intentional, your application works without changes. But on the host, it's an unprivileged UID.

Limitation of User Namespace Feature

The following are some of the limitations of the User Namespace feature.

  1. If you set hostUsers: false, you can't combine it with set hostNetwork: true, hostPID: true, or hostIPC: true, Kubernetes will reject it.

  2. Containers using user namespaces can't use volumeDevices for raw block volumes like /dev/sda.

  3. The filesystem must support idmap mounts. Any filesystem used in the Pod's volumes (including /var/lib/kubelet/pods/) needs idmap mount support. If it doesn't, the Pod fails to start with an error like failed to set MOUNT_ATTR_IDMAP.

  4. NFS volumes can't be mounted in a Pod with user namespaces because the Linux NFS client doesn't yet support idmap mounts.

  5. If your volume has files owned by a UID outside the 0–65535 range, the container sees them as owned by user nobody. The app can't read its own data files because they show up as owned by nobody inside the container, which leads to permission denied.

That’s a Wrap!

For most workloads, user namespaces will work and adds a security layer.

However, User namespaces is not a complete sandbox. It does not fully protect against the following.

  • Kernel vulnerabilities

  • Privileged syscalls

  • Unsafe capabilities

  • Docker socket mounting

  • hostPath mounts

  • privileged: true abuse etc..

🧱 Kubernetes Tip: In-place pod resize

In-Place Pod Resize feature allows you to change CPU and memory requests and limits on a running pod without deleting or recreating it.

We have a detailed guide explains,

  • How it works behind the scenes.

  • How to resize pod in-place with VPA

  • Memory downsizing issues and more..

👉 Detailed Guide: In-Place Pod Resize with VPA

🧱 CRI Vs CNI Vs CSI in Kubernetes

  • CRI (Container Runtime Interface): How kubelet talks to container runtimes

  • CNI (Container Network Interface): How pods get network connectivity

  • CSI (Container Storage Interface): How pods get persistent storage

Here, the key pattern is, K8s defines the interface, vendors build the plugins.

Reply

Avatar

or to participate

Keep Reading