By Yemo, from Alibaba Cloud Storage Team
Kubernetes 1.24 was released in May 2022. The highlight was that the dockershim component was removed from kubelet in this release. Starting from this release, users must choose containerd or CRI-O as the container runtime when using Kubernetes. If you want to continue to rely on Docker Engine as a container runtime, the cri-dockerd component is required.
Why did Kubernetes remove Docker? The main reason is that Docker does not support the CRI container runtime standard promoted by Kubernetes for a long time. Kubernetes needs to maintain the dockershim component for a long time to specifically adapt to Docker. Dockershim was a product of the early days of Kubernetes and the heyday of Docker. However, with the development of container runtime (such as containerd), Kubernetes has enough reasons to stop maintaining dockershim.
After removing dockershim, does Kubernetes not support Docker at all? The answer is no. At present, in the community, there is a shim cri-dockerd (provided by Mirantis and acquired by Docker Enterprise in 2019) that is independent of Kubernetes and supports CRI. Users can use shim to implement Kubernetes support for Docker.
In addition, since Docker Image has become the standard image format used by various container runtime, it may become a common phenomenon to use Docker in the development phase and use containerd and other container runtimes in the production environment for a long time.
Here, we briefly introduce the whole event of removing dockershim from Kubernetes. At the same time, many concepts including CRI, dockershim, containerd are mentioned. This article will take a deeper look at the container runtime.
When it comes to container runtime, we have to mention Open Container Initiative (OCI).
OCI, proposed in the context of preventing the container technology from fragmenting, is a formal specification for formulating container image format and container runtime, which mainly include OCI Runtime Spec, OCI Image Spec, and OCI Distribution Spec.
The well-known runc is a reference implementation of Runtime Spec. It was first migrated from the libcontainer of Docker and later donated to OCI by Docker. Docker containers are created based on runc.
The container runtime can be divided hierarchically:
Starting from Docker 1.11 (2016), Docker Daemon was split into multiple modules to adapt to the OCI standard. Among them, containerd is a container runtime that manages the lifecycle of a container (such as creation, start, stop, abort, signal processing, and deletion). Other services (such as image building, volume management, and log) are provided by other modules of Docker Daemon.
The container operation process in the figure above can be simplified as Docker Daemon → containerd → containerd-shim → runc. Among them, the containerd-shim is the direct operator of containers.
containerd-shim is introduced here because runc will exit after the container is created and run. As such, containerd-shim is used as the parent process of the container instead of containerd. This avoids the problem that all containers on the entire host have to exit when containerd does not work.
When it comes to Kubernetes removing dockershim events, we have to mention CRI. First of all, let's understand the background of CRI. In the early days of Kubernetes (before v1.5), Docker was the only container runtime supported by Kubernetes, and Kubelet directly called Docker API through hard coding. Later, a new container runtime rkt appeared and hoped to be integrated into the Kubelet code. Then, as a growing number of container runtimes emerged, it became clear that embedding was no longer suitable. In this context, the Container Runtime Interface (CRI) standard is proposed to decouple the Kubelet code from the implementation code of specific container runtime.
However, when Kubernetes launched CRI, it was not as dominant as it is now. Various container runtimes did not actively implement CRI, so it is necessary to adapt various container runtimes through CRI shim. For example, Docker had no intention to support CRI for the following reasons: Docker appeared earlier than Kubernetes, and Docker was in a stable and stronger position. Docker intended to promote Swarm, which was regarded as a competitor of Kubernetes. Finally, Kubelet chose the built-in dockershim to provide support for Docker.
Below is the architecture of Kubelet after the CRI interface is introduced.
The API defined by CRI mainly consists of two gRPC services: ImageService and RuntimeService.
Thanks to CRI, kubelet can achieve unified management of container runtimes (such as Docker, containerd, and CRI-O).
The supporting forms of Docker:
The call link of Docker is too long, and there are many redundant operations. As the CRI ecosystem became more perfect, the Kubernetes community removed dockershim in July 2020. Dockershim was officially deleted in version 1.24.
The supporting forms of containerd:
In summary, kubelet can achieve unified management of Docker, containerd, and CRI-O with the help of CRI. After Kubernetes 1.24 removes the dockershim component from kubelet, we recommend using containerd or CRI-O. Next, we will focus on containerd and CRI-O.
Containerd is an industry-standard container runtime that emphasizes simplicity, robustness, and portability.
Containerd was originally separated from Docker. As an independent open-source project, containerd aims to provide a more open and stable container operation infrastructure. (Please see the architecture diagram in the Docker section for details.)
The official architecture diagram provided by containerd shows that containerd also adopts the C/S architecture. containerd manages the complete container lifecycle of its host system: image transfer and storage, container execution and supervision, low-level storage and network attachments, etc. Runc is responsible for running containers. All containers that comply with OCI specifications can be supported.
In addition, containerd implements a richer container interface. In addition to using CRI, you can use the ctr tool to call these rich container runtime interfaces. For example:
The Kubernetes community has also developed a CRI runtime CRI-O specifically for Kubernetes, and the CRI-O is directly compatible with CRI and OCI specifications. It is a lightweight alternative to using Docker as the runtime for Kubernetes and supports any OCI-conformant runtimes. Kubelet talks directly to the CRI-O through CRI to extract an image and launch a lower-level runtime (such as runc).
An important difference between CRI-O and containerd is that CRI-O removed some unnecessary Linux features to reduce the possibility of external attacks.
CRI-O is a CRI service implemented by packaging the container interface directly on the OCI. Only specific CRI interfaces are provided to the public, and it does not have the ctr tool capability similar to containerd.
The overall architecture is shown below:
With the emergence of more container runtimes, different container runtimes have different requirement scenarios, so there is a need for multiple container runtimes, for which the Kubernetes community has introduced RuntimeClass.
Currently, sandboxed containers of Alibaba Cloud Container Service for Kubernetes (ACK) support multiple container runtimes. As shown in the following figure, the Pod of runc is on the left side, and the corresponding RuntimeClass is runc. The Pod of runv is on the right side, and the corresponding RuntimeClass is runv. You can configure multiple container runtimes in containerd.
As an important part of observability construction, logs can record access requests and error information in detail, which is convenient for us to locate problems. Applications on Kubernetes, Kubernetes components, and hosts generate various types of log data. With the development of Kubernetes, it has gone through the phases of Docker to CRI, increasing the complexity of log collection.
iLogtail, an infrastructure for collecting observability data launched by Alibaba Cloud Log Service (SLS), has good support for Docker and containerd in Kubernetes scenarios. iLogtail generally uses two deployment modes: Sidecar and DaemonSet.
The prerequisite for Logtail to collect business Pods or containers is to have access to the container runtime on the host and have access to the business container's data.
Please read the article entitled Comprehensive Analysis of Kubernetes Log Collection Principles for more information. iLogtail is open-source. You are welcome to follow us.
For more information, please check containerd github
Common Causes and Troubleshooting Methods for Connection Reset
Alibaba Cloud's Energy Expert Helps Analyze Carbon Footprint for The First Olympic Esports Week
1,042 posts | 256 followers
FollowAlibaba Developer - June 23, 2020
Alibaba Developer - May 8, 2019
Alibaba Developer - July 20, 2021
Alibaba Container Service - July 28, 2021
Alibaba Container Service - October 23, 2019
Alibaba Clouder - July 2, 2019
1,042 posts | 256 followers
FollowAlibaba Cloud Container Service for Kubernetes is a fully managed cloud container management service that supports native Kubernetes and integrates with other Alibaba Cloud products.
Learn MoreProvides a control plane to allow users to manage Kubernetes clusters that run based on different infrastructure resources
Learn MoreAccelerate and secure the development, deployment, and management of containerized applications cost-effectively.
Learn MoreAlibaba Cloud Function Compute is a fully-managed event-driven compute service. It allows you to focus on writing and uploading code without the need to manage infrastructure such as servers.
Learn MoreMore Posts by Alibaba Cloud Community