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:
dockerCLI →dockerd(REST API) →containerd(lifecycle management) →runc(OCI-compliant process that actually creates the namespaces/cgroups). - Because containers are visible host processes,
ps auxon the host shows containerized processes with a host-mapped PID — killing that PID from the host kills the container. - Biggest gotcha: containers run as
rootby 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 │
└────────────────────────┘
- Docker Daemon (
dockerd): A persistent background process that manages images, containers, networks, and storage volumes. It exposes a local REST API. containerd: An industry-standard, CNCF-graduated container runtime that manages the complete container lifecycle (pushes, pulls, runtime lifecycle execution).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
rootuser by default. Why: Docker does not remap the container’s root user unless explicitly configured. Fix: Set a non-rootUSERin 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, anddocker 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 runto a running process — tests knowledge of thedockerd→containerd→runcarchitecture and the OCI spec’s role.