Docker Internals: Isolation Without Virtualization

Containers feel like virtual machines but they're not. Here's what's actually happening.

VMs vs Containers (The Real Difference)

Virtual Machine:

Hardware
→ Hypervisor (VMware/VirtualBox)
  → Full Guest OS (entire Linux/Windows)
    → Your app

Container:

Hardware
→ Host OS
  → Docker Engine
    → Your app (shares host kernel!)

Key insight: Containers share the OS kernel. VMs don't.

Result: Containers start in milliseconds, VMs take minutes.

The Three Linux Tricks Docker Uses

1. Namespaces (Isolation)

Linux can create isolated views of system resources:

PID Namespace:

# Inside container
ps aux  # Shows only container processes

# On host
ps aux  # Shows ALL processes including container's

Container thinks it's alone. It's not.

Other namespaces:

  • Network (own IP, ports)
  • Mount (own filesystem)
  • User (own user IDs)
  • UTS (own hostname)

2. cgroups (Resource Limits)

docker run -m 512m --cpus=1.5 myapp

Linux cgroups enforce:

  • Max memory usage
  • CPU allocation
  • Disk I/O limits
  • Network bandwidth

Prevents: One container hogging all resources.

3. Union Filesystem (Layers)

Docker images stack like transparencies:

FROM ubuntu:20.04        # Layer 1: OS
RUN apt-get install python  # Layer 2: Python
COPY app.py /app/       # Layer 3: Your code

Benefits:

  • Share common layers (saves space)
  • Fast builds (only rebuild changed layers)
  • Easy rollbacks (swap layers)

What Happens When You docker run

docker run -d -p 8080:80 nginx
  1. Pull image (if not local)
  2. Create namespaces (isolate process)
  3. Set cgroups (resource limits)
  4. Mount layers (union filesystem)
  5. Start process (runs nginx)

Time: Under 1 second.

Security: Better Than You Think

Isolation:

  • Process can't see host filesystem (unless you mount it)
  • Can't see other containers
  • Network isolated by default
  • User namespace (root in container ≠ root on host)

Not perfect:

  • Shares kernel (kernel exploits affect all)
  • Default capabilities too permissive
  • Misconfigurations common

Best practice: Run containers as non-root user.

Why Kubernetes Exists

Docker runs containers. Kubernetes orchestrates them:

  • 100 containers across 10 servers
  • Automatic restarts if crashed
  • Load balancing
  • Rolling updates
  • Secret management

Docker = run one container Kubernetes = manage thousands

Try It

Run Ubuntu in a container:

docker run -it ubuntu bash

You're now "inside" a Linux system. But it shares your kernel.

Type ps aux - See only container processes.

Type exit - Back to host.


Related: Our Docker deployment tutorial Fun fact: This blog runs in Docker containers on AWS! EOF