Day 39: What `docker run` actually does — OCI, containerd, runc
Peeling back the "docker run" abstraction
docker run isn't one program doing one thing — it's a chain of standardized layers. The OCI (Open Container Initiative) defines two specifications: the image format (how layers/manifests are structured) and the runtime spec (how a container must be started, given a root filesystem and a config).
- Docker CLI sends the request to the Docker daemon (dockerd)
- dockerd delegates to containerd — a container lifecycle manager (start/stop/pull images) that several tools (Docker, Kubernetes's CRI) all build on
- containerd hands off the actual container creation to runc — a low-level OCI-compliant runtime
- runc makes the raw syscalls: creates namespaces, sets up cgroups, and execs your process inside them
Why this layering exists
Because containerd and runc implement the OCI spec rather than something Docker-specific, Kubernetes doesn't need Docker at all — it talks to any OCI-compliant runtime (containerd, CRI-O) directly through the CRI (Container Runtime Interface). This is exactly why "Docker" and "containers" stopped being synonymous.
sudo ctr --namespace moby containers list
sudo ctr --namespace moby tasks listKey terms
- OCI
- Open Container Initiative — standard specs for container images and runtimes.
- containerd
- A container lifecycle manager (pulling images, managing containers) used by Docker and Kubernetes alike.
- runc
- A low-level OCI-compliant runtime that makes the actual namespace/cgroup syscalls to create a container.
Why can Kubernetes run containers without Docker being installed on a node?