更新:移除 Dockershim 的常见问题解答

本文档取代了 2020 年底发布的原始文章弃用 Dockershim:常见问题解答。本文档包含 Kubernetes v1.24 版本的更新内容。


本文档解答了一些关于从 Kubernetes 中移除 dockershim 的常见问题。移除计划最初是在 Kubernetes v1.20 发布时宣布的。Kubernetes v1.24 版本实际上已将 dockershim 从 Kubernetes 中移除。

欲了解更多信息,请查看博文别慌:Kubernetes 和 Docker

要确定移除 dockershim 对您或您的组织会产生何种影响,您可以阅读检查 dockershim 移除是否对你有影响

在 Kubernetes 1.24 发布前的几个月和几天里,Kubernetes 的贡献者们努力工作,以确保这是一个平稳的过渡。

为什么 Dockershim 会从 Kubernetes 中被移除?

Kubernetes 的早期版本只支持特定的容器运行时:Docker Engine。后来,Kubernetes 增加了对其他容器运行时的支持。CRI 标准的创建是为了实现编排器(如 Kubernetes)和多种不同容器运行时之间的互操作性。Docker Engine 并没有实现这个接口(CRI),所以 Kubernetes 项目创建了特殊的代码来帮助过渡,并将这个 dockershim 代码作为 Kubernetes 本身的一部分。

dockershim 代码一直被认为是一个临时的解决方案(正如其名:shim)。您可以在移除 Dockershim 的 Kubernetes 增强提案中阅读更多关于社区讨论和规划的内容。事实上,维护 dockershim 已经成为 Kubernetes 维护者的沉重负担。

此外,一些与 dockershim 不兼容的特性,如 cgroups v2 和用户命名空间,正在这些新的 CRI 运行时中实现。从 Kubernetes 中移除 dockershim 有助于在这些领域取得进一步发展。

Docker 和容器是一回事吗?

Docker 普及了 Linux 容器模式,并在底层技术的开发中发挥了重要作用,然而 Linux 中的容器早已存在。容器生态系统已经发展到远不止 Docker 的范畴。像 OCI 和 CRI 这样的标准帮助了许多工具在我们的生态系统中成长和繁荣,其中一些工具取代了 Docker 的某些方面,而另一些则增强了现有的功能。

我现有的容器镜像还能用吗?

是的,通过 docker build 生成的镜像将与所有 CRI 实现兼容。您现有的所有镜像将和以前完全一样地工作。

私有镜像呢?

是的。所有 CRI 运行时都支持 Kubernetes 中使用的相同的拉取凭证配置,无论是通过 PodSpec 还是 ServiceAccount。

我还能在 Kubernetes 1.23 中使用 Docker Engine 吗?

是的,1.20 版本中唯一的变化是,如果使用 Docker Engine 作为运行时,kubelet 启动时会打印一条警告日志。在 1.23 及之前的所有版本中,你都会看到这个警告。dockershim 的移除发生在 Kubernetes 1.24 中。

如果您正在运行 Kubernetes v1.24 或更高版本,请参阅我还能使用 Docker Engine 作为我的容器运行时吗?。(请记住,如果您使用的是任何受支持的 Kubernetes 版本,都可以从 dockershim 迁移出来;从 v1.24 版本开始,您必须迁移,因为 Kubernetes 不再包含 dockershim)。

我应该使用哪个 CRI 实现?

这是一个复杂的问题,取决于很多因素。如果 Docker Engine 对你来说工作得很好,那么迁移到 containerd 应该是一个相对容易的替换,并且性能会更好,开销也更小。然而,我们鼓励你探索 CNCF 全景图中的所有选项,以防有其他选项更适合你的环境。

我还能使用 Docker Engine 作为我的容器运行时吗?

首先,如果你在自己的电脑上使用 Docker 开发或测试容器:什么都不会改变。无论你的 Kubernetes 集群使用什么容器运行时,你仍然可以在本地使用 Docker。容器使这种互操作性成为可能。

Mirantis 和 Docker 已经承诺维护一个 Docker Engine 的替代适配器,并且即使在 Kubernetes 移除内置的 dockershim 之后,也会继续维护该适配器。这个替代适配器名为 cri-dockerd

