01 - Containers & Virtualization

What Problem Do Containers Solve?

Before containers, deploying software was painful:

  • "It works on my machine" syndrome
  • Dependency conflicts between applications
  • Slow provisioning of new environments
  • Wasted resources running full VMs

Virtual Machines vs Containers

Virtual Machines (VMs)

┌─────────────────────────────┐
│         Your App            │
├─────────────────────────────┤
│      Guest OS (Linux)       │  ← Full operating system (~GBs)
├─────────────────────────────┤
│       Hypervisor            │  ← VMware, VirtualBox, KVM
├─────────────────────────────┤
│      Host OS (macOS)        │
├─────────────────────────────┤
│        Hardware             │
└─────────────────────────────┘
  • Each VM runs a full OS (kernel + userspace)
  • Heavy: GBs of memory, minutes to boot
  • Strong isolation (separate kernels)
  • Examples: VMware, VirtualBox, Hyper-V, KVM

Containers

┌──────────┐ ┌──────────┐ ┌───────────┐
│  App A   │ │  App B   │ │  App C    │
├──────────┤ ├──────────┤ ├───────────┤
│ Libs/Bins│ │ Libs/Bins│ │ Libs/Bins │
├──────────┴─┴──────────┴─┴───────────┤
│         Container Runtime           │  ← Docker Engine
├─────────────────────────────────────┤
│         Host OS Kernel              │  ← Shared!
├─────────────────────────────────────┤
│           Hardware                  │
└─────────────────────────────────────┘
  • Containers share the host kernel
  • Lightweight: MBs, seconds to start
  • Process-level isolation
  • Uses Linux kernel features (namespaces, cgroups)

Key Comparison

FeatureVMContainer
Boot timeMinutesSeconds
SizeGBsMBs
PerformanceNear-native with overheadNear-native
IsolationStrong (hardware-level)Process-level
OSFull guest OSShares host kernel
Density10s per host100s-1000s per host
PortabilityLess portableHighly portable

The Linux Kernel Features Behind Containers

1. Namespaces (Isolation)

Namespaces make a process think it's alone on the system:

NamespaceWhat It Isolates
PIDProcess IDs -- container sees its own PID 1
NETNetwork interfaces, IPs, ports
MNTFilesystem mount points
UTSHostname and domain name
IPCInter-process communication
USERUser and group IDs
CGROUPCgroup root directory
bash
# See namespaces of a process ls -la /proc/self/ns/ # Create a new namespace (what Docker does under the hood) unshare --pid --fork --mount-proc bash # Now you're in a new PID namespace! ps aux # Only shows processes in this namespace

2. Control Groups (cgroups) -- Resource Limits

Cgroups limit how much resources a process can use:

bash
# Docker uses cgroups to limit resources docker run --memory=512m --cpus=1.5 nginx # Under the hood, this creates cgroup entries at: # /sys/fs/cgroup/memory/docker/<container-id>/memory.limit_in_bytes # /sys/fs/cgroup/cpu/docker/<container-id>/cpu.cfs_quota_us

3. Union Filesystems (Layered Storage)

Containers use layered filesystems for efficiency:

┌─────────────────────┐
│  Container Layer    │  ← Read-Write (your changes)
├─────────────────────┤
│  App Layer          │  ← Read-Only
├─────────────────────┤
│  Dependencies       │  ← Read-Only
├─────────────────────┤
│  Base OS Layer      │  ← Read-Only (e.g., Ubuntu)
└─────────────────────┘
  • Each layer is read-only except the top (container layer)
  • Layers are shared between containers (saves disk space)
  • Copy-on-write: only modified files are duplicated

Container Runtimes

The container runtime is the software that actually runs containers:

RuntimeLevelDescription
containerdHigh-levelIndustry standard, used by Docker & K8s
CRI-OHigh-levelLightweight, Kubernetes-native
runcLow-levelOCI reference implementation
gVisorSandboxedGoogle's secure container runtime
Kata ContainersVM-basedContainers in lightweight VMs
Docker CLI → Docker Daemon → containerd → runc → Container
                                              ↓
Kubernetes → CRI → containerd/CRI-O → runc → Container

OCI (Open Container Initiative)

The OCI defines open standards for containers:

  • Runtime Spec: How to run a container
  • Image Spec: How container images are structured
  • Distribution Spec: How images are distributed (registries)

This means images built with Docker work with Podman, containerd, etc.

Quick Hands-On

bash
# Run your first container docker run hello-world # Run an interactive Ubuntu container docker run -it ubuntu bash # Inside the container: hostname # Random container ID cat /etc/os-release # Ubuntu ps aux # Only your bash process (PID namespace!) exit # The container is isolated but shares the host kernel uname -r # Same kernel version as host

FAANG Interview Angle

Common questions:

  1. "Explain the difference between VMs and containers"
  2. "What Linux kernel features enable containers?"
  3. "What is the OCI and why does it matter?"
  4. "When would you choose VMs over containers?"

Key answers:

  • Containers share the host kernel, VMs have their own
  • Namespaces provide isolation, cgroups provide resource limits
  • OCI ensures portability across container runtimes
  • Use VMs when you need different OS kernels or stronger security isolation

Official Links