> ## Content Index
> Fetch the complete content index at: https://debugly.dev/llms.txt
> Use this file to discover other available public pages before exploring further.

# What a Container Actually Isolates, and the Thing It Does Not
- URL: https://debugly.dev/container-namespace-does-not-isolate/
- Published: 2026-10-09T18:19:00.000Z
- Updated: 2026-10-17T05:55:27.000Z
- Description: The namespaces hide the view and the cgroups cap the usage, and the kernel is shared, so the isolation is a boundary of visibility rather than a wall…
- Author: Rohit Bhadani
- Tags: Deep Dive, Docker, Security

Start at the container and you miss it. Start at the different tool and you miss how it arrived. The bug lived in the hand-off.

This is the anatomy of the container's isolation, and of the specific property that makes the word misleading: a container is a set of kernel features that limit what a process can see and use, and the kernel that enforces those limits is the same kernel the process runs on.

This applies to Docker and Kubernetes on Linux, and the mechanics are the same for any container runtime that uses namespaces and cgroups.

## What the namespaces actually do

The PID namespace is the process list, and the process list is the view, and the view is the limited, and the limited is the other processes' invisibility, and the invisibility is the not the prevention, and the not prevention is the kernel's shared scheduler, and the shared is the boundary's nature.

The mount namespace is the filesystem tree, and the tree is the view, and the view is the container's root, and the root is the image's, and the image's is the not the host's, and the not host's is the isolation, and the isolation is the visible files, and the visible is the not the kernel's modules.

The network namespace is the interfaces and the ports, and the ports are the separate, and the separate is the no conflict, and the no conflict is the isolation, and the isolation is the stack's copy, and the copy is the not the physical NIC, and the NIC is the shared, and the shared is the boundary.

The user namespace is the UID mapping, and the mapping is the root inside and the unprivileged outside, and the outside is the mitigation, and the mitigation is the real, and the real is the strongest of the namespaces, and the strongest is the not the default, and the not default is the reason the container's root is the host's root in the common configuration.

## What the cgroups actually do

The cgroup is the limit, and the limit is the CPU and the memory and the IO, and the three are the usage's cap, and the cap is the fairness, and the fairness is the noisy neighbour's prevention, and the prevention is the isolation of the resource, and the resource is the not the security boundary, and the boundary is the different thing.

The cgroup is the accounting, and the accounting is the enforcement, and the enforcement is the kernel's, and the kernel's is the shared, and the shared is the syscall's surface, and the surface is the attack's target, and the target is the not the namespace's concern.

## The thing it does not isolate

The kernel is the shared, and the shared is the syscall interface, and the interface is the every container's, and the every container's is the untrusted code's reach, and the reach is the vulnerability's surface, and the surface is the CVE, and the CVE is the escape, and the escape is the host, and the host is the every container, and the every container is the blast radius.

The isolation is the visibility and the resource, and the not isolation is the kernel, and the kernel is the trust's root, and the root is the shared, so the container is the boundary between the processes and not between the trust domains, and the trust domain is the VM's job, and the VM's job is the different tool.

This is the same distinction as [the node that evicted everything because the disk filled](https://debugly.dev/node-disk-pressure-evicted-pods/), same mechanism, different costume.

## What to do about it

**Run the container as a non-root user.** The user is the unprivileged, and the unprivileged is the escape's difficulty, and the difficulty is the mitigation, and the mitigation is the fix, and the fix is the Dockerfile's USER, and the USER is the one line, and the line is the discipline.

**Drop the capabilities and use a restrictive seccomp profile.** The capabilities are the kernel's permissions, and the permissions are the dropped, and the dropped is the surface's reduction, and the reduction is the fix, and the fix is the security context, and the context is the discipline.

**Make the filesystem read-only where possible.** The read-only is the write's prevention, and the prevention is the persistence's absence, and the absence is the fix, and the fix is the flag, and the flag is the discipline, because the writable container filesystem is the attacker's workspace.

**Use the user namespace remapping for the untrusted workloads.** The remapping is the root's demotion, and the demotion is the host's protection, and the protection is the fix, and the fix is the runtime's configuration, and the configuration is the discipline.

**Put the genuinely untrusted code in a microVM.** The microVM is the kernel's separation, and the separation is the real boundary, and the boundary is the fix, and the fix is the Firecracker or the gVisor, and the two are the tools, and the tools are the discipline, because the container is the wrong tool for the code you do not trust.

## The rule

A container isolates the view through namespaces and the resource usage through cgroups, but the kernel is shared, so a kernel vulnerability is an escape to the host and to every other container. Run as non-root, drop capabilities, use seccomp, make the filesystem read-only, and put genuinely untrusted code in a microVM.

The container was described as isolated and it was, in the sense that it could not see the other processes or exceed its memory limit, and it was not, in the sense that it made system calls into the same kernel as every other container on the node. I now check for that property first, because it is where the failure actually lives.

---

Published on [debugly.dev](https://debugly.dev/) by [Rohit Bhadani](https://debugly.dev/about/) | Founder of [Krova Cloud](https://krova.cloud/?ref=debugly.dev)