User Namespaces in Kubernetes
Required knowledge for the CKS certification.
Without user namespaces, a process running as root inside a container is also seen by the kernel as root on the host. If an attacker manages to break out of the container — through a kernel vulnerability or a misconfigured mount — they are root on the host. User namespaces address this directly by isolating the user and group IDs used inside the container from those on the host.
User namespace support in Kubernetes reached General Availability (GA) in Kubernetes v1.36. The version timeline is Alpha in v1.25, Beta in v1.30, enabled by default in v1.33, and GA in v1.36. This is a Linux-only feature.
How User Namespaces Work
When a pod runs with user namespaces enabled, the kubelet assigns a range of host UIDs and GIDs to that pod and maps them so that UID 0 inside the container corresponds to an unprivileged UID on the host (above 65535). The kubelet guarantees that no two pods on the same node use the same mapping, preventing one pod from interfering with another through shared host-level identifiers.
Before: A container process running as UID 0 is also UID 0 on the host. A container escape grants the attacker full root privileges on the node.
After: A container process running as UID 0 is mapped to, for example, UID 833617920 on the host. A container escape leaves the attacker as an unprivileged host user, significantly reducing the blast radius.
ID-Mapped Mounts
When a volume is mounted into a pod with user namespaces enabled, the kernel performs a transparent translation of UIDs and GIDs using ID-mapped mounts. The container sees files as owned by UID 0 while disk ownership is unchanged — no recursive chown is required. This is an O(1) operation with no startup performance cost.
ID-mapped mounts were introduced in Linux 5.12, but Kubernetes also requires idmap support for tmpfs, which is used internally for service-account tokens, ConfigMaps, Secrets, projected volumes, and downwardAPI volumes. tmpfs gained idmap mount support in Linux 6.3, which is the practical minimum kernel version for using user namespaces in Kubernetes.
Requirements
- Kubernetes version: v1.25 or later (GA since v1.36; no feature gate required since v1.33)
- Operating system: Linux only; Windows nodes are not supported
- Container runtime: Must support user namespaces (check your runtime's documentation for the minimum supported version)
- Linux kernel: Linux 6.3 or later. ID-mapped mount support is required on every filesystem used by the pod's volumes;
tmpfs(used for service-account tokens, ConfigMaps, Secrets, projected, and downwardAPI volumes) gained idmap support in 6.3. Earlier kernels back to 5.12 have idmap support for some other filesystems but not fortmpfs. - Filesystem: Volumes must be backed by a filesystem that supports idmap mounts. Popular filesystems with idmap support in Linux 6.3 include
btrfs,ext4,xfs,fat,tmpfs, andoverlayfs. NFS does not currently support idmap mounts.
Enabling User Namespaces
Set hostUsers: false in the pod spec. No changes to container images are required.
apiVersion: v1
kind: Pod
metadata:
name: isolated-workload
spec:
hostUsers: false
containers:
- name: app
image: debian
command: ["sleep", "infinity"]
For Deployments and other workload resources, set the field in the pod template:
apiVersion: apps/v1
kind: Deployment
metadata:
name: isolated-app
spec:
replicas: 2
selector:
matchLabels:
app: isolated-app
template:
metadata:
labels:
app: isolated-app
spec:
hostUsers: false
containers:
- name: app
image: debian
command: ["sleep", "infinity"]
Verifying User Namespaces
After creating the pod, confirm it is running inside a user namespace:
kubectl exec -ti isolated-workload -- bash
Inside the container, check the user namespace ID:
readlink /proc/self/ns/user
Example output:
user:[4026534899]
Check the UID mapping:
cat /proc/self/uid_map
Example output:
0 833617920 65536
The three columns are: inside-UID start, host-UID start, length. A length of 65536 and a host-UID start above 65535 confirms the pod is running in a user namespace with a non-root host identity. Running the same command on the host will show a different namespace ID and a mapping that starts at 0.
To audit which pods in the cluster are not using user namespaces:
kubectl get pods -A -o custom-columns='NAMESPACE:.metadata.namespace,NAME:.metadata.name,HOST_USERS:.spec.hostUsers'
Pods with an empty or true value in the HOST_USERS column are not using user namespaces.
Namespaced Capabilities
When hostUsers: false is set, Linux capabilities granted to the container are limited to the pod's user namespace and are mostly invalid outside of it. The official Kubernetes documentation gives two illustrative examples:
CAP_SYS_MODULEhas no effect when granted to a pod using user namespaces — the pod cannot load kernel modules.CAP_SYS_ADMINis limited to the pod's user namespace and is invalid outside of it.
This means workloads that need elevated capabilities for in-container operations can be granted those capabilities without giving the process equivalent power over host resources.
Issue: Granting privileged Linux capabilities to a container running on the host user namespace gives the process those capabilities over host resources if the container is compromised or escapes.
Fix: Combine hostUsers: false with the required capabilities. Capabilities are scoped to the pod's user namespace and most are void or limited when applied to host resources.
Limitations
- Linux only. Windows nodes do not support user namespaces.
- NFS volumes. NFS does not currently support idmap mounts. Pods with NFS volumes cannot use user namespaces when those volumes are mounted.
- Opt-in per pod. The feature is not enforced cluster-wide by default. Use a
ValidatingAdmissionPolicyor an admission controller (Kyverno, OPA Gatekeeper) to requirehostUsers: falseacross target namespaces.

References
This article is based on information from the following official sources:
- User Namespaces | Kubernetes - Kubernetes Documentation
- Use a User Namespace With a Pod | Kubernetes - Kubernetes Documentation
- Kubernetes v1.36: User Namespaces Reach GA | Kubernetes - Kubernetes Blog
- Kubernetes v1.33: User Namespaces Enabled by Default | Kubernetes - Kubernetes Blog