There are many layers in the container world, and they are not unique, and their boundaries are not clear, they may depend on each other, they may contain each other, they may have the same function. I’m going to show you one by one.

A brief introduction

K8s(Kubernetes) is a portable, extensible open source platform for managing containerized workloads and services that facilitates declarative configuration and automation.

Docker is an open source application container engine.

Containerd is an industry-standard container runtime that emphasizes simplicity, robustness, and portability and can manage the full container life cycle on the host

2. The architecture

Both Docker and Kubernetes are on top of Containerd, so Kubernetes doesn’t need to use a full Docker, it just uses Containerd implemented by Docker.

Docker, along with CoreOS and Google, created OCI (Open Container Initial) and provided two specifications:

  • Runtime specification (github.com/opencontain…) Describes how to run filesystem Bundle

  • Mirroring specifications (github.com/opencontain…) Make image format, operation, etc

C. What is the CRI Container Runtime Interface?

CRI was introduced in Kubernetes 1.5 and acts as a bridge between Kubelet and the container runtime. The advanced container runtime that is expected to integrate with Kubernetes will implement CRI. Runtimes is expected to be responsible for managing the images and supporting Kubernetes Pods, as well as managing individual containers. CRI has only one function: in the case of Kubernetes, it describes the operations that the container should have and the parameters that each operation should have.

CRI works between Kubelet and The Container Runtime.

Docker: Docker has moved some of its functionality to Containerd, so CRI can directly interact with Containerd. Therefore, Docker itself does not need to support CRI(Containerd already does).

Containerd: Containerd can use the ShiM to connect to different low-level Runtime scenarios. This section describes containerd in detail

Cri-o: A lightweight runtime that supports RUNc and Clear Containers as low-level Runtimes.

CRI consists of three interfaces: Sandbox, Container, and Image. CRI provides some common interfaces for manipulating containers, such as Create Delete List.

– Sandbox Provides a certain running environment for Containers, including the pod network

– Container Contains operations related to the Container life cycle

– Image Provides operations on the Image

Four. What is Containerd?

In [k8s containerd]

Containerd can manage the full container lifecycle on the host:

  • Manage the lifecycle of the container (from creation to destruction)

  • Pull/push container images

  • Storage management (Managing the storage of images and container data)

  • Call runC to run the container (interact with the container runtime such as runC)

  • Manage container network interfaces and networks

Containerd architecture

Containerd consists of three sections:

– Storage Manages the Storage of image files

– Metadata Manages Metadata of images and containers

– Run time triggered by Task.

Content Service, which provides access to addressable Content in the image, where all immutable Content is stored;

Images Service provides image-related operations;

Snapshot Plugin: Used to manage file system snapshots of container images. Each layer in the image is decompressed into a filesystem snapshot, similar to graphDriver in Docker.

Containerd is designed as a large plug-in system that provides a GRPC-style API and Metrics interface.

Containerd main process

The Docker-Containerd component creates the container’s metadata and requests containerd’s task module. The Task module creates task instances in the Runtime, adds tasks to the Task List, and monitors cgroup operations. Each task instance invokes shim to create containers.

containerd-shim

Containerd-shim is a component of Containerd. It is used to separate containerd daemons and container processes. Containerd uses shim to call runc’s package function to start the container. When we execute the pstree command, we can see the following process relationship:

The shim is introduced to allow RUNC to exit the container after it has been created and run, and to use the Shim as the parent of the container instead of containerd as the parent. This is done so that if containerd dies, the container will not be affected because the Shim is still running.

In addition, shim can collect and report container exit status without requiring Containerd to wait for container processes.

When we need to replace runC runtime libraries, such as kata Container or gViser, we need to add the corresponding ShiM (Kata-Shim, etc.), both of which have their own shiM implementation.

——————–

Containerd

Container Runtimes Part 1: An Introduction to Container Runtimes

Container Runtimes Part 2: Anatomy of a Low-Level Container Runtime

Container Runtimes Part 3: High-Level Runtimes

Container Runtimes Part 4: Kubernetes Container Runtimes & CRI