containerd
itCloud native tools and technologies
containerd
containerd is the container runtime daemon that sits between higher-level systems and the operating system. It manages images, container filesystems, container metadata, and running processes on one host. Projects such as Kubernetes can use it through the Container Runtime Interface, or CRI.
You usually do not treat containerd as a complete developer platform. The project is designed to be embedded in a larger system. Kubernetes supplies cluster orchestration. Image builders produce images. Registries distribute them. containerd handles the node-level container lifecycle.
That boundary is the key to understanding containerd. It is infrastructure under other infrastructure.
Why containerd exists
A container platform must do more than start a process. It must fetch image content, verify content by digest, store layers, assemble a mountable root filesystem, retain container configuration, start the selected runtime, supervise the task, and clean up resources.
containerd puts these responsibilities behind services and a gRPC API. A client can ask for an image pull, create container metadata, create a task, or inspect events. Plugins provide implementations for areas such as content storage, snapshots, runtimes, and CRI.
This separation gives higher-level systems a stable runtime layer without requiring each system to implement the full host lifecycle.
The mental model
Follow one workload from an image reference to a running process:
- A client sends a request to containerd.
- containerd resolves and downloads image descriptors, configuration, and layers into its content store.
- A snapshotter unpacks the layers and prepares a mountable root filesystem.
- containerd records a container. This is metadata and configuration, not yet a running process.
- containerd creates a task for that container.
- A runtime shim connects containerd to an OCI runtime such as runc.
- The runtime creates and starts the operating-system process.
The distinction between a container and a task prevents a common misunderstanding. A container is the stored configuration and resource record. A task is the live process created from that container.
The parts that matter
Content store and images
The content store keeps immutable, content-addressed blobs. Image manifests, image indexes, configuration, and filesystem layers arrive here from an OCI-compatible registry or another source.
An image record gives a name to content. The underlying blob digest identifies the actual bytes. A multi-platform image index lets a client select the manifest for an operating system and architecture.
Snapshots and unpacking
Image layers are compressed content, not a ready-to-run filesystem. Unpacking applies those layers in order and creates committed snapshots. A final active snapshot provides the writable root filesystem for a container.
A snapshotter implements this filesystem work. The right snapshotter depends on the host filesystem, kernel support, and operational requirements.
Containers, tasks, shims, and runtimes
containerd stores container metadata before it creates a task. The runtime-v2 path then uses a shim to mediate between the long-running daemon and the selected runtime.
For runc, the shim invokes the runc binary to create, start, and stop the container process. The shim can remain available for task communication and reporting even though the low-level runtime command is short-lived.
Plugins
containerd is assembled from plugins. Built-in plugins expose services and implementations. External plugins can extend defined interfaces without recompiling the daemon. A failed plugin can explain why an expected snapshotter, runtime, or service is unavailable.
Namespaces
containerd namespaces separate names and metadata for multiple consumers of one daemon. Two consumers can use the same object name in different namespaces. Image content can still be shared by digest.
This is an administrative separation, not a security boundary. A client with access to the API can select another namespace. Authorization and host access controls must provide security.
Where containerd fits with Kubernetes
Kubernetes does not call runc directly. On a node configured for containerd, the kubelet speaks CRI to containerd's built-in CRI plugin. The plugin translates pod sandbox, container, and image operations into containerd services. containerd then prepares filesystems and uses a runtime path to create processes.
This layered design separates concerns:
- Kubernetes decides what should run and on which node.
- CRI defines the node-runtime contract.
- containerd manages images and container lifecycles on that node.
- A shim and OCI runtime perform the low-level execution work.
If a pod is rescheduled to another node, Kubernetes drives that decision. containerd only manages the resources on each host where it runs.
Choosing the right client
The bundled ctr client exposes containerd's native API and is intended for debugging containerd. Its command surface can change with the project and is not designed as a stable end-user experience.
nerdctl is a separate, general-purpose client with a Docker-compatible style. crictl exercises CRI and is useful when troubleshooting Kubernetes node-runtime behavior. Choose the client that matches the interface you need to observe.
Important limits
containerd does not schedule workloads across machines. It does not provide Kubernetes controllers, services, or desired-state reconciliation. It also does not replace an image build system or registry.
Direct containerd API integration makes sense when you are building a higher-level platform, runtime tool, or node agent. Direct day-to-day use is less appropriate when a supported orchestrator or general-purpose container client already supplies the workflow you need.
Operational work also depends on version context. containerd 2.x recommends configuration version 3, while configuration version 2 remains supported. Plugin identifiers and some defaults can differ across major versions. Read the documentation for your installed release before copying configuration.
A practical learning path
Start by drawing the request path from client to containerd, snapshotter, shim, and runtime. Then trace image content from registry to content store to snapshots. Next, learn which namespace and interface your platform uses. Finish with configuration, plugin health, registry hosts, release notes, and deprecation warnings for the version you operate.
That sequence turns a list of components into an operational model. When a workload fails, you can ask which boundary failed instead of treating the runtime as one opaque box.
