Understanding Container Runtimes: From Low‑Level to High‑Level (containerd, CRI‑O, Docker)
This article explains the role of container runtimes, classifies them into low‑level, high‑level, and sandbox types, and details the architectures and key components of popular runtimes such as containerd, CRI‑O, and Docker, highlighting their interactions with OCI specifications and system resources.
Container runtimes are the software components that manage the lifecycle of containers, handling image loading, resource isolation, and execution. They can be categorized into three types: low‑level runtimes, high‑level runtimes, and sandbox/virtualization runtimes.
Low‑Level Container Runtime
A low‑level runtime implements the OCI specification to run an isolated process from a rootfs and a config.json. It only provides process isolation and does not include storage or networking implementations; those must be supplied externally via CNI plugins, CSI storage, or OS‑specific mechanisms. Examples include runC and kata-runtime.
Only understands rootfs and config.json, not full images.
Relies on CNI for networking.
Does not provide persistent storage; external solutions like CSI are needed.
Platform‑specific (runC on Linux, runhcs on Windows).
When a low‑level runtime is extended with additional features, it becomes a high‑level runtime.
High‑Level Runtime Core Tasks
The primary job of a high‑level runtime is to bridge the OCI image spec and the runtime spec, efficiently converting an image into a rootfs and generating a config.json. This involves pulling the image manifest, downloading missing layers, indexing layers, extracting them, and merging them into a rootfs while handling layer reuse and copy‑on‑write semantics.
Use diffID from the image config to generate unique layer IDs.
Store parent‑child relationships for layers in an index.
Employ UnionFS copy‑on‑write to keep the rootfs read‑only and isolate writes.
High‑level runtimes also maintain a container meta object that stores ID, image info, low‑level runtime description, OCI spec, work‑layer ID, and labels, enabling unified management of processes, logs, and other operations.
containerd
containerd is a highly modular high‑level runtime where each function is exposed as an RPC service (gRPC or TTRPC). Its main modules include:
Content : indexes image layers by SHA‑256 and stores them in BoltDB.
Images : maps references to manifests and layers.
Snapshot : stores extracted filesystem layers and supports multiple UnionFS drivers (overlay, aufs, btrfs).
Containers : stores container metadata keyed by container ID.
Diff : computes diffIDs for verification.
containerd provides namespace isolation by separating module data into distinct directory trees, allowing it to serve both Docker and Kubernetes simultaneously. The Tasks service (runtime.PlatformRuntime) manages container processes and interacts with low‑level runtimes via shim processes. Since version 1.2.0, Tasks supports Windows, making containerd cross‑platform.
When a container is created, containerd assembles a container object from the Images and Snapshot modules, generates mount points, and hands the request to the Tasks service, which launches a containerd‑shim process that finally invokes the low‑level runtime.
CRI‑O
CRI‑O implements high‑level runtime functionality using pure Go libraries rather than RPC protocols. Key components:
containers/image : downloads images, normalizes them to a common ImageSource abstraction, and stores them via containers/storage.
LayerStore : manages both image layers and filesystem layers, creating directories for each layer and recording parent relationships.
ImageStore : handles image metadata (manifest, config, signatures).
ContainerStore : manages container metadata, similar to LayerStore but read‑only.
CRI‑O uses CNI plugins for networking and can optionally configure hostname and DNS via file mounts. When a RuntimeHandler is non‑VM, CRI‑O spawns conmon to manage the low‑level runtime; for VM handlers it delegates to a containerd‑shim process.
Docker Engine
Docker Engine consists of the daemon dockerd, a REST API, and the Docker CLI. It builds and distributes images, provides mature storage and networking implementations, and interacts with low‑level runtimes via OCI specs.
Image pulling follows these steps:
Fetch the manifest from the registry.
Download image layers and the config layer in parallel.
Extract layers using a filesystem driver (e.g., overlay) into directories under /var/lib/docker/overlay2.
Index layers by chainID, diffID, and size, without storing the original tar files.
Image pushing reverses the process, uploading only missing layers based on diffID checks.
Container creation involves generating a read‑write layer, merging it with extracted layers via UnionFS, constructing an OCI runtime spec from the image config, and passing the spec along with low‑level runtime details to containerd for execution. Docker adds higher‑level abstractions such as volumes, bind mounts, tmpfs, and network endpoints, which are persisted in its internal state.
Summary
The article outlines the fundamental principles of containerd, CRI‑O, and Docker runtimes, showing how they build on low‑level runtimes to provide advanced features. Docker pioneered many OCI‑compatible concepts, containerd emerged as Docker’s low‑level component, and CRI‑O offers a lightweight Kubernetes‑focused alternative.
Source: https://www.zeng.dev/post/2020-container-runtimes/
Signed-in readers can open the original source through BestHub's protected redirect.
This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactand we will review it promptly.
Liangxu Linux
Liangxu, a self‑taught IT professional now working as a Linux development engineer at a Fortune 500 multinational, shares extensive Linux knowledge—fundamentals, applications, tools, plus Git, databases, Raspberry Pi, etc. (Reply “Linux” to receive essential resources.)
How this landed with the community
Was this worth your time?
0 Comments
Thoughtful readers leave field notes, pushback, and hard-won operational detail here.
