本文发表于一年多前。旧文章可能包含过时内容。请检查页面中的信息自发布以来是否已变得不正确。
Containerd 为 Kubernetes 带来更多容器运行时选项
更新:Kubernetes 通过 `dockershim` 对 Docker 的支持现已弃用。欲了解更多信息,请阅读弃用通知。您也可以通过专门的 GitHub issue 讨论弃用问题。
容器运行时是执行容器并在节点上管理容器映像的软件。如今,最广为人知的容器运行时是 Docker,但生态系统中还有其他容器运行时,例如 rkt、containerd 和 lxd。Docker 是生产 Kubernetes 环境中使用最常见的容器运行时,但 Docker 的小弟 containerd 可能被证明是一个更好的选择。本文描述了如何将 containerd 与 Kubernetes 结合使用。
Kubernetes 1.5 引入了一个名为 容器运行时接口 (CRI) 的内部插件 API,以便轻松访问不同的容器运行时。CRI 使 Kubernetes 能够使用各种容器运行时,而无需重新编译。理论上,Kubernetes 可以使用任何实现 CRI 的容器运行时来管理 Pod、容器和容器镜像。
在过去的6个月中,来自Google、Docker、IBM、中兴和浙江大学的工程师们致力于为containerd实现CRI。该项目名为cri-containerd,并于2017年9月25日发布了功能完备的v1.0.0-alpha.0版本。借助cri-containerd,用户可以在不安装Docker的情况下,使用containerd作为底层运行时来运行Kubernetes集群。
containerd
Containerd 是一个兼容 OCI 的核心容器运行时,旨在嵌入到更大的系统中。它提供了在节点上执行容器和管理镜像所需的最少功能集。它由 Docker Inc. 发起,并于2017年3月捐赠给 CNCF。Docker 引擎本身是建立在 containerd 的早期版本之上,并将很快更新到最新版本。Containerd 即将发布功能完备的稳定版本,目前 1.0.0-beta.1 已可用。
Containerd 的范围比 Docker 小得多,提供了一个 Golang 客户端 API,并且更注重可嵌入性。较小的范围带来了更小的代码库,随着时间的推移更容易维护和支持,这与 Kubernetes 的要求相符,如下表所示:
Containerd 范围 (包含/不包含) | Kubernetes 要求 | |
---|---|---|
容器生命周期管理 | 包含 | 容器创建/启动/停止/删除/列出/检查 (✔️) |
镜像管理 | 包含 | 拉取/列出/检查 (✔️) |
网络 | 不包含,无具体网络解决方案。用户可以设置网络命名空间并将容器放入其中。 | Kubernetes 网络处理的是 Pod,而不是容器,因此容器运行时不应提供不满足要求的复杂网络解决方案。(✔️) |
卷 | 不包含,无卷管理。用户可以设置主机路径并将其挂载到容器中。 | Kubernetes 管理卷。容器运行时不应提供可能与 Kubernetes 冲突的内部卷管理。(✔️) |
持久化容器日志 | 不包含,无持久化容器日志。容器标准输入输出作为 FIFO 提供,可以根据需要进行重定向/修饰。 | Kubernetes 对持久化容器日志有特定要求,例如格式和路径等。容器运行时不应持久化不可管理的容器日志。(✔️) |
指标 | 包含。Containerd 提供容器和快照指标作为 API 的一部分。 | Kubernetes 期望容器运行时提供容器指标(CPU、内存、可写层大小等)和镜像文件系统使用情况(磁盘、inode 使用情况等)。(✔️) |
总的来说,从技术角度看,containerd 是 Kubernetes 一个非常好的替代容器运行时。 |
cri-containerd
Cri-containerd 就是这样一个项目:它是 containerd 的 CRI 实现。它与 Kubelet 和 containerd 在同一节点上运行。cri-containerd 位于 Kubernetes 和 containerd 之间,处理来自 Kubelet 的所有 CRI 服务请求,并使用 containerd 来管理容器和容器镜像。cri-containerd 通过形成 containerd 服务请求,并添加足够的额外功能来支持 CRI 要求,从而部分地管理这些服务请求。
与当前的 Docker CRI 实现(dockershim)相比,cri-containerd 消除了堆栈中的额外一层,使堆栈更稳定、更高效。
架构
Cri-containerd 使用 containerd 来管理完整的容器生命周期和所有容器镜像。如下所示,cri-containerd 还通过 CNI(另一个 CNCF 项目)管理 Pod 网络。
我们用一个例子来演示当 Kubelet 创建一个单容器 Pod 时 cri-containerd 是如何工作的:
- Kubelet 通过 CRI 运行时服务 API 调用 cri-containerd 创建一个 Pod;
- cri-containerd 使用 containerd 创建并启动一个特殊的 暂停容器(沙箱容器),并将该容器放入 Pod 的 cgroups 和命名空间中(为简洁起见,省略了步骤);
- cri-containerd 使用 CNI 配置 Pod 的网络命名空间;
- Kubelet 随后通过 CRI 镜像服务 API 调用 cri-containerd 拉取应用程序容器镜像;
- 如果镜像在节点上不存在,cri-containerd 会进一步使用 containerd 拉取镜像;
- 然后 Kubelet 通过 CRI 运行时服务 API 调用 cri-containerd,使用拉取的容器镜像在 Pod 内创建并启动应用程序容器;
- cri-containerd 最后调用 containerd 创建应用程序容器,将其放入 Pod 的 cgroups 和命名空间中,然后启动 Pod 的新应用程序容器。完成这些步骤后,一个 Pod 及其相应的应用程序容器就被创建并运行了。
状态
Cri-containerd v1.0.0-alpha.0 于2017年9月25日发布。
它功能齐全。支持所有 Kubernetes 功能。
所有 CRI 验证测试 已通过。(CRI 验证是一个测试框架,用于验证 CRI 实现是否满足 Kubernetes 的所有要求。)
所有常规的 节点端到端测试 已通过。(Kubernetes 测试框架,用于测试 Kubernetes 节点级别功能,例如管理 Pod、挂载卷等。)
要了解有关 v1.0.0-alpha.0 版本的更多信息,请参阅项目仓库。
试用一下
有关使用 Ansible 和 Kubeadm 进行多节点集群安装和启动的步骤,请参阅此仓库链接。
如需在 Google Cloud 上从头开始创建集群,请参阅 Kubernetes the Hard Way。
有关从发布压缩包进行自定义安装,请参阅此仓库链接。
要在本地虚拟机上使用 LinuxKit 进行安装,请参阅此仓库链接。
后续步骤
我们将稳定性与可用性改进作为下一步重点。
稳定性
- 在 Ubuntu、COS (Container-Optimized OS) 等各种操作系统发行版上,在 Kubernetes 测试基础设施中设置一套完整的 Kubernetes 集成测试。
- 积极修复用户报告的任何测试失败和其他问题。
可用性
- 改善 crictl 的用户体验。Crictl 是一个适用于所有 CRI 容器运行时的可移植命令行工具。目标是使其易于用于调试和开发场景。
- 将 cri-containerd 与 kube-up.sh 集成,帮助用户使用 cri-containerd 和 containerd 启动生产质量的 Kubernetes 集群。
- 改进我们为用户和管理员提供的文档。
我们计划在 2017 年底发布 v1.0.0-beta.0。
贡献
Cri-containerd 是一个 Kubernetes 孵化项目,位于 https://github.com/kubernetes-incubator/cri-containerd。欢迎提供任何形式的贡献,包括想法、问题和/或修复。对于贡献者而言,开发者入门指南 是一个很好的起点。
社区
Cri-containerd 由 Kubernetes SIG-Node 社区开发和维护。我们很乐意听取您的反馈。加入社区:
- sig-node 社区网站
- Slack:Kubernetes 中的 #sig-node 频道 (kubernetes.slack.com)
- 邮件列表:https://groups.google.com/forum/#!forum/kubernetes-sig-node