你可以安装 cri-dockerd 并用它来连接 kubelet 和 Docker Engine。请阅读将 Docker Engine 节点从 dockershim 迁移到 cri-dockerd 以了解更多信息。

目前在生产环境中使用其他运行时的例子多吗?

所有 Kubernetes 项目产生的工件(Kubernetes 二进制文件)在每个版本发布时都经过了验证。

此外,kind 项目使用 containerd 已经有一段时间了,并且在其用例中看到了稳定性的提升。Kind 和 containerd 每天都被多次利用来验证对 Kubernetes 代码库的任何更改。其他相关项目也遵循类似的模式,证明了其他容器运行时的稳定性和可用性。例如,OpenShift 4.x 自 2019 年 6 月以来一直在生产环境中使用 CRI-O 运行时。

有关其他示例和参考,你可以查看 containerd 和 CRI-O 的采用者,这两个容器运行时都隶属于云原生计算基金会(CNCF)。

人们一直在提 OCI,那是什么?

OCI 代表开放容器倡议,它标准化了容器工具和技术之间的许多接口。他们维护着一个用于打包容器镜像(OCI 镜像规范)和运行容器(OCI 运行时规范)的标准规范。他们还以 runc 的形式维护了一个运行时规范的实际实现,runc 是 containerdCRI-O 的底层默认运行时。CRI 在这些低级规范的基础上构建,为管理容器提供了一个端到端的标准。

在更换 CRI 实现时,我应该注意什么?

虽然 Docker 和大多数 CRI(包括 containerd)之间的底层容器化代码是相同的,但在一些边缘方面存在一些差异。迁移时需要考虑的一些常见事项是:

  • 日志记录配置
  • 运行时资源限制
  • 调用 docker 或通过其控制套接字使用 Docker Engine 的节点配置脚本
  • 需要 docker CLI 或 Docker Engine 控制套接字的 kubectl 插件
  • 需要直接访问 Docker Engine 的 Kubernetes 项目工具(例如:已弃用的 kube-imagepuller 工具)
  • 诸如 registry-mirrors 和不安全镜像仓库等功能的配置
  • 期望 Docker Engine 可用且在 Kubernetes 之外运行的其他支持脚本或守护进程(例如,监控或安全代理)
  • GPU 或特殊硬件及其与你的运行时和 Kubernetes 的集成方式

如果你使用 Kubernetes 的资源请求/限制或基于文件的日志收集 DaemonSet,它们将继续以相同的方式工作,但如果你自定义了 dockerd 配置,你需要尽可能地为你的新容器运行时进行调整。

另一个需要注意的事情是,任何期望在构建镜像时为系统维护或嵌套在容器内运行的东西都将不再工作。对于前者,你可以使用 crictl 工具作为直接替代品(参见从 docker cli 到 crictl 的映射);对于后者,你可以使用更新的容器构建选项,如 imgbuildahkanikobuildkit-cli-for-kubectl,这些都不需要 Docker。

对于 containerd,你可以从他们的文档开始,看看在迁移过程中有哪些配置选项可用。

有关如何将 containerd 和 CRI-O 与 Kubernetes 一起使用的说明,请参阅 Kubernetes 关于容器运行时的文档。

如果我有更多问题怎么办?

如果你使用的是供应商支持的 Kubernetes 发行版,可以向他们咨询其产品的升级计划。对于最终用户的问题,请发布到我们的最终用户社区论坛:https://discuss.kubernetes.io/

你可以通过一个专门的 GitHub issue 来讨论移除 dockershim 的决定。

你也可以查看这篇优秀的博文等等,Docker 在 Kubernetes 中被弃用了?现在我该怎么办?,其中对这些变化进行了更深入的技术讨论。

有什么工具可以帮助我发现正在使用的 dockershim 吗?

有!Docker Socket 检测器(DDS)是一个 kubectl 插件,你可以安装它然后用它来检查你的集群。DDS 可以检测到活动的 Kubernetes 工作负载是否将 Docker Engine 套接字(docker.sock)作为卷挂载。更多细节和使用模式请参见 DDS 项目的 README

可以给我一个拥抱吗?

当然,我们仍然应要求提供拥抱。🤗🤗🤗