A docker run passes through five programs. The docker CLI sends a REST request over /var/run/docker.sock to dockerd, which owns Docker 514 's own concepts (names, networks, volumes, builds) and calls containerd 234,762 over gRPC. containerd unpacks the image into snapshots, writes the OCI bundle and starts a containerd-shim-runc-v2 for the container. The shim runs runc 13,463 , which creates the namespaces and cgroup, pivots into the root filesystem, applies seccomp and capabilities, and execs your command. runc then exits, and the shim stays as the container's parent, so the daemons can restart without killing containers (live-restore, daemon.json).
ps -o pid,ppid,comm -C dockerd,containerd,containerd-shim-runc-v2
ID=$(docker inspect -f '{{.Id}}' l3-ns)
sudo ctr -n moby containers info "$ID" | jq -c '[.Image, .Runtime.Name]'
sudo runc --root /run/docker/runtime-runc/moby state "$ID" | jq -c '[.status, .pid]' PID PPID COMMAND
327 1 containerd
482 1 dockerd
370202 1 containerd-shim
370489 1 containerd-shim
["docker.io/library/alpine:3","io.containerd.runc.v2"]
["running",370227]The daemons and shims (one per container) are children of systemd 142,543 . ctr, containerd's debugging client, finds Docker's containers in containerd's moby namespace, and runc reports the PID that lsns showed in Namespaces.
