这篇文章已超过一年。较旧的文章可能包含过时的内容。请检查页面信息自发布以来是否已不再正确。
Kubernetes containerd 集成进入 GA
Kubernetes containerd 集成进入 GA
在之前的一篇博客文章《Containerd 为 Kubernetes 带来更多容器运行时选项》中,我们介绍了 Kubernetes containerd 集成的 Alpha 版本。经过又 6 个月的开发,containerd 集成现已正式可用 (GA)!你现在可以使用 containerd 1.1 作为生产级 Kubernetes 集群的容器运行时了!
Containerd 1.1 可与 Kubernetes 1.10 及更高版本配合使用,并支持所有 Kubernetes 功能。Containerd 在 Google Cloud Platform 上的 Kubernetes 测试基础设施中的测试覆盖率现在已与 Docker 集成相当 (参见:测试仪表盘)。
我们很高兴看到 containerd 快速成长达到这个重要的里程碑。阿里云从 containerd 的第一天起就积极开始使用它,并且由于其强调简洁性和健壮性,使其成为我们 Serverless Kubernetes 产品中运行的完美容器引擎,该产品对性能和稳定性有很高的要求。毫无疑问,containerd 将成为容器时代的核心引擎,并将继续推动创新向前发展。
— Xinwei,阿里云高级工程师
架构改进
Kubernetes containerd 集成架构已经演进了两次。每一次演进都使得堆栈更加稳定和高效。
Containerd 1.0 - CRI-Containerd (已EOL)

对于 containerd 1.0,需要在 Kubelet 和 containerd 之间运行一个名为 cri-containerd 的守护进程。Cri-containerd 处理来自 Kubelet 的 容器运行时接口 (CRI) 服务请求,并相应地使用 containerd 管理容器和容器镜像。与 Docker CRI 实现 (dockershim) 相比,这消除了堆栈中的额外一跳。
然而,cri-containerd 和 containerd 1.0 仍然是两个不同的守护进程,它们通过 grpc 进行交互。循环中的额外守护进程使得用户更难理解和部署,并引入了不必要的通信开销。
Containerd 1.1 - CRI 插件 (当前)

在 containerd 1.1 中,cri-containerd 守护进程已被重构为 containerd CRI 插件。CRI 插件内置于 containerd 1.1 中,并默认启用。与 cri-containerd 不同,CRI 插件通过直接函数调用与 containerd 交互。这种新架构使得集成更加稳定和高效,并消除了堆栈中的另一个 grpc 跳跃。用户现在可以直接将 Kubernetes 与 containerd 1.1 一起使用。不再需要 cri-containerd 守护进程。
性能
提升性能是 containerd 1.1 版本的主要关注点之一。性能在 Pod 启动延迟和守护进程资源使用方面进行了优化。
以下结果是 containerd 1.1 和 Docker 18.03 CE 之间的比较。containerd 1.1 集成使用了内置于 containerd 的 CRI 插件;而 Docker 18.03 CE 集成使用了 dockershim。
结果是使用 Kubernetes 节点性能基准测试生成的,该测试是 Kubernetes 节点 e2e 测试的一部分。大多数 containerd 基准测试数据可在 节点性能仪表盘上公开访问。
Pod 启动延迟
“105 Pod 批量启动基准测试”结果显示,containerd 1.1 集成的 Pod 启动延迟低于使用 dockershim 的 Docker 18.03 CE 集成 (数值越低越好)。
CPU 和内存
在稳态下,运行 105 个 Pod 时,containerd 1.1 集成总体上消耗的 CPU 和内存比使用 dockershim 的 Docker 18.03 CE 集成少。结果会因节点上运行的 Pod 数量而异,选择 105 是因为它是当前每个节点最大用户 Pod 数的默认值。
如下图所示,与使用 dockershim 的 Docker 18.03 CE 集成相比,containerd 1.1 集成的 kubelet CPU 使用率降低了 30.89%,容器运行时 CPU 使用率降低了 68.13%,kubelet 常驻集大小 (RSS) 内存使用率降低了 11.30%,容器运行时 RSS 内存使用率降低了 12.78%。
crictl
容器运行时命令行接口 (CLI) 是一个用于系统和应用故障排除的有用工具。当使用 Docker 作为 Kubernetes 的容器运行时时,系统管理员有时会登录到 Kubernetes 节点上运行 Docker 命令来收集系统和/或应用信息。例如,可以使用 docker ps 和 docker inspect 检查应用进程状态,使用 docker images 列出节点上的镜像,使用 docker info 查看容器运行时配置等。
对于 containerd 和所有其他兼容 CRI 的容器运行时 (例如 dockershim),我们建议使用 crictl 作为 Docker CLI 的替代命令行工具,用于在 Kubernetes 节点上排查 Pod、容器和容器镜像的问题。
crictl 是一个为 Kubernetes 节点故障排除提供类似 Docker CLI 体验的工具,并且 crictl 在所有兼容 CRI 的容器运行时上都一致工作。它托管在 kubernetes-incubator/cri-tools 仓库中,当前版本是 v1.0.0-beta.1。crictl 被设计成类似于 Docker CLI,旨在为用户提供更好的过渡体验,但它并不完全相同。下面解释了一些重要的区别。
范围有限 - crictl 是一个故障排除工具
crictl 的范围仅限于故障排除,它不是 docker 或 kubectl 的替代品。Docker 的 CLI 提供了丰富的命令集,使其成为一个非常有用的开发工具。但在 Kubernetes 节点上进行故障排除时,它并不是最合适的。一些 Docker 命令对 Kubernetes 无用,例如 docker network 和 docker build;有些甚至可能破坏系统,例如 docker rename。crictl 仅提供了节点故障排除所需的足够命令,这在生产节点上使用可能更安全。
Kubernetes 导向
crictl 提供了一种更 Kubernetes 友好的容器视图。Docker CLI 缺少核心的 Kubernetes 概念,例如 pod 和 namespace,因此无法提供容器和 Pod 的清晰视图。一个例子是 docker ps 会显示一些模糊、很长的 Docker 容器名称,并将 pause 容器和应用容器一起显示。

