- What is a Container?
- Linux Technologies Behind Containers
- Container Architecture
- Containers vs Virtual Machines
- Container Images and Layers
- Container Runtimes
- Container Lifecycle
- Benefits and Use Cases
At its core, a container is just a Linux process — but with special powers that make it think it's running in its own isolated system.
┌─────────────────────────────────────────────────────────────┐
│ The Evolution of Application Deployment │
├─────────────────────────────────────────────────────────────┤
│ │
│ TRADITIONAL (Physical Servers) │
│ ┌────────────────────────────────────────────────────┐ │
│ │ Server 1 Server 2 Server 3 │ │
│ │ ┌──────────┐ ┌──────────┐ ┌──────────┐ │ │
│ │ │ App A │ │ App B │ │ App C │ │ │
│ │ │ │ │ │ │ │ │ │
│ │ │ ┌──────┐ │ │ ┌──────┐ │ │ ┌──────┐ │ │ │
│ │ │ │ OS │ │ │ │ OS │ │ │ │ OS │ │ │ │
│ │ │ └──────┘ │ │ └──────┘ │ │ └──────┘ │ │ │
│ │ │ Hardware │ │ Hardware │ │ Hardware │ │ │
│ │ └──────────┘ └──────────┘ └──────────┘ │ │
│ └────────────────────────────────────────────────────┘ │
│ │
│ Problems: │
│ ❌ One app per server (waste of resources) │
│ ❌ Expensive hardware for each app │
│ ❌ Slow deployment (days/weeks) │
│ ❌ Hard to scale │
│ ❌ Environment inconsistencies │
│ │
├─────────────────────────────────────────────────────────────┤
│ │
│ VIRTUALIZED (Virtual Machines) │
│ ┌────────────────────────────────────────────────────┐ │
│ │ Single Physical Server │ │
│ │ ┌──────────┐ ┌──────────┐ ┌──────────┐ │ │
│ │ │ VM 1 │ │ VM 2 │ │ VM 3 │ │ │
│ │ │ App A │ │ App B │ │ App C │ │ │
│ │ │┌────────┐│ │┌────────┐│ │┌────────┐│ │ │
│ │ ││Guest OS││ ││Guest OS││ ││Guest OS││ │ │
│ │ │└────────┘│ │└────────┘│ │└────────┘│ │ │
│ │ └──────────┘ └──────────┘ └──────────┘ │ │
│ │ ┌──────────────────────────────────────────┐ │ │
│ │ │ Hypervisor (VMware/KVM) │ │ │
│ │ └──────────────────────────────────────────┘ │ │
│ │ ┌──────────────────────────────────────────┐ │ │
│ │ │ Host Operating System │ │ │
│ │ └──────────────────────────────────────────┘ │ │
│ │ ┌──────────────────────────────────────────┐ │ │
│ │ │ Physical Hardware │ │ │
│ │ └──────────────────────────────────────────┘ │ │
│ └────────────────────────────────────────────────────┘ │
│ │
│ Improvements: │
│ ✅ Better resource utilization │
│ ✅ Multiple apps on one server │
│ ✅ Isolation between apps │
│ │
│ But still: │
│ ❌ Heavy (full OS per VM = GBs) │
│ ❌ Slow boot (minutes) │
│ ❌ Resource overhead (multiple OS copies) │
│ │
├─────────────────────────────────────────────────────────────┤
│ │
│ CONTAINERIZED (Modern Approach) │
│ ┌────────────────────────────────────────────────────┐ │
│ │ Single Physical Server │ │
│ │ ┌────────┐ ┌────────┐ ┌────────┐ ┌────────┐ │ │
│ │ │Container │Container │Container │Container │ │
│ │ │ App A │ │ App B │ │ App C │ │ App D │ │ │
│ │ │ +Libs │ │ +Libs │ │ +Libs │ │ +Libs │ │ │
│ │ └────────┘ └────────┘ └────────┘ └────────┘ │ │
│ │ ┌──────────────────────────────────────────┐ │ │
│ │ │ Container Runtime (Docker/containerd) │ │ │
│ │ └──────────────────────────────────────────┘ │ │
│ │ ┌──────────────────────────────────────────┐ │ │
│ │ │ Host Operating System │ │ │
│ │ │ (Shared Kernel) │ │ │
│ │ └──────────────────────────────────────────┘ │ │
│ │ ┌──────────────────────────────────────────┐ │ │
│ │ │ Physical Hardware │ │ │
│ │ └──────────────────────────────────────────┘ │ │
│ └────────────────────────────────────────────────────┘ │
│ │
│ Advantages: │
│ ✅ Lightweight (MBs vs GBs) │
│ ✅ Fast startup (milliseconds) │
│ ✅ High density (100s per server) │
│ ✅ Shared kernel = less overhead │
│ ✅ Portable across environments │
│ ✅ Consistent from dev to production │
│ ✅ Easy to scale horizontally │
│ │
└─────────────────────────────────────────────────────────────┘
- Isolated: Has its own view of the system (processes, network, filesystem)
- Lightweight: Shares the host kernel (no OS overhead like VMs)
- Portable: Runs consistently across different environments
- Fast: Starts in milliseconds (no OS boot required)
- Efficient: Minimal resource overhead
┌─────────────────────────────────────────────────────────────┐
│ Container Concept │
├─────────────────────────────────────────────────────────────┤
│ │
│ Host Operating System (Linux) │
│ ┌─────────────────────────────────────────────────────┐ │
│ │ Linux Kernel (Shared) │ │
│ │ ┌──────────────┐ ┌──────────────┐ ┌──────────────┐ │ │
│ │ │ Container 1 │ │ Container 2 │ │ Container 3 │ │ │
│ │ │ │ │ │ │ │ │ │
│ │ │ App + Libs │ │ App + Libs │ │ App + Libs │ │ │
│ │ │ │ │ │ │ │ │ │
│ │ │ Namespaces │ │ Namespaces │ │ Namespaces │ │ │
│ │ │ cgroups │ │ cgroups │ │ cgroups │ │ │
│ │ └──────────────┘ └──────────────┘ └──────────────┘ │ │
│ └─────────────────────────────────────────────────────┘ │
│ │
└─────────────────────────────────────────────────────────────┘
Unlike traditional applications, containers include:
- ✅ Application code
- ✅ Runtime dependencies (libraries, binaries)
- ✅ Configuration files
- ✅ Environment variables
- ✅ Everything needed to run the app
Containers leverage fundamental Linux kernel features to provide isolation and resource control.
Namespaces provide isolated views of system resources. Each container gets its own namespace, making it think it's the only process on the system.
┌────────────────────────────────────────────────┐
│ Linux Namespaces │
├────────────────────────────────────────────────┤
│ │
│ ┌─────────────┐ ┌─────────────┐ │
│ │ Container A │ │ Container B │ │
│ ├─────────────┤ ├─────────────┤ │
│ │ PID NS │ │ PID NS │ │
│ │ • PID 1 │ │ • PID 1 │ │
│ │ • PID 2 │ │ • PID 2 │ │
│ ├─────────────┤ ├─────────────┤ │
│ │ NET NS │ │ NET NS │ │
│ │ • eth0 │ │ • eth0 │ │
│ │ • 10.8.0.5 │ │ • 10.8.0.6 │ │
│ ├─────────────┤ ├─────────────┤ │
│ │ MNT NS │ │ MNT NS │ │
│ │ • /app │ │ • /app │ │
│ │ • /data │ │ • /data │ │
│ └─────────────┘ └─────────────┘ │
│ │
│ Host sees different PIDs: 12345, 12346 │
│ Containers see: PID 1, PID 1 │
│ │
└────────────────────────────────────────────────┘
| Namespace | Kernel Flag | What It Isolates | Example |
|---|---|---|---|
| PID | CLONE_NEWPID |
Process IDs | Container PID 1 is host PID 12345 |
| NET | CLONE_NEWNET |
Network interfaces, IPs, ports | Each container has own eth0, IP |
| MNT | CLONE_NEWNS |
Mount points, filesystems | Container has own /, /proc |
| UTS | CLONE_NEWUTS |
Hostname and domain name | Container has own hostname |
| IPC | CLONE_NEWIPC |
Inter-process communication | Shared memory, semaphores, queues |
| USER | CLONE_NEWUSER |
User and group IDs | Root in container ≠ root on host |
| Cgroup | CLONE_NEWCGROUP |
Cgroup root directory | Virtualized cgroup view |
Example: PID Namespace in Action
# On the host
$ ps aux | grep nginx
root 12345 nginx: master process
# Inside the container
$ ps aux
PID USER COMMAND
1 root nginx: master process
2 root nginx: worker processThe container process thinks it's PID 1, but the host sees it as PID 12345!
cgroups limit and account for resource usage. They ensure containers don't consume more than their allocated share of resources.
┌─────────────────────────────────────────────────────────────┐
│ cgroups Hierarchy │
├─────────────────────────────────────────────────────────────┤
│ │
│ System Resources │
│ ┌───────────────────────────────────────────────────┐ │
│ │ CPU: 4 cores │ Memory: 16 GB │ Disk I/O │ │
│ └───────────────────────────────────────────────────┘ │
│ │ │
│ ┌───────────┼───────────┐ │
│ ▼ ▼ ▼ │
│ ┌────────────┐ ┌────────────┐ ┌────────────┐ │
│ │Container A │ │Container B │ │Container C │ │
│ ├────────────┤ ├────────────┤ ├────────────┤ │
│ │CPU: 1 core │ │CPU: 2 cores│ │CPU: 0.5 │ │
│ │Mem: 512MB │ │Mem: 4GB │ │Mem: 1GB │ │
│ │I/O: 10MB/s │ │I/O: 50MB/s │ │I/O: 5MB/s │ │
│ └────────────┘ └────────────┘ └────────────┘ │
│ │
└─────────────────────────────────────────────────────────────┘
| Controller | What It Controls | Example Configuration |
|---|---|---|
| cpu | CPU time, shares, quotas | --cpus=2 or --cpu-shares=512 |
| memory | RAM usage, limits, OOM behavior | --memory=1g --memory-swap=2g |
| blkio | Block I/O (disk read/write) | --device-read-bps /dev/sda:10mb |
| cpuset | CPU and memory node assignment | --cpuset-cpus=0,1 |
| devices | Device access permissions | --device /dev/sda:/dev/xvda:r |
| pids | Number of processes/threads | --pids-limit=100 |
| net_cls | Network traffic classification | Used for QoS tagging |
Example: Memory Limits
# Run container with 512MB RAM limit
docker run -m 512m nginx
# What happens:
# 1. cgroup memory controller monitors usage
# 2. If container tries to use > 512MB
# 3. Kernel OOM killer terminates processes
# 4. Container may be restarted (depends on policy)Union filesystems allow multiple directories to be overlaid, appearing as a single merged directory. This enables the layered image structure.
┌─────────────────────────────────────────────────────────────┐
│ Union Filesystem Layers │
├─────────────────────────────────────────────────────────────┤
│ │
│ Container View: Single /filesystem │
│ ┌───────────────────────────────────────────────────┐ │
│ │ /app, /etc, /usr, /var (Merged view) │ │
│ └───────────────────────────────────────────────────┘ │
│ ▲ │
│ │ │
│ ┌─────────────────────┴─────────────────────────────┐ │
│ │ Container Layer (Read-Write) │ │
│ │ • Log files • Temp files • Changes │ │
│ ├───────────────────────────────────────────────────┤ │
│ │ Application Layer (Read-Only) │ │
│ │ • App binaries • Dependencies │ │
│ ├───────────────────────────────────────────────────┤ │
│ │ Base OS Layer (Read-Only) │ │
│ │ • /bin • /usr • /lib │ │
│ └───────────────────────────────────────────────────┘ │
│ │
│ Common implementations: OverlayFS, AUFS, Btrfs │
│ │
└─────────────────────────────────────────────────────────────┘
┌─────────────────────────────────────────────────────────────┐
│ Container Process Architecture │
├─────────────────────────────────────────────────────────────┤
│ │
│ Host System (Linux) │
│ ┌─────────────────────────────────────────────────────┐ │
│ │ Kernel Space │ │
│ │ ├─ Scheduler (CPU allocation) │ │
│ │ ├─ Memory Management │ │
│ │ ├─ Network Stack │ │
│ │ └─ Device Drivers │ │
│ └────────────────┬────────────────────────────────────┘ │
│ │ │
│ ┌────────────────┴────────────────────────────────────┐ │
│ │ User Space │ │
│ │ │ │
│ │ Container Runtime (Docker/containerd) │ │
│ │ ├─ Image Management │ │
│ │ ├─ Container Lifecycle │ │
│ │ └─ API/CLI Interface │ │
│ │ │ │
│ │ ┌──────────────────────────────────────────────┐ │ │
│ │ │ Container Process Tree │ │ │
│ │ │ ┌────────────────────────────────────────┐ │ │ │
│ │ │ │ PID 1 (init/app) │ │ │ │
│ │ │ │ └─ PID 2 (child process) │ │ │ │
│ │ │ │ └─ PID 3 (worker) │ │ │ │
│ │ │ └────────────────────────────────────────┘ │ │ │
│ │ │ │ │ │
│ │ │ Namespaces: PID, NET, MNT, UTS, IPC, USER │ │ │
│ │ │ cgroups: CPU, Memory, I/O limits │ │ │
│ │ │ Capabilities: Dropped privileges │ │ │
│ │ └──────────────────────────────────────────────┘ │ │
│ └─────────────────────────────────────────────────────┘ │
│ │
└─────────────────────────────────────────────────────────────┘
┌─────────────────────────────────────────────────────────────┐
│ Container Network Architecture │
├─────────────────────────────────────────────────────────────┤
│ │
│ ┌────────────────────────────────────────────────────┐ │
│ │ Physical Network (eth0: 192.168.1.10) │ │
│ └────────────────┬───────────────────────────────────┘ │
│ │ │
│ ┌────────────────┴──────────────────────────────────┐ │
│ │ Host Namespace │ │
│ │ ┌─────────────────────────────────────────────┐ │ │
│ │ │ Bridge: docker0 (172.17.0.1) │ │ │
│ │ │ ├─ NAT rules (iptables) │ │ │
│ │ │ └─ Port forwarding │ │ │
│ │ └──────┬──────────┬─────────┬─────────────────┘ │ │
│ │ │ │ │ │ │
│ │ ┌────┴──┐ ┌────┴──┐ ┌───┴────┐ │ │
│ │ │ veth0 │ │ veth1 │ │ veth2 │ (host side) │ │
│ └────┴───────┴──┴───────┴──┴────────┴───────────────┘ │
│ │ │ │ │
│ │ │ │ │
│ ┌──────┴──┐ ┌───┴─────┐ ┌─┴────────┐ │
│ │Container│ │Container│ │Container │ │
│ │ 1 │ │ 2 │ │ 3 │ │
│ │ │ │ │ │ │ │
│ │ eth0 │ │ eth0 │ │ eth0 │ (container side) │
│ │172.17. │ │172.17. │ │172.17. │ │
│ │ 0.2 │ │ 0.3 │ │ 0.4 │ │
│ └─────────┘ └─────────┘ └──────────┘ │
│ │
└─────────────────────────────────────────────────────────────┘
┌──────────────────────────────────────────────────────────────┐
│ Virtual Machines vs Containers │
├──────────────────────────────────────────────────────────────┤
│ │
│ VIRTUAL MACHINES CONTAINERS │
│ ┌────────────────────┐ ┌────────────────────┐ │
│ │ VM 1 │ │ Container 1 │ │
│ │ ┌──────────────┐ │ │ ┌──────────────┐ │ │
│ │ │ App │ │ │ │ App │ │ │
│ │ ├──────────────┤ │ │ ├──────────────┤ │ │
│ │ │ Binaries │ │ │ │ Binaries │ │ │
│ │ ├──────────────┤ │ │ └──────────────┘ │ │
│ │ │ Guest OS │ │ └────────────────────┘ │
│ │ │ (Full OS) │ │ │
│ │ └──────────────┘ │ ┌────────────────────┐ │
│ └────────────────────┘ │ Container 2 │ │
│ ┌────────────────────┐ │ ┌──────────────┐ │ │
│ │ VM 2 │ │ │ App │ │ │
│ │ ┌──────────────┐ │ │ ├──────────────┤ │ │
│ │ │ App │ │ │ │ Binaries │ │ │
│ │ ├──────────────┤ │ │ └──────────────┘ │ │
│ │ │ Binaries │ │ └────────────────────┘ │
│ │ ├──────────────┤ │ │
│ │ │ Guest OS │ │ ┌──────────────────────────┐ │
│ │ │ (Full OS) │ │ │ Container Runtime │ │
│ │ └──────────────┘ │ │ (Docker/containerd) │ │
│ └────────────────────┘ └──────────────────────────┘ │
│ ┌────────────────────────────────────────────────────────┐ │
│ │ Hypervisor (ESXi, KVM, Hyper-V) │ │
│ └────────────────────────────────────────────────────────┘ │
│ ┌────────────────────────────────────────────────────────┐ │
│ │ Host Operating System │ │
│ └────────────────────────────────────────────────────────┘ │
│ ┌────────────────────────────────────────────────────────┐ │
│ │ Physical Hardware │ │
│ └────────────────────────────────────────────────────────┘ │
│ │
└──────────────────────────────────────────────────────────────┘
| Feature | Virtual Machines | Containers |
|---|---|---|
| Isolation | Complete (hardware-level) | Process-level (namespaces) |
| OS | Full OS per VM | Shared host kernel |
| Boot Time | Minutes | Milliseconds |
| Size | GBs (entire OS) | MBs (app + dependencies) |
| Performance | Overhead from virtualization | Near-native performance |
| Resource Usage | High (multiple OS instances) | Low (shared kernel) |
| Portability | Limited (hypervisor-specific) | High (runs anywhere) |
| Security | Strong (hardware isolation) | Good (kernel-level isolation) |
| Density | Low (5-10 VMs/host) | High (100s containers/host) |
| Use Case | Full OS needed, legacy apps | Microservices, cloud-native apps |
┌──────────────────────────────────────────────────────────────┐
│ Resource Efficiency │
├──────────────────────────────────────────────────────────────┤
│ │
│ Scenario: Running 10 web applications │
│ │
│ Virtual Machines: │
│ ┌────────────────────────────────────────────────┐ │
│ │ 10 VMs × 2GB RAM = 20GB RAM │ │
│ │ 10 VMs × 20GB Disk = 200GB Disk │ │
│ │ Boot time: 10 VMs × 2min = 20 minutes │ │
│ └────────────────────────────────────────────────┘ │
│ │
│ Containers: │
│ ┌────────────────────────────────────────────────┐ │
│ │ 10 Containers × 100MB RAM = 1GB RAM │ │
│ │ 10 Containers × 100MB Disk = 1GB Disk │ │
│ │ Boot time: 10 Containers × 1s = 10 seconds │ │
│ └────────────────────────────────────────────────┘ │
│ │
│ Savings: 95% RAM, 99.5% Disk, 99% faster startup │
│ │
└──────────────────────────────────────────────────────────────┘
Container images are built in layers, where each layer represents a filesystem diff. This enables efficient storage and sharing.
┌─────────────────────────────────────────────────────────────┐
│ Container Image Layers │
├─────────────────────────────────────────────────────────────┤
│ │
│ Dockerfile Instructions → Image Layers │
│ │
│ FROM ubuntu:20.04 │
│ └─► Layer 1: [Ubuntu base] 75 MB │
│ │
│ RUN apt-get update && apt-get install -y python3 │
│ └─► Layer 2: [Python installed] +120 MB │
│ │
│ COPY app.py /app/ │
│ └─► Layer 3: [App code] +5 KB │
│ │
│ RUN pip3 install flask │
│ └─► Layer 4: [Dependencies] +50 MB │
│ │
│ CMD ["python3", "/app/app.py"] │
│ └─► Layer 5: [Metadata] +1 KB │
│ │
│ Total Image Size: ~245 MB │
│ │
│ When running: │
│ └─► Layer 6: [Container layer] (Read-Write) │
│ • Logs, temp files, runtime data │
│ │
└─────────────────────────────────────────────────────────────┘
Multiple containers can share base layers:
┌─────────────────────────────────────────────────────────────┐
│ Layer Sharing │
├─────────────────────────────────────────────────────────────┤
│ │
│ Container 1 Container 2 Container 3 │
│ (nginx) (apache) (nginx-custom) │
│ ┌─────────────┐ ┌─────────────┐ ┌─────────────┐ │
│ │ Nginx cfg │ │ Apache cfg │ │ Custom cfg │ │
│ ├─────────────┤ ├─────────────┤ ├─────────────┤ │
│ │ Nginx binary│ │Apache binary│ │ Nginx binary│ │
│ ├─────────────┤ ├─────────────┤ ├─────────────┤ │
│ │ Ubuntu │◄────┤ Ubuntu │────►│ Ubuntu │ │
│ │ (shared) │ │ (shared) │ │ (shared) │ │
│ └─────────────┘ └─────────────┘ └─────────────┘ │
│ │
│ 3 containers, but Ubuntu base layer stored only once! │
│ │
└─────────────────────────────────────────────────────────────┘
When a container modifies a file from a read-only layer:
- File is copied from read-only layer to container layer
- Container modifies the copy
- Original layer remains unchanged
- Other containers still see original file
┌─────────────────────────────────────────────────────────────┐
│ Copy-on-Write Mechanism │
├─────────────────────────────────────────────────────────────┤
│ │
│ Before Modification: │
│ ┌──────────────────────────────────────┐ │
│ │ Container Layer (R/W) [empty] │ │
│ ├──────────────────────────────────────┤ │
│ │ Image Layer (R/O) │ │
│ │ • /etc/nginx/nginx.conf (original) │ │
│ └──────────────────────────────────────┘ │
│ │
│ After Modification: │
│ ┌──────────────────────────────────────┐ │
│ │ Container Layer (R/W) │ │
│ │ • /etc/nginx/nginx.conf (modified) ◄─┐ Container sees │
│ ├──────────────────────────────────────┤ │ this version │
│ │ Image Layer (R/O) │ │ │
│ │ • /etc/nginx/nginx.conf (original) │──┘ │
│ └──────────────────────────────────────┘ │
│ │
└─────────────────────────────────────────────────────────────┘
A container runtime is the software responsible for running containers. There are multiple levels of container runtimes.
┌─────────────────────────────────────────────────────────────┐
│ Container Runtime Stack │
├─────────────────────────────────────────────────────────────┤
│ │
│ ┌─────────────────────────────────────────────────────┐ │
│ │ High-Level Runtime (User Interface) │ │
│ │ • Docker CLI, Podman, nerdctl │ │
│ │ • Image management (build, pull, push) │ │
│ │ • Volume management │ │
│ │ • Network management │ │
│ └──────────────────────┬──────────────────────────────┘ │
│ │ │
│ ▼ │
│ ┌─────────────────────────────────────────────────────┐ │
│ │ Container Runtime (Daemon/API) │ │
│ │ • containerd, CRI-O │ │
│ │ • Image unpacking │ │
│ │ • Container lifecycle management │ │
│ │ • CRI implementation (for Kubernetes) │ │
│ └──────────────────────┬──────────────────────────────┘ │
│ │ │
│ ▼ │
│ ┌─────────────────────────────────────────────────────┐ │
│ │ Low-Level Runtime (OCI Runtime) │ │
│ │ • runc, crun, kata-runtime │ │
│ │ • Creates namespaces │ │
│ │ • Configures cgroups │ │
│ │ • Runs container process │ │
│ └─────────────────────────────────────────────────────┘ │
│ │ │
│ ▼ │
│ ┌─────────────────────────────────────────────────────┐ │
│ │ Linux Kernel │ │
│ │ • Namespaces, cgroups, capabilities │ │
│ │ • Process scheduling, memory management │ │
│ └─────────────────────────────────────────────────────┘ │
│ │
└─────────────────────────────────────────────────────────────┘
| Runtime | Description | Key Features |
|---|---|---|
| Docker | Full-featured platform | • Complete ecosystem • Docker Hub registry • Compose for multi-container • Build system (Dockerfile) |
| Podman | Daemonless container engine | • Docker-compatible CLI • Rootless containers • systemd integration • No daemon required |
| containerd | Industry-standard runtime | • Graduated CNCF project • Used by Kubernetes • Lightweight • CRI support |
| CRI-O | Kubernetes-focused runtime | • Designed for Kubernetes • OCI-compliant • Lightweight • No extra features |
| Runtime | Description | Security Model |
|---|---|---|
| runc | Reference OCI implementation | Standard Linux isolation |
| crun | Fast runtime in C | Standard Linux isolation |
| gVisor | Google's sandboxed runtime | User-space kernel (runsc) |
| Kata Containers | VM-based containers | Lightweight VMs (QEMU/Firecracker) |
| Firecracker | AWS microVM | Minimal VM overhead |
┌─────────────────────────────────────────────────────────────┐
│ Kubernetes Container Runtime Interface (CRI) │
├─────────────────────────────────────────────────────────────┤
│ │
│ ┌─────────────┐ │
│ │ kubelet │ │
│ └──────┬──────┘ │
│ │ CRI (gRPC) │
│ ├────────────────┬────────────────┐ │
│ ▼ ▼ ▼ │
│ ┌────────────┐ ┌──────────┐ ┌──────────┐ │
│ │containerd │ │ CRI-O │ │ Docker │ │
│ │ +CRI │ │ │ │ (deprecated) │
│ └──────┬─────┘ └─────┬────┘ └─────┬────┘ │
│ │ │ │ │
│ └───────────────┼───────────────┘ │
│ ▼ │
│ ┌──────────┐ │
│ │ runc │ │
│ └──────────┘ │
│ │ │
│ ▼ │
│ Linux Kernel (namespaces, cgroups) │
│ │
└─────────────────────────────────────────────────────────────┘
⚠️ Note: As of Kubernetes v1.24, dockershim has been removed. Use containerd or CRI-O directly.
┌─────────────────────────────────────────────────────────────┐
│ Container Lifecycle States │
├─────────────────────────────────────────────────────────────┤
│ │
│ ┌──────────────────────┐ │
│ │ Image (on disk) │ │
│ └──────────┬───────────┘ │
│ │ create │
│ ▼ │
│ ┌──────────────────────┐ │
│ │ Created │ │
│ │ (not running yet) │ │
│ └──────────┬───────────┘ │
│ │ start │
│ ▼ │
│ ┌──────────────────────┐ │
│ ┌───│ Running │───┐ │
│ │ │ (process executing) │ │ │
│ │ └──────────────────────┘ │ │
│ │ │ │
│ pause stop │
│ │ │ │
│ ▼ ▼ │
│ ┌──────────┐ ┌─────────────┐ │
│ │ Paused │ │ Stopped │ │
│ │(frozen) │ │ (exited) │ │
│ └────┬─────┘ └──────┬──────┘ │
│ │ │ │
│ unpause restart │
│ │ │ │
│ └───────────┬───────────────┘ │
│ │ │
│ │ remove │
│ ▼ │
│ ┌──────────────┐ │
│ │ Deleted │ │
│ └──────────────┘ │
│ │
└─────────────────────────────────────────────────────────────┘
# Create container (doesn't start it)
docker create --name web nginx:latest
# Start container
docker start web
# Run (create + start in one command)
docker run -d --name web nginx:latest
# Pause (freeze all processes)
docker pause web
# Unpause
docker unpause web
# Stop (graceful shutdown - SIGTERM, then SIGKILL after timeout)
docker stop web
# Kill (immediate termination - SIGKILL)
docker kill web
# Restart
docker restart web
# Remove (must be stopped first, or use -f)
docker rm web
docker rm -f web # Force remove running containerSame container runs on:
• Developer laptop (Docker Desktop)
• CI/CD pipeline (Jenkins/GitLab)
• QA environment (on-prem)
• Production (AWS, GCP, Azure, on-prem)
"Works on my machine" → "Works everywhere"
• Same dependencies
• Same configuration
• Same behavior
Traditional VMs: Containers:
• 5-10 per host • 100s per host
• GBs per instance • MBs per instance
• Minutes to boot • Seconds to start
Each container has:
• Own processes (can't see other containers)
• Own network (own IP, ports)
• Own filesystem (own files, directories)
• Resource limits (CPU, RAM)
Scale horizontally:
$ kubectl scale deployment web --replicas=100
(100 containers in seconds)
| Use Case | Why Containers? | Example |
|---|---|---|
| Microservices | Independent services, easy scaling | E-commerce (order, payment, inventory services) |
| CI/CD | Consistent build/test environments | Jenkins agents, GitLab runners |
| Development | Match production environments locally | Docker Compose for local dev stack |
| Legacy Modernization | Package old apps with dependencies | Move monolith to containers gradually |
| Batch Processing | Spin up, process, shut down | Data processing jobs, ETL pipelines |
| Machine Learning | Reproducible training environments | Jupyter notebooks, model training |
| Multi-tenant SaaS | Isolation between customers | Separate container per customer/tenant |
| Edge Computing | Lightweight, fast deployment | IoT gateways, edge servers |
┌─────────────────────────────────────────────────────────────┐
│ Container Security Layers │
├─────────────────────────────────────────────────────────────┤
│ │
│ 1. Image Security │
│ ├─ Use official/verified images │
│ ├─ Scan for vulnerabilities (Trivy, Clair) │
│ ├─ Keep images updated │
│ └─ Sign images (Docker Content Trust) │
│ │
│ 2. Runtime Security │
│ ├─ Run as non-root user │
│ ├─ Drop capabilities (--cap-drop=ALL) │
│ ├─ Read-only filesystem (--read-only) │
│ ├─ Resource limits (--memory, --cpus) │
│ └─ Use security profiles (AppArmor, SELinux, Seccomp) │
│ │
│ 3. Network Security │
│ ├─ Minimize exposed ports │
│ ├─ Use private networks │
│ ├─ Implement network policies │
│ └─ TLS for inter-container communication │
│ │
│ 4. Host Security │
│ ├─ Keep kernel updated │
│ ├─ Harden host OS │
│ ├─ Monitor container activity │
│ └─ Use minimal host OS (CoreOS, Flatcar) │
│ │
└─────────────────────────────────────────────────────────────┘
- Docker Documentation
- Docker Resources: What is a Container?
- Open Container Initiative (OCI)
- containerd
- CRI-O
- Container Runtime Interface (CRI)
- Docker and Container Orchestration
- Kubernetes Pods
- Kubernetes Networking
Next Steps:
- Learn about Docker and Container Orchestration
- Understand Container Runtimes in Detail
- Explore Kubernetes Pods