containerd and runc

containerd and runc: How the Pieces Fit Together

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).

The daemons, containerd's view and runc's view of l3-nsShell
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]'
Output
    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.

From docker run to a running process: CLI, dockerd, containerd, shim and runc
From docker run to a running process: CLI, dockerd, containerd, shim and runc