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

Dockershim:历史背景

自 Kubernetes v1.24 起,Dockershim 已被移除,这对项目来说是一个积极的举措。然而,无论是从社会角度还是在软件开发中,上下文对于充分理解事物都至关重要,因此这值得更深入的审视。随着 Kubernetes v1.24 中 dockershim 的移除,我们看到社区中对此决定存在一些困惑(有时甚至是恐慌级别)和不满,这主要是由于缺乏对移除原因的上下文了解。弃用并最终从 Kubernetes 中移除 dockershim 的决定并非仓促或轻率做出的。然而,它已经酝酿了很长时间,以至于今天许多用户都比这个决定要新,当然也比最初导致 dockershim 成为必要选择要新得多。

那么,dockershim 是什么?为什么它要被移除?

在 Kubernetes 的早期,我们只支持一种容器运行时。该运行时就是 Docker Engine。那时,市面上并没有很多其他选择,Docker 是使用容器的主流工具,所以这不是一个有争议的选择。最终,我们开始添加更多容器运行时,例如 rkt 和 hypernetes,并且很明显 Kubernetes 用户希望能够选择最适合他们的运行时。因此,Kubernetes 需要一种方式来让集群操作员能够灵活地使用他们选择的任何运行时。

容器运行时接口 (CRI) 的发布是为了提供这种灵活性。CRI 的引入对项目和用户都非常有利,但也带来了一个问题:Docker Engine 作为容器运行时使用早于 CRI,而 Docker Engine 不兼容 CRI。为了解决这个问题,kubelet 组件中引入了一个小型软件 shim (dockershim),专门用于弥补 Docker Engine 和 CRI 之间的空白,从而允许集群操作员在很大程度上不间断地继续使用 Docker Engine 作为他们的容器运行时。

然而,这个小小的软件垫片从未打算成为一个永久性解决方案。多年来,它的存在给 kubelet 本身带来了许多不必要的复杂性。由于这个垫片,一些集成在 Docker 中的实现不一致,导致维护人员的负担增加,而且维护特定于供应商的代码不符合我们的开源理念。为了减轻这种维护负担,并朝着支持开放标准的更具协作性的社区迈进,引入了 KEP-2221,提议移除 dockershim。随着 Kubernetes v1.20 的发布,弃用正式生效。

我们在这方面沟通得并不好,不幸的是,弃用公告在社区内引起了一些恐慌。关于这对 Docker 公司意味着什么,Docker 构建的容器镜像是否仍能运行,以及 Docker Engine 到底是什么的困惑,在社交媒体上引发了一场轩然大波。这是我们的错;我们当时应该更清楚地沟通发生了什么以及为什么。为了解决这个问题,我们发布了一篇博客配套的 FAQ,以缓解社区的担忧,并纠正关于 Docker 是什么以及容器如何在 Kubernetes 中工作的一些误解。鉴于社区的担忧,Docker 和 Mirantis 共同同意以 cri-dockerd 的形式继续支持 dockershim 代码,如果需要,您可以继续使用 Docker Engine 作为您的容器运行时。为了对希望尝试其他运行时(如 containerd 或 cri-o)的用户感兴趣,我们编写了迁移文档

我们后来调查了社区,并发现仍有许多用户存在疑问和担忧。为此,Kubernetes 维护者和 CNCF 承诺通过扩展文档和其他计划来解决这些担忧。事实上,这篇博客文章就是该计划的一部分。随着如此多的最终用户成功迁移到其他运行时,以及改进的文档,我们相信现在每个人都有了一条通往迁移的康庄大道。

Docker 不会消失,无论是作为一个工具还是作为一家公司。它是云原生社区和 Kubernetes 项目历史的重要组成部分。没有他们,我们不会有今天的成就。话虽如此,从 kubelet 中移除 dockershim 最终对社区、生态系统、项目和整个开源都有益。这是一个我们所有人齐心协力支持开放标准的机会,我们很高兴能在 Docker 和社区的帮助下做到这一点。