【K8S】关于Kubernetes弃用Docker一事
一、Kubernetes 为什么弃用 Docker
2014 年左右是 Docker 如日中天的时候,在容器领域没有任何对手,而这时 Kubernetes 才刚刚诞生,虽然背后有 Google 和 Borg 的支持但还是比较弱小,当时的 Kubernetes 也只有选择在 Docker 上运行。到2016年时CNCF 已经成立一年,而 Kubernetes 也已经发布了可以正式用于生产环境的1.0版本,于是它宣布加入了 CNCF,成为了第一个 CNCF 托管项目。
2016 年底的 1.5 版里,Kubernetes 引入了一个新的接口标准:Container Runtime Interface(CRI)。CRI 采用了 ProtoBuffer 和 gPRC,规定 kubelet 该如何调用容器运行时去管理容器和镜像,但这一套全新的接口和之前的 Docker 调用完全不兼容。Kubernetes 允许在底层接入其他容器技术(比如 rkt、kata 等)。这个时候 Docker 已经非常成熟,市场的惯性也非常强大,各大云厂商不可能一下子就把 Docker 全部替换掉。所以 Kubernetes 也只能同时提供一个“折中”方案,在 kubelet 和 Docker 中间加入一个垫片(shim)作为适配器,把 Docker 的接口转换成符合 CRI 标准的接口。有了 CRI 和 shim后Kubernetes 具备了和 Docker 解耦的条件。
二、什么是 containerd
Docker 为了自保开始推动自身的重构,把原本单体架构的 Docker Engine 拆分成了多个模块,其中的 Docker daemon 部分捐献给了 CNCF,形成了 containerd。containerd 作为 CNCF 的托管项目是符合 CRI 标准的。但 Docker 出于自己诸多原因的考虑,它只是在 Docker Engine 里调用了 containerd,外部的接口仍然保持不变,也就是说还不与 CRI 兼容。这时 Kubernetes 里就出现了两种调用链:
· 第一种是用 CRI 接口调用 dockershim,然后 dockershim 调用 Docker,Docker 再走 containerd 去操作容器
· 第二种是用 CRI 接口直接调用 containerd 去操作容器(省去了 dockershim 和 Docker Engine 两个环节,性能更好)
在 2018 年 Kubernetes 1.10 发布的时候,containerd 也更新到了 1.1 版,正式与 Kubernetes 集成。按照官方给出的性能测试数据,containerd1.1 相比当时的 Docker 18.03,Pod 的启动延迟降低了大约 20%,CPU 使用率降低了 68%,内存使用率降低了 12%。这个巨大的性能改善吸引了各大云厂商的关注。
三、正式“弃用 Docker”
2020年,Kubernetes 1.20在拥有 CRI 和 containerd 后正式宣布 kubelet 将弃用 Docker 支持,并会在未来的版本中彻底删除。这个声明发布后就引起了恐慌,因为 Docker 几乎成为了容器技术的代名词,而且 Kubernetes 也已经使用 Docker 很多年。但是如果理解 CRI 和 containerd 这两个项目就知道 Kubernetes 的这个举动只是弃用了 dockershim这个小组件,也就是说把 docker shim 移出了 kubelet,并不是弃用了 Docker。对早已经把下层改成开源 containerd的K8S和Docker都不会有太大影响,原来的 Docker 镜像和容器仍然会正常运行,唯一的变化就是 Kubernetes 绕过了 Docker后直接调用 Docker 内部的 containerd 。如果是使用 kubectl 来管理 Kubernetes 的话这基本没有任何影响,如果是使用docker命令的话则看不到Kubernetes 里运行的容器。在官方弃用Docker后,直到 1.24 版才把 dockershim 从 kubelet 里清除掉。
四、Docker 的未来
虽然现在 Kubernetes 不再默认使用 Docker作为CRI,但 Docker 还是能够以其他的形式与 Kubernetes 共存的。Docker 镜像仍然可以在 Kubernetes 里正常使用,仍然可以拉取 Docker Hub 上的镜像或者编写 Dockerfile 来打包应用。单就容器开发的便利性来讲Docker 还是暂时难以被替代的,广大云原生开发者可以在这个熟悉的环境里继续工作,利用 Docker 来开发运行在 Kubernetes 里的应用。再次,虽然 Kubernetes 已经不再包含 dockershim,但Docker 公司却把这部分代码接管了过来,另建了一个叫 cri-dockerd(https://github.com/mirantis/cri-dockerd)的项目,作用也是一样的,把 Docker Engine 适配成 CRI 接口,这样 kubelet 就又可以通过它来操作 Docker 了。
Docker 虽然被 Kubernetes 排挤到了角落,但它仍然具有强韧的生命力,多年来积累的众多忠实用户和数量庞大的应用镜像是它的最大资本和后盾,足以支持它在另一条不与 Kubernetes 正面交锋的道路上走下去。Docker 简单易用,并且具有完善的工具链和友好的交互界面,市面上很难找到能够与它媲美的软件,应该说是入门学习容器技术和云原生的不二之选。至于 Kubernetes 底层用的什么,不必太过于执着和关心
评论