Skip to main content

Docker Architecture & Internals

This chapter focuses on the under-the-hood architecture of Docker. For commands and image management, see the Images & Commands "Bible" chapter.


1. Client-Server Architecture

Docker uses a Client-Server architecture. The Docker client communicates with the Docker daemon (dockerd) over a socket or TCP. The daemon is responsible for building images, running containers, and managing storage and networks.

Default ports (when using TCP):

  • 2375/TCP: Unencrypted Docker API (insecure; use only in isolated dev environments).
  • 2376/TCP: TLS-encrypted Docker API (recommended for remote access).
  • Unix socket: Default unix:///var/run/docker.sock for local client; no network port.
+------------+        +--------------------------+
| Client | | Docker Host |
+------------+ +--------------------------+
| | REST | +---------+ |
| docker build| API | | dockerd | (Deamon) |
| docker pull| -----> | +----+----+ |
| docker run | | | |
+------------+ | v |
| +----+----+ +--------+ |
| |containerd|->|shim | |
| +----+----+ +--------+ |
| | | |
| v v |
| +------+ +------+ |
| | runc | | runc | |
| +------+ +------+ |
+--------------------------+
  • dockerd: The persistent daemon that listens for Docker API requests and manages container and image lifecycle.
  • containerd: An industry-standard container runtime with an emphasis on simplicity, robustness and portability. It manages the complete container lifecycle of its host system.
  • containerd-shim: Allows runc to exit after starting the container. This permits dockerd or containerd to be upgraded or restarted without killing running containers (Daemonless Containers).
  • runc: The CLI tool for spawning and running containers according to the OCI specification.

OCI link: Docker/containerd use the OCI Runtime Spec (config.json + rootfs) to tell runc how to create the container. The OCI Image Spec defines the image format (manifest, layers, config) that registries and runtimes exchange.


2. Networking Modes (Deep Dive)

Understanding Docker networking is crucial for debugging connectivity issues and understanding Kubernetes networking models.

A. Bridge Network (docker0) - The Default

  • Mechanism: Docker creates a software bridge named docker0 on the host. Connected containers get their own internal IP address (usually 172.17.0.x).
  • Isolation: Containers on the same bridge can talk to each other. They are isolated from the host network but can access the internet via NAT (Network Address Translation).
  • Performance: Slight overhead due to NAT/Bridging.

Inspect bridge and container IPs (debugging):

# Host: see bridge and its subnet
ip addr show docker0

# List containers on default bridge with their IPs
docker network inspect bridge

Sample snippet from docker network inspect bridge:

"Containers": {
"abc123...": {
"Name": "web",
"IPv4Address": "172.17.0.2/16"
}
}

B. Host Network

  • Mechanism: The container shares the host's networking namespace directly. It does not get its own IP address.
  • Use Case: Performance-critical applications or protocols that handle large ranges of ports.
  • Security Risk: No network isolation. If the container binds to port 80, it takes port 80 on the host. A compromised container can sniff host network traffic.
Real-World: Host Network

Avoid --network host in multi-tenant or shared hosts. Port conflicts (e.g. two containers both binding 8080) will cause one to fail. Prefer bridge or user-defined networks and explicit port publishing (-p).

C. None Network

  • Mechanism: The container has a loopback interface (lo) but no external network interface.
  • Use Case: Batch jobs that need strict isolation or handle sensitive data without network access.

D. Container Network (The Kubernetes Foundation)

  • Mechanism: Reuse the network namespace of another container.
  • Concept: docker run --net=container:other-container ...
  • Kubernetes Pattern: This is exactly how Pods work! All containers in a Pod share the same network namespace (held open by the "Pause" container). They share localhost and ports.

3. Storage Drivers & Mounts

Containers are ephemeral. To persist data, you must understand how Docker manages filesystem layers and mounts.

A. Storage Drivers (Overlay2)

Docker uses storage drivers to manage the contents of the image layers and the writable container layer.

  • overlay2: The default and recommended driver for Linux. It uses hard links to share data between layers efficiently.

B. Mount Types

  1. Bind Mounts:

    • Source: Specific file or directory on the Host Machine (e.g., /home/user/code).
    • Destination: Path inside container.
    • Performance: Very high (native FS speed).
    • Use Case: Local development (hot reloading), sharing config files.
  2. Volumes:

    • Source: Managed by Docker in /var/lib/docker/volumes/.
    • Security: Easier to back up, migrate, and manage capabilities.
    • Drivers: Can map to cloud storage (AWS EBS, NFS) via volume drivers.
    • Use Case: Databases, persistent application data.
  3. tmpfs Mounts:

    • Source: Host memory (RAM).
    • Persistence: None. Data is lost when container stops.
    • Use Case: Storing secrets, high-speed ephemeral data.

Inspecting mounts and storage driver (debugging):

# List mount points seen by a container (bind/volume/tmpfs)
docker inspect --format '{{json .Mounts}}' <container> | jq

# See overlay layers for a container (LowerDir = read-only layers, UpperDir = writable)
docker inspect --format '{{.GraphDriver.Data}}' <container>

Sample GraphDriver.Data (overlay2):

map[LowerDir:/var/lib/docker/overlay2/xyz/diff:... UpperDir:/var/lib/docker/overlay2/abc/diff WorkDir:...]

On the host, findmnt or mount | grep overlay shows the merged overlay mount for the container.


4. Kubernetes and Docker: CRI Flow

When Kubernetes runs on a node, it does not talk to dockerd. The Kubelet talks to the CRI (Container Runtime Interface). The default CRI implementation is containerd (or CRI-O).

Kubelet  -->  CRI (gRPC)  -->  containerd  -->  containerd-shim  -->  runc  -->  Kernel

So on a K8s node you will see containerd (and optionally dockerd only if you use Docker for local builds). Container images are pulled and managed by containerd; docker CLI is not required for Kubernetes to run containers.