How to Enable User Namespaces in Kubernetes v1.36 for Enhanced Container Security
By • min read
<h2>Introduction</h2>
<p>After years of development, Kubernetes v1.36 has finally made User Namespaces generally available (GA) on Linux. This feature allows you to run containers as root without giving them actual root privileges on the host. Instead, the container’s root user is mapped to a non-privileged user on the host, drastically reducing the blast radius of a container breakout. This guide walks you through enabling and using User Namespaces in your Kubernetes workloads, from understanding the concept to verifying the setup.</p><figure style="margin:20px 0"><img src="https://picsum.photos/seed/290543604/800/450" alt="How to Enable User Namespaces in Kubernetes v1.36 for Enhanced Container Security" style="width:100%;height:auto;border-radius:8px" loading="lazy"><figcaption style="font-size:12px;color:#666;margin-top:5px"></figcaption></figure>
<h2>What You Need</h2>
<ul>
<li>A Kubernetes cluster running <strong>v1.36 or later</strong> (Linux nodes only)</li>
<li>kubectl configured to interact with the cluster</li>
<li>Basic knowledge of Pod specifications and security contexts</li>
<li>Node kernel version <strong>Linux 5.12+</strong> (for ID‑mapped mounts support)</li>
<li>Container runtime that supports user namespaces (e.g., containerd 1.6+, CRI‑O 1.24+)</li>
</ul>
<h2>Step-by-Step Guide</h2>
<h3>Step 1: Verify Your Cluster Version</h3>
<p>Before you begin, ensure your cluster is running Kubernetes v1.36 or newer. Check with:</p>
<pre><code>kubectl version --short</code></pre>
<p>If you see a server version less than 1.36, upgrade your cluster first. User Namespaces are not available in earlier versions.</p>
<h3>Step 2: Understand the Key Setting – <em>hostUsers: false</em></h3>
<p>The core of User Namespaces support is the <code>hostUsers</code> field in the Pod spec. Setting <code>hostUsers: false</code> tells Kubernetes to isolate the Pod’s user namespace from the host. This means any UID inside the container (including UID 0 “root”) is remapped to a non‑privileged UID on the host. The container can still run as root internally, but the kernel sees a different, unprivileged user. This is different from running a container with a non‑root user – here the container can have all the privileges it needs, but they are <strong>namespaced</strong>.</p>
<h3>Step 3: Create a Pod with User Namespaces Enabled</h3>
<p>Write a Pod manifest that includes <code>hostUsers: false</code>. For example:</p>
<pre><code>apiVersion: v1
kind: Pod
metadata:
name: isolated-workload
spec:
hostUsers: false
containers:
- name: app
image: fedora:42
securityContext:
runAsUser: 0
</code></pre>
<p>Notice that <code>runAsUser: 0</code> is still allowed. Inside the container, the process runs as root, but thanks to the user namespace, that root identity is mapped to a high, unprivileged UID on the host. You do not need to change your container images – they work as before.</p>
<h3>Step 4: Apply the Pod and Verify Isolation</h3>
<p>Deploy the Pod with:</p>
<pre><code>kubectl apply -f pod.yaml</code></pre>
<p>Check the Pod’s events and status:</p>
<pre><code>kubectl describe pod isolated-workload</code></pre>
<p>You should see the user namespace being enabled automatically. To confirm isolation, you can exec into the container and check the UID mapping:</p>
<pre><code>kubectl exec -it isolated-workload -- cat /proc/self/uid_map</code></pre>
<p>This will show a mapping like <code>0 1000000 65536</code>, meaning the container’s UID 0 corresponds to UID 1000000 on the host.</p>
<h3>Step 5: Work with Volumes – ID‑mapped Mounts at Work</h3>
<p>A critical enabler for User Namespaces is <strong>ID‑mapped mounts</strong>, introduced in Linux 5.12. When you attach a PersistentVolume or a hostPath volume to a Pod with <code>hostUsers: false</code>, the kernel automatically remaps file ownership at mount time. For example, if the volume has files owned by UID 1000000 on disk, the container sees them as owned by UID 0. No <code>chown</code> is needed, even for large volumes. This is an O(1) operation and does not affect start‑up performance.</p>
<p>To test, attach a volume to your Pod and check file permissions inside the container versus on the host. Inside the container, files will appear owned by root; on the host, they remain with the high UID.</p>
<h3>Step 6: Use Namespaced Capabilities (e.g., CAP_NET_ADMIN)</h3>
<p>One of the most powerful benefits of User Namespaces is that capabilities become <strong>namespaced</strong>. For example, granting <code>CAP_NET_ADMIN</code> inside a Pod with <code>hostUsers: false</code> gives the container control over its own network namespace (e.g., creating virtual interfaces) without affecting the host network. This was previously only possible by running a fully privileged container. Add the capability in the security context:</p>
<pre><code>securityContext:
capabilities:
add: ["NET_ADMIN"]</code></pre>
<p>Now the container can run network‑related commands that would normally require root, but the host remains secure. Test this by execing into the container and running <code>ip link add dummy0 type dummy</code> – it should succeed.</p>
<h2>Tips and Best Practices</h2>
<ul>
<li><strong>Always test with non‑production workloads first.</strong> While the feature is GA, ensure your applications handle the remapped UIDs correctly, especially when reading file ownership from volumes.</li>
<li><strong>Combine with Pod Security Standards.</strong> User Namespaces complement, but do not replace, other security measures like seccomp, AppArmor, and network policies.</li>
<li><strong>Monitor kernel version.</strong> ID‑mapped mounts require Linux kernel 5.12+. Older kernels will fall back to slow recursive <code>chown</code>, degrading performance. Verify your nodes’ kernel versions.</li>
<li><strong>Use <code>hostUsers: false</code> as a default.</strong> Consider mutating webhooks or Pod security admission to enforce it for all workloads. This drastically reduces the risk of breakout exploits.</li>
<li><strong>Check runtime support.</strong> Not all container runtimes support user namespaces yet. If you encounter errors, upgrade your runtime to a version that explicitly supports this feature (e.g., containerd 1.6+, CRI‑O 1.24+).</li>
<li><strong>Remember: Linux only.</strong> This feature does not apply to Windows nodes. Ensure your Pods are scheduled only on Linux nodes when using <code>hostUsers: false</code>.</li>
</ul>
<p>By following these steps, you can leverage Kubernetes v1.36’s User Namespaces to run containers with root privileges internally while keeping the host safe—a long‑awaited milestone for secure, rootless container orchestration.</p>