LearnKubernetes
Kubernetes1. Containerization Basics·INTERMEDIATE·5 min read

Docker Fundamentals

TL;DR

  • Containers are ordinary Linux processes isolated by two kernel primitives: namespaces (what a process can see) and cgroups (what it can use).
  • Containers share the host kernel; VMs virtualize hardware and run a full guest OS each — this is why containers boot in milliseconds and are measured in MBs, while VMs boot in minutes and are measured in GBs.
  • The Docker Engine is a layered pipeline: docker CLI → dockerd (REST API) → containerd (lifecycle management) → runc (OCI-compliant process that actually creates the namespaces/cgroups).
  • Because containers are visible host processes, ps aux on the host shows containerized processes with a host-mapped PID — killing that PID from the host kills the container.
  • Biggest gotcha: containers run as root by default, which is a real privilege-escalation risk if the container runtime is ever escaped.

Core Concepts

Containers vs. Virtual Machines

       VIRTUAL MACHINES (VMs)                      CONTAINERS
┌─────────────────────────────────┐      ┌─────────────────────────────────┐
│  App A   │  App B   │  App C    │      │  App A   │  App B   │  App C    │
├──────────┼──────────┼───────────┤      ├──────────┼──────────┼───────────┤
│ Libs/Bins│ Libs/Bins│ Libs/Bins │      │ Libs/Bins│ Libs/Bins│ Libs/Bins │
├──────────┼──────────┼───────────┤      ├──────────┴──────────┴───────────┤
│ Guest OS │ Guest OS │ Guest OS  │      │       Container Runtime         │
├──────────┴──────────┴───────────┤      ├─────────────────────────────────┤
│           Hypervisor            │      │        Host OS Kernel           │
├─────────────────────────────────┤      ├─────────────────────────────────┤
│         Infrastructure          │      │         Infrastructure          │
└─────────────────────────────────┘      └─────────────────────────────────┘

VMs include a full copy of a guest operating system, virtualized hardware drivers, and application binaries. They require a hypervisor (Type 1, e.g. ESXi, or Type 2, e.g. VirtualBox) to translate guest CPU instructions to host hardware. Containers share the host system’s kernel and only contain application code, standard libraries, and dependencies — they run as native processes directly on the host CPU.

Namespaces (Isolation)

Namespaces restrict what a process can see. The kernel provides several namespace types to isolate different aspects of the system:

  • pid (Process ID): Gives the container its own process tree. Process ID 1 inside the container is mapped to a high-numbered PID on the host.
  • net (Networking): Provides isolated network interfaces, routing tables, and port bindings.
  • mnt (Mount): Isolates file system mount points, preventing containers from seeing the host directory structure.
  • ipc (Inter-Process Communication): Prevents containers from reading shared memory segments of other host processes.
  • uts (UNIX Timesharing System): Allows the container to define its own hostname and domain name.
  • user: Maps container root users to non-root users on the host for security.

Control Groups / Cgroups (Resource Constraints)

Cgroups restrict what a process can use. They govern hardware boundaries:

  • Limit maximum memory allocation, preventing a container from starving the host OS.
  • Define CPU shares and limits, preventing CPU starvation of other workloads.
  • Throttle disk I/O read/write speeds and network bandwidth.

Docker Engine Architecture

The Docker Engine is a client-server application with three major components:

┌─────────────────┐       REST API       ┌────────────────────────┐
│  Docker CLI     ├─────────────────────▶│     Docker Daemon      │
│  (docker run)   │◀─────────────────────┤       (dockerd)        │
└─────────────────┘                      └──────────┬─────────────┘
                                                    │ gRPC

                                         ┌────────────────────────┐
                                         │       containerd       │
                                         └──────────┬─────────────┘


                                         ┌────────────────────────┐
                                         │         runc           │
                                         └────────────────────────┘
  1. Docker Daemon (dockerd): A persistent background process that manages images, containers, networks, and storage volumes. It exposes a local REST API.
  2. containerd: An industry-standard, CNCF-graduated container runtime that manages the complete container lifecycle (pushes, pulls, runtime lifecycle execution).
  3. runc: A lightweight, low-level runtime tool conforming to the OCI (Open Container Initiative) specification. It communicates with the Linux kernel to initialize namespaces and cgroups, starts the container process, and exits.

Because containers share the host kernel, any process running inside a container is visible in the host’s process tree. The host OS maps the containerized PID 1 to a standard high-number PID (e.g. PID 24503) in the host namespace — kill -9 24503 on the host terminates the container immediately.

Containers vs Virtual Machines

Aspect Virtual Machines Containers
Isolation unit Hypervisor + full guest OS Kernel namespaces + cgroups
Image size GBs MBs
Boot time Minutes Milliseconds
Kernel Separate kernel per VM Shared host kernel
Density per host Lower Higher
Attack surface if escaped Contained to hypervisor boundary Direct host kernel exposure

Command / Configuration Reference

# Run an isolated Nginx container, mapping host port 8080 to container port 80
docker run -d --name web-server -p 8080:80 nginx:alpine

# Inspect low-level container details, including namespaced IP address
docker inspect web-server | grep -i ipaddress

# Execute an interactive shell inside a running container (debugging)
docker exec -it web-server /bin/sh

# Limit a container to 512MB RAM and 0.5 CPU shares via cgroups
docker run -d --name memory-bound --memory="512m" --cpus="0.5" redis:alpine

# Validate live CPU/memory/IO utilization against the configured limits
docker stats memory-bound
  • docker run — creates a brand-new container instance from an image, configures its namespaces/cgroups, and runs its entrypoint process.
  • docker start — starts an existing, stopped container instance, retaining its configuration and filesystem state.
  • docker exec — spawns a secondary process inside the namespace of an already-running container, primarily used for debugging.

Common Pitfalls

  • Pitfall: Containers run as the root user by default. Why: Docker does not remap the container’s root user unless explicitly configured. Fix: Set a non-root USER in the Dockerfile or enable user namespace remapping so a container-root compromise does not translate to host-root.

Interview Questions

  • If you log into a host machine and run ps aux, can you see the processes running inside Docker containers? — tests understanding of shared-kernel process visibility and PID namespace mapping.
  • What is the difference between docker run, docker start, and docker exec? — tests precise knowledge of the container lifecycle API.
  • What are the two kernel primitives that make containers possible, and what does each control? — tests namespaces (visibility) vs cgroups (resource limits) distinction.
  • Why are containers considered lighter-weight than virtual machines? — tests understanding of shared-kernel architecture vs full OS virtualization.
  • Walk through the component chain from docker run to a running process — tests knowledge of the dockerdcontainerdrunc architecture and the OCI spec’s role.
🔒 Locked
Sign in and unlock the full syllabus to keep reading.
Sign in to continue
Knowledge check
5 scenario questions on this topic
Take the quiz →
Related in 1. Containerization Basics
Dockerizing Applications
INTERMEDIATE
Multi-stage Docker Builds
EXPERT