然而,pause 容器是 Pod 的实现细节,每个 Pod 使用一个 pause 容器,因此在列出属于 Pod 的容器时,不应显示它们。
相比之下,crictl 是为 Kubernetes 设计的。它为 Pod 和容器提供了不同的命令集。例如,crictl pods 列出 Pod 信息,而 crictl ps 只列出应用容器信息。所有信息都格式化为表格列。


另一个例子是,crictl pods 包含一个 --namespace 选项,用于按 Kubernetes 中指定的命名空间过滤 Pod。

有关如何将 crictl 与 containerd 一起使用的更多详细信息
Docker Engine 呢?
“切换到 containerd 是否意味着我不能再使用 Docker Engine 了?” 我们经常听到这个问题,简短的答案是:不能。
Docker Engine 是构建在 containerd 之上的。Docker Community Edition (Docker CE) 的下一个版本将使用 containerd version 1.1。当然,它会内置 CRI 插件并默认启用。这意味着用户可以选择继续将 Docker Engine 用于 Docker 用户典型的其他目的,同时还可以配置 Kubernetes 使用与 Docker Engine 在同一节点上同时使用的底层 containerd。参见下面的架构图,显示了 Docker Engine 和 Kubelet 使用同一个 containerd。
由于 Kubelet 和 Docker Engine 都使用 containerd,这意味着选择 containerd 集成的用户不仅能获得新的 Kubernetes 功能、性能和稳定性改进,还可以选择保留 Docker Engine 用于其他用例。
使用 containerd 的 命名空间机制,以保证 Kubelet 和 Docker Engine 无法看到或访问对方创建的容器和镜像。这确保它们不会互相干扰。这也意味着
- 用户将无法使用 docker ps 命令看到 Kubernetes 创建的容器。请改用 crictl ps。反之亦然,用户将无法在 Kubernetes 中或使用 crictl ps 命令看到 Docker CLI 创建的容器。crictl create 和 crictl runp 命令仅用于故障排除。不建议在生产节点上手动使用 crictl 启动 Pod 或容器。
- 用户将无法使用 docker images 命令看到 Kubernetes 拉取的镜像。请改用 crictl images 命令。反之亦然,Kubernetes 将无法看到由 docker pull、docker load 或 docker build 命令创建的镜像。请改用 crictl pull 命令,如果必须加载镜像,请使用 ctr cri load。
总结
- Containerd 1.1 原生支持 CRI。它可以直接被 Kubernetes 使用。
- Containerd 1.1 已达到生产就绪状态。
- Containerd 1.1 在 Pod 启动延迟和系统资源利用率方面表现良好。
- crictl 是用于与 containerd 1.1 及其他符合 CRI 的容器运行时进行交互的命令行工具,用于节点故障排除。
- Docker CE 的下一个稳定版本将包含 containerd 1.1。用户可以选择继续将 Docker 用于非 Kubernetes 特定的用例,并配置 Kubernetes 使用 Docker 附带的同一个底层 containerd。
我们要感谢来自 Google、IBM、Docker、中兴、浙大以及许多其他促成此事发生的个人贡献者们!
有关 containerd 1.1 版本的详细更改列表,请参阅此处:https://github.com/containerd/containerd/releases/tag/v1.1.0
试用
使用 containerd 作为容器运行时来设置 Kubernetes 集群
- 对于使用 kube-up.sh 在 GCE 上启动的生产级集群,请参见此处。
- 对于使用 Ansible 和 kubeadm 的多节点集群安装程序和启动步骤,请参见此处。
- 对于从头开始在 Google Cloud 上创建集群,请参见Kubernetes the Hard Way。
- 对于从发布 tarball 进行自定义安装,请参见此处。
- 要使用 LinuxKit 在本地虚拟机上安装,请参见此处。
贡献
containerd CRI 插件是 containerd 中的一个开源 GitHub 项目:https://github.com/containerd/cri。欢迎任何关于想法、问题和/或修复的贡献。开发者入门指南是贡献者的一个良好起点。
社区
该项目由 Kubernetes SIG-Node 社区和 containerd 社区成员共同开发和维护。我们很想听取你的反馈。加入社区:
- sig-node 社区网站
- Slack
- 在 kubernetes.slack.com 的 #sig-node 频道
- 在 https://dockr.ly/community 的 #containerd 频道
- 邮件列表:https://groups.google.com/forum/#!forum/kubernetes-sig-node