Docker、Containerd和Kubernetes之间的关系

描述

1)Kubernetes与Docker

Docker是最早出现的那批容器引擎工具,所以它最早占领了市场。Kubernetes主要用来做容器编排,用来管理容器集群,是一个平台。

Kubernetes要想去控制容器,就得借助容器引擎,在早期的Kubernetes版本里,除了选择Docker作为容器引擎外,没更好的选择。所以早期的Kubernetes和Docker深深地绑定了在一起。由于Docker可以在没有Kubernetes的情况下使用,而Kubernetes必须要有容器运行时(Docker引擎)才能进行编排。

这对于Kubernetes来说,绝对是一个非常大的隐患,这相当于是将自己命根子交给了别人,如果哪天Docker翻脸了,Kubernetes必然损失巨大。

好在,Kubernetes发展比Docker更加迅猛,势头远远盖过了Docker,Kubernetes终于有资格自己决定做一些事情了。

2)CRI

为了解决隐患,Kubernetes在1.5版本里,引入了一个新的接口标准:CRI(Container Runtime Interface),它主要用来规定如何调用容器运行时来管理容器和镜像,但这个接口标准和之前的Docker调用标准有不少差异,所以两者完全不兼容。这意味着,Kubernetes可以撇开Docker,使用其它容器运行时(如rkt)。

由于Docker用户非常庞大,Kubernetes也意识到了直接不兼容Docker会有许多不确定风险,当时,Kubernetes用了一个临时方案,在Kubernetes和Docker中间开发了一个Dockershim,主要用来将Docker的接口标准转换成CRI标准。

3)Containerd

Docker意识到Kubernetes的改变,为了迎合Kubernetes,将Docker Engine拆分成多个模块,其中Docker Daemon部分也就是说Containerd捐献给了CNCF。

所以,Containerd实际上是Docker引擎拆出来的一个模块。

Containerd 作为 CNCF 的托管项目,自然是要符合 CRI 标准的。但当时的Docker 出于自己诸多原因的考虑,它只是在 Docker Engine 里调用了 containerd,外部的接口仍然保持不变,也就是说还不与 CRI 兼容。

在当时的Kubernetes版本里,有两种方法调用容器:

第一种是用 CRI 调用 dockershim,然后 dockershim 调用 Docker,Docker 再走 containerd 去操作容器。

第二种是用 CRI 直接调用 containerd 去操作容器。

Docker

很明显,第一种方法多了两层调用,性能明显不如第二种方法。所以Kubernetes决定将dockershim移除,所以也就不能直接使用Docker了,在外界看来就像是Kubernetes弃用了Docker。

4)弃用dockershim

2020年Kubernetes发布1.20版本时,对外声明将在后续版本里(实际上是在22年的1.24版本里)移除dockershim,也就是取消对Docker的支持。当时,众多吃瓜群众理解错了意思,认为成了Kubernetes弃用Docker。它实际上只是“弃用了 dockershim”这个小组件,也就是说把 dockershim 移出了 kubelet,并不是“弃用了 Docker”这个软件产品。

这个举措对Kubernetes和 Docker 来说都不会有什么太大的影响,因为他们两个都早已经把下层都改成了开源的 containerd,原来的 Docker 镜像和容器仍然会正常运行,唯一的变化就是 Kubernetes绕过了 Docker,直接调用 Docker 内部的 containerd 而已。

5)Kubernetes移除dockershim后对Docker的影响

虽然现在 Kubernetes 不再默认绑定 Docker,但 Docker 还是能够以其他的形式与 Kubernetes 共存的。

首先,因为容器镜像格式已经被标准化了(OCI 规范,Open Container Initiative),Docker 镜像仍然可以在 Kubernetes 里正常使用,原来的开发测试、CI/CD 流程都不需要改动,我们仍然可以拉取 Docker Hub 上的镜像,或者编写 Dockerfile 来打包应用。

其次,Docker 是一个完整的软件产品线,不止是 containerd,它还包括了镜像构建、分发、测试等许多服务,甚至在 Docker Desktop 里还内置了 Kubernetes。单就容器开发的便利性来讲,Docker 还是暂时难以被替代的,广大云原生开发者可以在这个熟悉的环境里继续工作,利用 Docker 来开发运行在 Kubernetes 里的应用。

再次,虽然 Kubernetes 已经不再包含 dockershim,但 Docker 公司却把这部分代码接管了过来,另建了一个叫 cri-dockerd的项目,作用也是一样的,把 Docker Engine 适配成 CRI 接口,这样 kubelet 就又可以通过它来操作 Docker 了,就仿佛是一切从未发生过。

综合来看,Docker 虽然在容器编排战争里落败,被 Kubernetes 排挤到了角落,但它仍然具有强韧的生命力,多年来积累的众多忠实用户和数量庞大的应用镜像是它的最大资本和后盾,足以支持它在另一条不与 Kubernetes 正面交锋的道路上走下去。而对于我们这些初学者来说,Docker 方便易用,具有完善的工具链和友好的交互界面,市面上很难找到能够与它媲美的软件了,应该说是入门学习容器技术和云原生的“不二之选”。

审核编辑:汤梓红

 

打开APP阅读更多精彩内容
声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉

全部0条评论

快来发表一下你的评论吧 !

×
20
完善资料,
赚取积分