更新:弃用 Dockershim 的常见问题

本文是针对2020年末发布的弃用 Dockershim 的常见问题的博客更新。

本文回顾了自 Kubernetes v1.20 版本宣布弃用 Dockershim 以来所引发的一些常见问题。关于弃用细节以及这些细节背后的含义,请参考博文 别慌: Kubernetes 和 Docker

你还可以查阅:检查弃用 Dockershim 对你的影响这篇文章, 以确定弃用 dockershim 会对你或你的组织带来多大的影响。

随着 Kubernetes 1.24 版本的发布迫在眉睫,我们一直在努力尝试使其能够平稳升级顺利过渡。

为什么会从 Kubernetes 中移除 dockershim ?

Kubernetes 的早期版本仅适用于特定的容器运行时:Docker Engine。 后来,Kubernetes 增加了对使用其他容器运行时的支持。创建 CRI 标准是为了实现编排器(如 Kubernetes)和许多不同的容器运行时之间交互操作。 Docker Engine 没有实现(CRI)接口,因此 Kubernetes 项目创建了特殊代码来帮助过渡, 并使 dockershim 代码成为 Kubernetes 的一部分。

dockershim 代码一直是一个临时解决方案(因此得名:shim)。 你可以阅读 Kubernetes 移除 Dockershim 增强方案 以了解相关的社区讨论和计划。 事实上,维护 dockershim 已经成为 Kubernetes 维护者的沉重负担。

此外,在较新的 CRI 运行时中实现了与 dockershim 不兼容的功能,例如 cgroups v2 和用户命名空间。 取消对 dockershim 的支持将加速这些领域的发展。

在 Kubernetes 1.23 版本中还可以使用 Docker Engine 吗?

可以使用,在 1.20 版本中唯一的改动是,如果使用 Docker Engine, 在 kubelet 启动时会打印一个警告日志。 你将在 1.23 版本及以前版本看到此警告。dockershim 将在 Kubernetes 1.24 版本中移除 。

什么时候移除 dockershim ?

考虑到此变更带来的影响,我们使用了一个加长的废弃时间表。 dockershim 计划在 Kubernetes v1.24 中进行移除, 参见 Kubernetes 移除 Dockershim 增强方案。 Kubernetes 项目将与供应商和其他生态系统组织密切合作,以确保平稳过渡,并将依据事态的发展评估后续事项。

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

首先,如果你在自己的电脑上使用 Docker 用来做开发或测试容器:它将与之前没有任何变化。 无论你为 Kubernetes 集群使用什么容器运行时,你都可以在本地使用 Docker。容器使这种交互成为可能。

Mirantis 和 Docker 已承诺 为 Docker Engine 维护一个替代适配器, 并在 dockershim 从 Kubernetes 移除后维护该适配器。 替代适配器名为 cri-dockerd

我现有的容器镜像还能正常工作吗?

当然可以,docker build 创建的镜像适用于任何 CRI 实现。 所有你的现有镜像将和往常一样工作。

私有镜像呢?

当然可以。所有 CRI 运行时均支持在 Kubernetes 中相同的拉取(pull)Secret 配置, 无论是通过 PodSpec 还是 ServiceAccount。

Docker 和容器是一回事吗?

Docker 普及了 Linux 容器模式,并在开发底层技术方面发挥了重要作用, 但是 Linux 中的容器已经存在了很长时间。容器的生态相比于 Docker 具有更宽广的领域。 OCI 和 CRI 等标准帮助许多工具在我们的生态系统中发展壮大, 其中一些替代了 Docker 的某些方面,而另一些则增强了现有功能。

现在是否有在生产系统中使用其他运行时的例子?

Kubernetes 所有项目在所有版本中出产的工件(Kubernetes 二进制文件)都经过了验证。

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

至于其他示例和参考资料,你可以查看 containerd 和 CRI-O 的使用者列表, 这两个容器运行时是云原生基金会(CNCF)下的项目。

人们总在谈论 OCI,它是什么?

OCI 是 Open Container Initiative 的缩写, 它标准化了容器工具和底层实现之间的大量接口。 它们维护了打包容器镜像(OCI image)和运行时(OCI runtime)的标准规范。 它们还以 runc 的形式维护了一个 runtime-spec 的真实实现, 这也是 containerdCRI-O 依赖的默认运行时。 CRI 建立在这些底层规范之上,为管理容器提供端到端的标准。

我应该用哪个 CRI 实现?

这是一个复杂的问题,依赖于许多因素。 如果你正在使用 Docker,迁移到 containerd 应该是一个相对容易地转换,并将获得更好的性能和更少的开销。 然而,我们鼓励你探索 CNCF landscape 提供的所有选项,做出更适合你的选择。

当切换 CRI 实现时,应该注意什么?

虽然 Docker 和大多数 CRI(包括 containerd)之间的底层容器化代码是相同的, 但其周边部分却存在差异。迁移时要考虑如下常见事项:

  • 日志配置
  • 运行时的资源限制
  • 调用 docker 或通过其控制套接字使用 docker 的节点配置脚本
  • 需要访问 docker 命令或控制套接字的 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,你可查阅有关它的文档, 获取迁移时可用的配置选项。

有关如何在 Kubernetes 中使用 containerd 和 CRI-O 的说明, 请参阅 Kubernetes 相关文档

我还有其他问题怎么办?

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

你也可以看看这篇优秀的博客文章:等等,Docker 被 Kubernetes 弃用了? 对这些变化进行更深入的技术讨论。

我可以加入吗?

当然,只要你愿意,随时随地欢迎。🤗🤗🤗