docker run nginx), several coordinated steps occur: the client checks for the image, pulls it if necessary, prepares the filesystem, and finally starts the container process using an OCI-compatible runtime.
Example: pulling and starting NGINX with Docker
docker run:
- The Docker CLI converts your command into a REST API request and sends it to the Docker daemon.
- The Docker daemon checks whether the requested image exists locally. If not, it pulls the image from the configured registry (Docker Hub by default).
- Once the image is available, the Docker daemon delegates lifecycle operations to containerd.
- containerd handles image management, snapshotting, unpacking images, and preparing an OCI-compliant bundle for the container.
- containerd interacts with a shim (commonly
containerd-shim) that manages the container process lifecycle and keeps the container running independently of the containerd daemon. - The shim invokes an OCI-compliant runtime (default:
runc) to create and start the container process. - The runtime (
runc) uses kernel primitives such as namespaces and cgroups to create the isolated container environment.
- Docker CLI → Docker daemon → containerd → containerd-shim → runc → kernel (namespaces, cgroups)
runcis the reference implementation of the OCI runtime specification and is the default runtime used by containerd and many container engines to create container processes.- Important:
runcoperates on OCI bundles — a filesystem layout containing aconfig.jsonand a root filesystem. You cannot give an image directly torunc; tools like containerd or BuildKit unpack an image to a bundle before invokingrunc. - Because
runcadheres to OCI, many tools and runtimes use it by default for broad compatibility.
runc:
- Kata Containers — typically uses
kata-runtime. - gVisor — uses
runsc.
runc (if the runtime is installed and registered).
Examples: run a container with a specific runtime
The
--runtime option works only if the specified runtime is installed on the host and registered with the container engine (for Docker, configured in daemon.json under runtimes). If the runtime isn’t configured, Docker will report an error.- containerd is a long-running daemon that manages images, snapshots, and the container lifecycle. It coordinates with a runtime (such as
runc) through shims. - The shim (
containerd-shim) keeps the container process alive and provides a stable endpoint for I/O and exit status even if containerd crashes or restarts. - Container engines that orchestrate pull/unpack steps (for example, Docker) generally rely on containerd + an OCI runtime to start the container process.
Recap — example using a specific runtime
- Docker — Learn KodeKloud course page
- OCI runtime specification: https://github.com/opencontainers/runtime-spec
- containerd: https://containerd.io/
- gVisor: https://gvisor.dev/
- Kata Containers: https://katacontainers.io/