Containers Deep Dive
Containers have revolutionized how we deploy applications. Let's understand how they work at a fundamental level.
What Makes a Container?
A container is NOT a virtual machine. It's a combination of Linux kernel features that provide isolation:
- Namespaces - Isolate what processes can see
- Cgroups - Limit what resources processes can use
- Union Filesystems - Layer filesystems efficiently
Linux Namespaces
Namespaces create isolated views of system resources. Each container gets its own namespace for:
| Namespace | Isolates |
|---|---|
| PID | Process IDs - Container sees its processes starting from PID 1 |
| Network | Network interfaces, IP addresses, ports |
| Mount | Filesystem mount points |
| UTS | Hostname and domain name |
| IPC | Inter-process communication |
| User | User and group IDs |
# On host: thousands of processes
$ ps aux | wc -l
247
# Inside container: only container processes
$ docker exec mycontainer ps aux
PID USER COMMAND
1 root /app/server
12 root ps aux
Control Groups (cgroups)
Cgroups limit and account for resource usage:
Container Resource Limits:
CPU: 2 cores (or 200% CPU time)
Memory: 4GB (hard limit)
Memory Swap: 8GB
Disk I/O: 100 MB/s
When a container exceeds its memory limit, it gets killed (OOMKilled).
Container Images
A container image is a read-only template containing:
- Application code
- Runtime (Python, Node.js, etc.)
- Libraries and dependencies
- Environment configuration
Image Layers
Images are built in layers, each layer representing a change:
FROM python:3.11-slim # Layer 1: Base Python image
COPY requirements.txt . # Layer 2: Add requirements file
RUN pip install -r req... # Layer 3: Install dependencies
COPY . /app # Layer 4: Add application code
CMD ["python", "app.py"] # Layer 5: Define startup command
┌─────────────────────────┐
│ Layer 5: CMD │ (Read-only)
├─────────────────────────┤
│ Layer 4: App code │ (Read-only)
├─────────────────────────┤
│ Layer 3: Dependencies │ (Read-only)
├─────────────────────────┤
│ Layer 2: requirements │ (Read-only)
├─────────────────────────┤
│ Layer 1: Base image │ (Read-only)
└─────────────────────────┘
Copy-on-Write
When a container runs, a thin writable layer is added on top:
┌─────────────────────────┐
│ Writable Container │ ← Changes go here
│ Layer │
├─────────────────────────┤
│ Image Layers │ (Read-only, shared)
│ (shared between │
│ containers) │
└─────────────────────────┘
This is why containers are so efficient - 100 containers from the same image share the base layers!
Docker Architecture
┌──────────────────────────────────────────┐
│ Docker CLI │
│ (docker run, build, etc.) │
└────────────────────┬─────────────────────┘
│ REST API
┌────────────────────┴─────────────────────┐
│ Docker Daemon │
│ (dockerd - background service) │
├──────────────────────────────────────────┤
│ containerd │
│ (container lifecycle management) │
├──────────────────────────────────────────┤
│ runc │
│ (OCI runtime - creates containers) │
└──────────────────────────────────────────┘
Container Lifecycle
# Create and start
docker run -d --name myapp nginx
# Lifecycle states
Created → Running → Paused → Running → Stopped → Removed
↑ ↓
└───────────────────┘
(restart)
Container Networking
Containers can be connected in various ways:
Bridge Network (Default)
┌─────────────────────────────────────┐
│ Docker Bridge │
│ (172.17.0.0/16) │
├─────────┬─────────┬─────────────────┤
│ Container│Container│ │
│ .2 │ .3 │ │
└─────────┴─────────┴─────────────────┘
Host Network
Container uses the host's network directly (best performance).
Custom Networks
Create isolated networks for specific applications.
Container Storage
- Volumes: Persistent storage managed by Docker
- Bind Mounts: Map host directory into container
- tmpfs: In-memory storage (fast but temporary)
# Volume example
docker run -v mydata:/app/data myimage
# Bind mount example
docker run -v /host/path:/container/path myimage
Advantages of Containers
- Lightweight - Share kernel, MBs not GBs
- Fast Startup - Seconds, not minutes
- Portable - "Works on my machine" solved
- Efficient - Higher density than VMs
- Immutable - Same image runs everywhere
- Version Control - Images can be tagged and tracked
Disadvantages of Containers
- Same Kernel - Can only run Linux containers on Linux
- Security - Weaker isolation than VMs
- Stateful Apps - More complex to handle persistent data
- Networking - Can be complex to configure
- Monitoring - Need container-aware tools
Container Orchestration
For production, you need orchestration:
- Kubernetes - Industry standard
- Docker Swarm - Simple, built into Docker
- Nomad - HashiCorp's alternative
These handle:
- Scheduling containers across hosts
- Service discovery
- Load balancing
- Rolling updates
- Self-healing
What's Next?
Now that you understand both VMs and Containers in depth, let's compare them side-by-side in the next chapter.