K8s弃用Docker

2022-05-30 19:36邰芷卉
计算机与网络 2022年19期
关键词:适配器镜像调用

邰芷卉

如今很多人关注K8s弃用Docker的事,担心现在学习Docker是否还值得,是不是该切换到containerd或其他运行时。这些怀疑有一定的道理。两年前,K8s发布“弃用Docker”的消息时,确实在社区引起了“轩然大波”,影响甚至蔓延到了社区之外,K8s发表了好几篇博客来重复解释原因。

两年过去了,虽然K8s 1.24已经实现了“弃用Docker”的目标,但很多人似乎对这一点还不是很清楚。所以这里就来聊聊这个话题。

容器运行时接口(CRI)

要理解K8s为何“弃用Docker”,我们得回顾一下K8s的发展史。

2014年,Docker正处于鼎盛时期,而K8s刚刚诞生。虽然它得到了Google和Borg的支持,但它还是比较新。因此,K8s首先选择支持Docker。

快进到2016年,CNCF成立一年,K8s也发布了1.0版本,可以正式用于生产环境。这些都表明K8s已经长大了。

于是宣布加入CNCF,成为第一个CNCF托管项目,它想利用基金会的力量联合其他厂商来“打倒”Docker。

在2016年底的1.5版本中,K8s引入了新的接口标准:CRI(Container Runtime Interface)容器运行时接口。CRI使用ProtoBufferandgPRC来指定kubelet应该如何调用容器运行以管理容器和镜像,但这是一组与以前的Docker调用完全不兼容的新接口。显然它不想再和Docker绑定,在底层允许访问其他容器技术(如rkt、kata等),感觉可以随时“踢开”Docker。

但此时Docker已经非常成熟,市场的惯性也非常强。各大云厂商不可能一下子全部替換掉Docker。因此,K8s只能同时提供一种“折中”的方案,在kubelet和Docker之间增加一个“适配器”,将Docker的接口转换为CRI兼容的接口。因为这个“适配器”夹在kubeletDocker和Docker之间,所以形象地被称为shim,意思是“垫片”。

有了CRI和shim,虽然K8s仍然使用Docker作为底层运行时,但它也具备了与Docker解耦的条件,从而拉开了“弃用Docker”大戏的帷幕。

Containerd

面对挑战,Docker采取了“断臂求生”的策略,推动自身重构,将原有单一架构的Docker Engine拆分成多个模块,其中Docker daemon部分捐赠给CNCF,containerd形成。

作为CNCF的托管项目,containerd必须符合CRI标准。但是由于很多原因,Docker只是containerd在Docker Engine中调用,对外的接口保持不变,也就是说不兼容CRI。

由于Docker的“固执”,此时K8s中有2条调用链:

使用CRI接口调用dockershim,然后dockershim调用Docker,Docker再去containerd操作容器;

使用CRI接口直接调用containerd操作容器。

显然,因为containerd是用来管理容器的,所以这2个调用链的最终效果是完全一样的,但是第二种方法去掉了dockershim和Docker Engine这2个环节,更加简洁明性能也更好。

2018年Kubernetes 1.10发布时,containerd也更新到1.1版本,正式与Kubernetes集成,并发表显示一些性能测试的数据。从这些数据可以看出,相比当时的Docker 18.03,containerd1.1Pod启动延迟降低了20 %左右,CPU使用率降低了68 %,内存使用率降低了12 %,这样可观的性能提升对云厂商来说非常有诱惑力。

弃用Docker

2020年,K8s 1.20终于正式向Docker“宣战”:kubelet将弃用Docker支持,并将在未来的版本中完全移除。但由于Docker几乎已经成为容器技术的代名词,而且K8s也已经使用Docker多年,该公告在传播时很快“变味了”,“kubelet将弃用Docker支持”被简化为更吸人眼球的东西“K8s将弃用Docker”。

这自然引起了IT界的恐慌,“不明真相的群众”纷纷表示震惊:

“用了这么久的Docker突然不能用了。”

“为什么K8s会这样对待Docker?”

“之前对Docker的投资会归零吗?现有的大量镜像怎么办?”

其实,如果了解了上面提到的这2个项目CRI,containerd你就会知道,K8s的这一举动并不奇怪,一切都是“自然”的:其实只是“弃用dockershim”,也就是dockershim搬出kubelet,并不是“弃用Docker”的软件产品。

因此,“弃用Docker”对K8s和Docker的影响不大,因为它们都已经将底层改为开源containerd,原有的Docker镜像和容器仍然可以正常运行。唯一的变化是K8s绕过了Docker,直接调用Docker内部的containerd。

然而,还是会有一些影响。如果K8s直接使用containerd来操作容器,那么它就是独立于Docker的工作环境,二者都无法访问对方管理的容器和镜像。换句话说,使用docker ps命令将不会看到K8s中运行的容器。

这对一些人来说可能需要花一点时间来适应并使用新工具crictl,但用于查看容器和镜像的子命令仍然是相同的,例如ps,images等,其实不难适应(如果你一直在用kubectl管理K8s,就没有这个影响)。

K8s原本计划用一年时间完成“弃用Docker”的工作,但它确实低估了Docker的基础。1.23版本还是没能移除dockershim,只好延期半年。最后,1.24版本从kubelet中删除了dockershim的代码。

从此,Kubernetes与Docker彻底“分道扬镳”。

Docker的未来

那么,Docker的未来会怎样呢?云原生时代就没有它的立足之地吗?这个问题的答案显然是否定的。

作为容器技术的奠基人,没有人可以质疑Docker的历史地位。虽然K8s默认不再绑定Docker,但Docker仍然可以与其他形式的K8s共存。

首先,由于容器镜像格式已经标准化(OCI规范,Open Container Initiative),Docker镜像在K8s中仍然可以正常使用,不需要改变原有的开发测试和CI/CD流程。我们仍然可以拉取Docker Hub,或编写一个Dockerfile来打包应用程序。

其次,Docker是一个完整的软件产品线,它不仅仅是containerd,它还包括镜像构建、分发、测试等很多服务,甚至连K8s都内置于Docker Desktop中。

就容器开发的便利性而言,Docker暂时还难以被取代。大多数云原生开发人员可以继续在这个熟悉的环境中工作,使用Docker来开发在K8s中运行的应用程序。

同样,虽然K8s不再包含dockershim,Docker已经接管了这部分代码并构建了一个名为cri-dockerd的项目,该项目也同样工作,将Docker Engine适配为CRI接口,这样kubelet可以通过它再次操作Docker,就像它从来没有发生过一样。

总的来说,Docker虽然在容器编排大战中败下阵来,被K8s挤到了墙角,但依然具有很强的生命力。多年积累的众多忠实用户和大量应用形象是其最大的资本和后盾,足以支持它在另一条不与K8s正面交锋的道路上。

对于初学者来说,Docker简单易用,工具链完整,界面友好,市面上很难找到与之相媲美的软件,应该说是入门级学习容器技术和云原生的上上选择。

猜你喜欢
适配器镜像调用
镜像
核电项目物项调用管理的应用研究
LabWindows/CVI下基于ActiveX技术的Excel调用
镜像
适配器模式及其应用
新型水文测验GPS适配器设计与应用
基于系统调用的恶意软件检测技术研究
基于蓝牙串口适配器的GPS接收机与AutoCAD的实时无线通信
美国麦格普公司新型M—LOK相机三脚架适配器
镜像