Skip to main content

Container Isolation

The security boundaries that Linux namespaces and cgroups create around a container process, limiting its view of the filesystem, network, processes, and system resources. Container isolation is weaker than VM isolation — all containers share the host kernel.

Container Isolation — What Separates Containers From Each Other

What Is Container Isolation in Simple Terms?

Container isolation is the set of boundaries Docker creates around each container process. These boundaries are implemented by the Linux kernel using two technologies: namespaces (which control what the process can see) and cgroups (which control what resources it can use).

The important thing to understand: containers are NOT virtual machines. They share the host kernel. The isolation is real and effective for most purposes, but it is not as complete as VM isolation.

◈ DIAGRAM
+------------------------------------------+
| Virtual Machine Isolation |
| Complete OS boundary |
| Different kernel per VM |
| Kernel exploit in one VM: |
| cannot affect other VMs |
| Escape difficulty: very high |
+------------------------------------------+
+------------------------------------------+
| Container Isolation |
| Namespace + cgroup boundary |
| Shared kernel |
| Kernel exploit: |
| could affect all containers on host |
| Escape difficulty: moderate |
| But: more than enough for most workloads |
+------------------------------------------+

The Six Namespaces Docker Uses

Bash
# PID namespace — container has its own process tree
# Container sees PID 1 (nginx), host sees PID 12345
docker exec my-nginx ps aux
# PID 1 = nginx master
ps aux | grep nginx
# PID 12345 = nginx master (same process, different view)
# NET namespace — container has own network interfaces
docker exec my-nginx ip addr
# eth0: 172.17.0.2 <- container sees its own interface
ip addr # on host
# docker0: 172.17.0.1 <- host sees bridge interface
# MNT namespace — container has own filesystem view
# /etc/nginx/nginx.conf exists in container
# same path does not exist on host
# UTS namespace — container has own hostname
docker exec my-nginx hostname
# a84f9c2b1d3e <- container ID as hostname
hostname # on host
# prod-server-01

cgroups — Resource Isolation

Bash
# Set memory and CPU limits
docker run -d \
--memory=512m \
--cpus=1.5 \
payment-api:latest
# Kernel enforces these limits
# Memory exceeded: process killed (OOMKill)
# CPU exceeded: process throttled
# Verify cgroup limits are set
cat /sys/fs/cgroup/memory/docker/$(docker inspect \
--format '{{.Id}}' payment-api)/memory.limit_in_bytes
# 536870912 = 512MB

Isolation Limitations

TEXT
What containers DO isolate:
Filesystem (each container has its own view)
Network (each container has its own interfaces)
Processes (containers cannot see each other's processes)
Hostname (each container has its own hostname)
Resources (cgroups limit CPU and memory)
What containers do NOT isolate:
The Linux kernel (shared by all containers)
Kernel vulnerabilities (affect all containers on host)
Time (containers share host clock)
System calls (containers use host kernel syscalls)
Security

Container isolation is sufficient for running trusted workloads on a shared host. For running untrusted code (like user-submitted programs), consider stronger isolation: gVisor (Google's container runtime with its own kernel), Kata Containers (lightweight VMs), or Firecracker (microVMs used by AWS Lambda and Fargate). These provide VM-level isolation with container-level startup speed.

Frequently Asked Questions

What exactly does container isolation prevent, and what does it not prevent?

Namespaces give a container its own view of the filesystem, network interfaces, process tree, and hostname, so processes inside can't see or directly interact with processes, files, or network sockets outside their namespace by default. What it doesn't provide is kernel isolation — every container on a host shares that one kernel, so a kernel vulnerability or a container running with excessive capabilities can potentially break out, which is fundamentally different from a hypervisor-isolated VM.

What's a common container isolation mistake in production?

Running containers as root inside the container (the default unless a Dockerfile specifies USER) and/or granting `--privileged` mode for convenience during debugging, then shipping that config to production. A root process inside a container that escapes isolation becomes root on the host. Best practice: run as a non-root user, drop unnecessary Linux capabilities explicitly, and use read-only root filesystems where the application allows it.