4.4 KiB
17.6 containerd - 核心容器运行时
本节介绍 containerd,它是现代容器技术栈中最为核心的基础组件之一。了解 containerd 有助于更深入地理解 Docker 和 Kubernetes 的底层运行机制。
containerd 简介
containerd 是一个行业标准的容器运行时,它最初是由 Docker 引擎中剥离出来的一个核心组件,后来 Docker 将其捐赠给了云原生计算基金会(CNCF),目前已经是一个 CNCF 毕业(Graduated)项目。
它的主要职责是管理单个宿主机上完整的容器生命周期,包括:
- 镜像的传输和存储
- 容器执行和管理
- 存储和网络接口的管理
简单来说,当你在使用 Docker 或者 Kubernetes 时,真正去底层调用操作系统接口(如 Linux 的 Namespace 和 Cgroups)来启动和管理容器进程的,往往是 containerd(及它所调用的 runc 组件)。
与 Docker 和 Kubernetes 的关系
理解 containerd,首先要理清它与用户日常操作的 Docker 以及 Kubernetes 的关系。
Docker 的架构
在早期,Docker 引擎是一个包含了所有功能的单体架构。随着技术的发展和标准化要求,Docker 将底层关于容器运行时的部分解耦出来,形成了 containerd 和 runc。
当你执行一个 docker run 命令时,调用链路大致如下:
- Docker Client 发送请求给 Docker Daemon(
dockerd)。 dockerd将请求转发给containerd。containerd准备好镜像和容器的必要环境,然后调用runc。runc负责按照 OCI(Open Container Initiative)标准,拉起并运行真正的容器进程。
因此,Docker 现在实际上是构建在 containerd 之上的一个包含更多开发者友好特性(如构建镜像、Compose 管理等)的增强平台。
Kubernetes 与 CRI
Kubernetes 作为一个容器编排系统,为了屏蔽底层不同容器运行时的实现差异,引入了 CRI(Container Runtime Interface)标准。
- 早期版本中,Kubernetes 默认使用 docker 作为运行时,通过一个名为
dockershim的桥接组件对接 Docker,Docker 再对接 containerd。 - 随着 containerd 原生支持了 CRI 插件,Kubernetes 开始直接与 containerd 通信,去掉了
dockershim和dockerd的中间层。这就是为什么从 Kubernetes v1.24 开始“弃用 Docker”引发了广泛关注,实际上 Kubernetes 只是弃用dockershim,底层依然在使用从 Docker 基因中诞生的 containerd。
为什么直接使用 containerd?
对普通应用开发者来说,Docker 依然是本地开发和测试的首选。但对于构建云平台、自动化流水线或深度管理 Kubernetes 集群的系统工程师来说,直接使用 containerd 可以带来:
- 更高的性能与更少的开销:去掉了 Docker Daemon 等附加组件的资源占用,链路更短。
- 更强的稳定性:作为专注于运行时的底层组件,它的核心功能极为稳定且更新受控。
- 直接符合 Kubernetes CRI 标准:在生产级 Kubernetes 集群中作为标准配置。
基础用法与工具介绍
不同于 docker 命令行工具,containerd 提供了不同的客户端来满足不同的使用场景:
- ctr:containerd 自带的调试用客户端。它功能比较基础,主要用于开发者在开发 containerd 时进行快速调试,一般不作为最终用户的日常管理工具。
- crictl:Kubernetes 提供的 CRI 命令行工具。它用于排查 Kubernetes 节点上的容器和沙箱(Pod)问题。
- nerdctl:这是一个由系统社区成员(主要是 containerd 项目的维护者)开发的,完全兼容 Docker CLI 体验的 containerd 命令行客户端。对于习惯了
docker run/ps/build命令的用户来说,nerdctl可以作为直接操作 containerd 的理想替代品,并且它还支持直接构建镜像(依赖 BuildKit)。
nerdctl 使用示例
安装完 containerd 和 nerdctl 后,你可以体验到几乎与 Docker 完全一致的命令行:
# 启动一个 nginx 容器
$ nerdctl run -d -p 8080:80 --name my-nginx nginx:alpine
# 查看运行中的容器
$ nerdctl ps
# 查看本地镜像
$ nerdctl images
对于那些希望在生产服务器上剥离 Docker 庞大体积,但又想要保留类似 Docker 方便的命令行体验的用户,containerd + nerdctl 是一个极佳的组合。