乐趣区

关于程序员:K8s-为什么要弃用-Docker

在写“K8s”系列文章的过程中,很多读者留言询问 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 中有两条调用链:

  • 应用 CRI 接口调用 dockershim,而后 dockershim 调用 Docker,Docker 再去 containerd 操作容器。
  • 应用 CRI 接口间接调用 containerd 操作容器。

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

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 的投资会归零吗?现有的大量镜像怎么办?

其实,如果你理解了下面提到的这两个我的项目 CRIcontainerd 你就会晓得,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 简略易用,工具链残缺,界面敌对,市面上很难找到与之相媲美的软件。应该说是入门级学习容器技术和云原生的“最佳抉择”。

本文译自:K8s — Why Deprecating Docker?
作者:Tony

云原生技术社区有 20+ 技术交换群,想进群跟技术大牛们聊天,或退出志愿者队伍,请加小助手微信:

本文由 mdnice 多平台公布

退出移动版