Skip to main content
Now that we understand sandboxing technologies like gVisor and Kata Containers, this lesson explains how container runtimes are used when deploying containers and what happens under the hood. When you run a container (for example 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
High-level flow when executing docker run:
  1. The Docker CLI converts your command into a REST API request and sends it to the Docker daemon.
  2. The Docker daemon checks whether the requested image exists locally. If not, it pulls the image from the configured registry (Docker Hub by default).
  3. Once the image is available, the Docker daemon delegates lifecycle operations to containerd.
  4. containerd handles image management, snapshotting, unpacking images, and preparing an OCI-compliant bundle for the container.
  5. containerd interacts with a shim (commonly containerd-shim) that manages the container process lifecycle and keeps the container running independently of the containerd daemon.
  6. The shim invokes an OCI-compliant runtime (default: runc) to create and start the container process.
  7. The runtime (runc) uses kernel primitives such as namespaces and cgroups to create the isolated container environment.
Concise conceptual diagram:
  • Docker CLI → Docker daemon → containerd → containerd-shim → runc → kernel (namespaces, cgroups)
runc
  • runc is 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: runc operates on OCI bundles — a filesystem layout containing a config.json and a root filesystem. You cannot give an image directly to runc; tools like containerd or BuildKit unpack an image to a bundle before invoking runc.
  • Because runc adheres to OCI, many tools and runtimes use it by default for broad compatibility.
Alternative OCI-compatible runtimes Sandbox-oriented runtimes implement the OCI runtime interface so container engines can select them instead of runc:
  • Kata Containers — typically uses kata-runtime.
  • gVisor — uses runsc.
Since these runtimes implement the OCI runtime interface, engines like Docker can invoke them in place of 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.
Technical clarifications
  • 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.
Quick reference table: components and responsibilities Recap — example using a specific runtime
What’s next We will cover how to install gVisor and configure it as a runtime for container engines in the next lesson. For background reading, see the OCI runtime specification and documentation for containerd, gVisor, and Kata Containers. Links and references

Watch Video