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

对于 containerd 1.0,需要在 Kubelet 和 containerd 之间运行一个名为 cri-containerd 的守护进程。Cri-containerd 处理来自 Kubelet 的 容器运行时接口 (CRI) 服务请求,并使用 containerd 来管理容器和容器镜像。与 Docker CRI 实现(dockershim)相比,这消除了堆栈中的一个额外跃点。
然而,cri-containerd 和 containerd 1.0 仍然是通过 grpc 交互的 2 个不同的守护进程。循环中的额外守护进程使得用户更难以理解和部署,并引入了不必要的通信开销。
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 时,与使用 dockershim 的 Docker 18.03 CE 集成相比,containerd 1.1 集成消耗的 CPU 和内存总体上更少。结果会随着节点上运行的 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 的替代 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 和 命名空间,因此它无法提供容器和 pod 的清晰视图。一个示例是 docker ps 显示有些模糊、很长的 Docker 容器名称,并且同时显示暂停容器和应用程序容器。

然而,暂停容器是 pod 的实现细节,其中每个 pod 使用一个暂停容器,因此在列出 pod 的成员容器时不应显示暂停容器。
相比之下,crictl 是为 Kubernetes 设计的。它具有用于 pod 和容器的不同命令集。例如,crictl pods 列出 pod 信息,而 crictl ps 仅列出应用程序容器信息。所有信息都格式化为表格列。


另一个示例,crictl pods 包括一个 --namespace 选项,用于按 Kubernetes 中指定的命名空间过滤 pod。

有关如何将 crictl 与 containerd 一起使用的更多详细信息
Docker Engine 怎么样?
“切换到 containerd 是否意味着我不能再使用 Docker Engine 了?”我们经常听到这个问题,简短的回答是 NO。
Docker Engine 构建在 containerd 之上。下一个版本的 Docker Community Edition (Docker CE) 将使用 containerd 版本 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 的容器运行时进行通信的 CLI 工具,用于节点故障排除。
- 下一个稳定版本的 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 进行自定义安装,请参阅此处。
- 要在本地 VM 上使用 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