本文发表于一年多前。旧文章可能包含过时内容。请检查页面中的信息自发布以来是否已变得不正确。

Kubernetes Containerd 集成进入 GA 阶段

Kubernetes Containerd 集成进入 GA 阶段

在之前的博客《Containerd 为 Kubernetes 带来更多容器运行时选项》中,我们介绍了 Kubernetes containerd 集成的 Alpha 版本。经过 6 个月的开发,与 containerd 的集成现在已正式发布!您现在可以将 containerd 1.1 作为生产 Kubernetes 集群的容器运行时!

Containerd 1.1 可与 Kubernetes 1.10 及更高版本配合使用,并支持所有 Kubernetes 功能。在 Kubernetes 测试基础设施中,containerd 集成在 Google Cloud Platform 上的测试覆盖率现在与 Docker 集成相当(参见:测试仪表板)。

我们很高兴看到 containerd 迅速发展到这一重要里程碑。阿里云从第一天起就积极使用 containerd,凭借其简单性和健壮性,使其成为我们 Serverless Kubernetes 产品中运行的完美容器引擎,该产品对性能和稳定性有很高的要求。毫无疑问,containerd 将成为容器时代的核心引擎,并继续推动创新向前发展。

— 欣慰,阿里云高级工程师

架构改进

Kubernetes containerd 集成架构已演进两次。每次演进都使堆栈更加稳定和高效。

Containerd 1.0 - CRI-Containerd (已停止维护)

cri-containerd architecture

对于 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 architecture

在 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 集成比带有 dockershim 的 Docker 18.03 CE 集成具有更低的 Pod 启动延迟(越低越好)。

latency

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%。

cpumemory

crictl

容器运行时命令行接口 (CLI) 是系统和应用程序故障排除的有用工具。当使用 Docker 作为 Kubernetes 的容器运行时时,系统管理员有时会登录到 Kubernetes 节点,运行 Docker 命令以收集系统和/或应用程序信息。例如,可以使用 docker psdocker 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.1crictl 的设计旨在类似于 Docker CLI,为用户提供更好的过渡体验,但它并不完全相同。有一些重要的区别,如下所述。

有限范围 - crictl 是一个故障排除工具

crictl 的范围仅限于故障排除,它不能替代 docker 或 kubectl。Docker 的 CLI 提供了丰富的命令集,使其成为一个非常有用的开发工具。但它不是 Kubernetes 节点上故障排除的最佳选择。一些 Docker 命令对 Kubernetes 没有用处,例如 docker networkdocker build;有些甚至可能破坏系统,例如 docker renamecrictl 提供了足够多的命令用于节点故障排除,这在生产节点上使用可以说更安全。

Kubernetes 导向

crictl 提供了更友好的 Kubernetes 容器视图。Docker CLI 缺乏核心 Kubernetes 概念,例如 podnamespace,因此它无法提供清晰的容器和 Pod 视图。一个例子是 docker ps 显示了一些晦涩的、长长的 Docker 容器名称,并且将 pause 容器和应用程序容器一起显示。

docker ps

然而,pause 容器是 Pod 的实现细节,每个 Pod 使用一个 pause 容器,因此在列出属于 Pod 的容器时,不应显示它们。

相比之下,crictl 专为 Kubernetes 设计。它为 Pod 和容器提供了不同的命令集。例如,crictl pods 列出 Pod 信息,而 crictl ps 仅列出应用程序容器信息。所有信息都以表格列的形式良好格式化。

crictl pods crictl ps

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

crictl pods filter

有关如何将 crictl 与 containerd 结合使用的更多详细信息

Docker Engine 呢?

“切换到 containerd 意味着我不能再使用 Docker Engine 了吗?”我们经常听到这个问题,简短的答案是“不”。

Docker Engine 构建在 containerd 之上。Docker Community Edition (Docker CE) 的下一个版本将使用 containerd 1.1 版本。当然,它将内置并默认启用 CRI 插件。这意味着用户可以选择继续将 Docker Engine 用于 Docker 用户典型的其他目的,同时还可以配置 Kubernetes 以使用与 Docker Engine 在同一节点上附带并同时使用的底层 containerd。请参见下面的架构图,其中显示了 Docker Engine 和 Kubelet 使用相同的 containerd。

docker-ce

由于 Kubelet 和 Docker Engine 都使用 containerd,这意味着选择 containerd 集成的用户不仅可以获得新的 Kubernetes 功能、性能和稳定性改进,还可以选择保留 Docker Engine 用于其他用例。

Containerd 命名空间机制用于保证 Kubelet 和 Docker Engine 不会看到或访问彼此创建的容器和镜像。这确保它们不会相互干扰。这也意味着

  • 用户将无法使用 docker ps 命令查看 Kubernetes 创建的容器。请改用 crictl ps。反之亦然,用户将无法在 Kubernetes 中或使用 crictl ps 命令查看 Docker CLI 创建的容器。crictl createcrictl runp 命令仅用于故障排除。不建议在生产节点上手动使用 crictl 启动 Pod 或容器。
  • 用户将无法使用 docker images 命令查看 Kubernetes 拉取的镜像。请改用 crictl images 命令。反之亦然,Kubernetes 将无法查看由 docker pulldocker loaddocker 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 进行自定义安装,请参阅此处
  • 要在本地虚拟机上使用 LinuxKit 进行安装,请参阅此处

贡献

containerd CRI 插件是 containerd 中的一个开源 github 项目 https://github.com/containerd/cri。欢迎提出任何想法、问题和/或修复方面的贡献。开发者入门指南是贡献者入门的好地方。

社区

该项目由 Kubernetes SIG-Node 社区和 containerd 社区的成员共同开发和维护。我们很乐意听取您的反馈。加入社区