Q: What happens internally during docker run internals execution?
Deep dive into docker run internals: learn how the Docker CLI, containerd daemon, runc OCI runtime, Linux namespaces, cgroups v2, and overlay2 filesystem isolate and execute containers.
Want to master this scenario in a live sandbox? KodeKloud's Docker Certified Associate (DCA) Hands-On Lab Course covers this exact problem with hands-on terminal drills.
🛠️ Production Runbook & Step-by-Step Resolution
Direct Answer: When an interviewer asks about docker run internals, they are testing whether you understand Linux operating system fundamentals, OCI runtime standards, and the division of labor between the Docker CLI, containerd daemon, and low-level runc syscalls.
Docker CLI Parsing & REST API Call to dockerd
The command docker run -d -p 80:80 --name web nginx is executed. The Docker CLI parses CLI flags, translates them into an OCI container creation schema, and sends a REST request over the Unix domain socket /var/run/docker.sock to the Docker daemon (dockerd).
# Simulating the CLI call using curl against dockerd Unix socket
sudo curl --unix-socket /var/run/docker.sock \
-X POST http://localhost/v1.43/containers/create?name=web \
-H "Content-Type: application/json" \
-d '{"Image": "nginx", "HostConfig": {"PortBindings": {"80/tcp": [{"HostPort": "80"}]}}}'
- CLI Translation: CLI validates inputs and converts flags into JSON API payload.
- Socket Communication:
dockerdreceives the HTTP request over/var/run/docker.sock.
Image Layer Verification & Overlay2 RootFS Composition
dockerd passes the container specification to containerd via gRPC. containerd checks if the requested image layers exist locally. If missing, it pulls the OCI image manifest, unpacks tarball layers into the content store, and mounts an Overlay2 union filesystem.
# Inspect the Overlay2 filesystem mounts for a running container
docker inspect web --format '{{.GraphDriver.Data.MergedDir}}'
- Lowerdir: Read-only container image layers stacked on top of each other.
- Upperdir: Read-write scratch layer storing container modifications.
- Mergeddir: Unified view of the filesystem presented inside the container.
containerd-shim Spawning for Daemon Independence
containerd generates an OCI config.json bundle and launches a lightweight process called containerd-shim. The shim keeps container standard IO (stdin/stdout/stderr) and exit status descriptors open so the container remains running even if dockerd or containerd restarts.
# View containerd-shim processes running on the host
ps -ef | grep containerd-shim
- Daemonless Containers: Decouples the lifecycle of the container from the management daemon.
- Process Adoption: Prevents zombie processes by serving as the subreaper for the container process tree.
runc Execution: Linux Namespaces & Process Isolation
The shim invokes runc (the reference OCI runtime). runc issues the Linux clone() and unshare() system calls with flags that create isolated kernel namespaces.
# Inspect namespaces of the container process (PID <pid>)
sudo lsns -p <pid>
- PID Namespace: Isolates process IDs; the main container process becomes PID 1 inside the container while appearing as a standard PID on the host.
- NET Namespace: Provides private network interfaces, routing tables, and firewall rules.
- MNT Namespace: Isolates filesystem mount points, executing
pivot_rootinto the Overlay2 merged directory. - IPC, UTS, USER Namespaces: Isolates inter-process shared memory, hostname, and UID/GID mappings.
Linux Cgroups v2 Resource Allocation & Hardening
runc creates a dedicated control group under /sys/fs/cgroup/ to enforce CPU, memory, PIDs, and I/O resource limits.
# Inspect active cgroup limits applied to the container
cat /sys/fs/cgroup/system.slice/docker-<id>.scope/memory.max
- Memory Limits: Enforces
memory.max; kernel OOM killer terminates process if limits are breached. - CPU Quotas: Configures
cpu.maxCFS scheduler periods to prevent container CPU starvation. - Security Hardening: Applies default seccomp BPF syscall filters and drops Linux capabilities (e.g.
CAP_SYS_ADMIN).
Virtual Network Interface (veth) & iptables NAT Rules
The Docker bridge network driver creates a virtual ethernet (veth) pair. One end is attached to the docker0 bridge on the host; the peer end is placed inside the container's NET namespace as eth0. dockerd configures host iptables PREROUTING rules to forward host port 80 to container port 80.
# Inspect Docker iptables port-forwarding rules
sudo iptables -t nat -L DOCKER -n -v
- veth Interface: Virtual wire moving Ethernet packets between host and container network namespaces.
- iptables DNAT: Translates incoming packets on host port 80 to the container IP on port 80.
What Are the Key Docker Run Internals Components?
Structural comparison of the key daemon and runtime components executing during docker run internals:
- CLI & Daemon: Docker CLI parses arguments and sends a REST POST request over /var/run/docker.sock to dockerd.
- Image & Overlay2: containerd pulls image layers and mounts an Overlay2 union filesystem (lowerdir read-only layers + upperdir scratch layer).
- Shim Spawning: containerd creates containerd-shim to supervise the container independently of daemon restarts.
- runc & Namespaces: runc issues clone() and unshare() syscalls to isolate PID, NET, MNT, IPC, and UTS namespaces.
- Cgroups & Security: runc applies cgroup v2 memory/CPU limits, drops capabilities, and attaches default seccomp filters.
- Network & execve: Docker sets up a veth pair to docker0, configures iptables DNAT, and runc calls execve() on ENTRYPOINT before exiting.
Senior hiring managers and bar raisers evaluate how you prioritize during outages. Avoid these common anti-patterns:
- Claiming that Docker is a hypervisor or that containers run a full guest OS kernel Containers share the host Linux kernel; isolation is achieved purely through kernel namespaces, cgroups, and chroot/pivot_root.
- Believing runc stays running in the background as long as the container is alive runc executes once to set up namespaces/cgroups and calls execve() before exiting; containerd-shim is the long-running supervisor process.
- Overlooking the difference between Docker storage driver (overlay2) and bind mounts Overlay2 introduces copy-up performance penalties for write-heavy databases; stateful workloads require direct volume mounts.
- Assuming Docker containers are completely secure by default Unless rootless Docker or user namespaces are enabled, root (UID 0) inside a container is UID 0 on the host kernel.