Kubernetes 正在弃用 Docker?Docker将何去何从?

一段时间以来,当人们想到容器时,似乎都会想到DockerKubernetes。在构建和运行容器方面,Docker 一直是大名鼎鼎的品牌,而在管理和编排容器方面,Kubernetes 一直是大名鼎鼎的品牌。听到 Kubernetes 从 1.20 版开始不再支持 Docker 作为容器运行时,这可能有点令人震惊。

因此,我想借此机会谈谈这一变化的真正含义,以及 Kubernetes 用户需要做些什么。

一、Docker 有何变化?

Kubernetes 弃用 Docker 实际上并不像听起来那么重要,所以让我们来谈谈这到底发生了什么。

Kubernetes 正在取消对 Docker 作为容器运行时的支持。Kubernetes 实际上并不处理在机器上运行容器的过程。相反,它依赖于另一个称为容器运行时的软件。

容器运行时在主机上运行容器,而 Kubernetes 会告诉每个主机上的容器运行时要做什么。在运行 Kubernetes 时,您可以选择多种软件作为容器运行时。到目前为止,一个相当流行的选择是使用 Docker 作为容器运行时。

然而,将来这将不再是一个选项。您仍然可以以与 Kubernetes 相关的其他方式使用 Docker(稍后会详细介绍),但您将无法将 Docker 用作 Kubernetes 下的容器运行时。

二、Kubernetes 为什么弃用 Docker?

两年前 K8s 发布“弃用 Docker”的消息时,确实在 K8s 社区引起了“轩然大波”,影响甚至蔓延到了社区之外,K8s 不得不写好几篇博客来重复解释原因。

两年过去了,虽然 K8s 1.24 已经实现了“弃用 Docker”的目标,但很多人似乎对这一点还是没有太清晰的认识。所以今天我们就来聊聊这个话题。

到目前为止,Kubernetes 已经支持使用 Docker 容器运行时,那么为什么他们选择停止支持它呢?

1. 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 使用ProtoBuffergPRC来指定应该如何kubelet调用容器运行时来管理容器和镜像,但这是一组新的接口,与以前的 Docker 调用完全不兼容。

显然它不想再与Docker绑定,而允许底层接入其他容器技术(例如rkt、kata等),并且可以随时“踢掉”Docker。

但此时Docker已经非常成熟,而且市场的惯性也非常强,各大云厂商不可能一下子把Docker全部替换掉​​。

因此K8s只能同时提供一个“折中”的方案,在kubelet和Docker之间增加一个“适配器”,将Docker的接口转换成符合CRI的接口:

因为这个“适配器”是夹在Linuxkubelet和Docker之间的,所以被形象地称为“shim”,也就是“垫片”。

有了CRI和shim,K8s虽然依然使用Docker作为底层运行,但是也具备了与Docker解耦的条件,由此拉开了“弃用Docker”大戏的序幕。

2. 容器化

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

作为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进行集成,并发表了一篇博文(https://kubernetes.io/blog/2018/05/24/kubernetes-containerd-integration-goes-ga/),展示了一些性能测试数据:

从这些数据可以看出,相比当时的Docker 18.03,containerd1.1降低了Pod启动延迟约20%,CPU使用率降低了68%,内存使用率降低了12%,这是一个相当大的性能提升,对于云厂商来说非常有诱惑力。

3. 官方弃用 Docker

两年后,也就是2020年,K8s 1.20终于正式向Docker“宣战”:将kubelet不再支持Docker,并且在未来的版本中彻底删除。

但由于 Docker 几乎已经成为容器技术的代名词,而且 K8s 多年来也一直在使用 Docker,因此该公告在传播过程中很快就“散发出恶臭”,“kubelet 将弃用 Docker 支持”被简化为更吸引眼球的“K8s 将弃用 Docker”。

这自然引起了IT界的恐慌,“不明真相的群众”纷纷表示震惊:用了这么久的Docker突然不能用了。K8s为何如此对待Docker?之前对Docker的投资会化为零吗?大量的现有镜像该如何处理?

其实,如果你了解上面提到的两个项目CRIcontainerdKubernetes,就会知道K8s的这一举动并不令人意外,一切都很“自然”:它其实只是“弃用dockershim ”,也就是搬出dockershim来而已kubelet并不是“弃用Docker”的软件产品。

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

但是会有一些影响,如果containerd直接使用 K8s 来操作容器,那么它和 Docker 就是一个独立的工作环境,双方都无法访问对方管理的容器和镜像,也就是说使用命令docker ps是看不到 K8s 中正在运行的容器的。

这对于某些人来说可能需要一点时间来适应和使用新工具crictl,但用于查看容器和图像的子命令仍然相同,例如psimages等,适应起来并不困难(但如果我们一直使用 kubectl 来管理 K8s 的话,这就没什么影响了)。

K8s 原本计划用一年时间完成“淘汰 Docker”的工作,但确实低估了 Docker 的基础,dockershim在 1.23 版本依然未能淘汰,不得不推迟了半年,最终在今年 5 月份发布的 1.24 版本才将代码dockershimkubelet.

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

Kubernetes 可与所有实现容器运行时接口 (CRI)标准的容器运行时配合使用。这本质上是 Kubernetes 与容器运行时之间通信的标准方式,任何支持此标准的运行时都可以自动与 Kubernetes 配合使用。

Docker 未实现容器运行时接口 (CRI)。过去,容器运行时没有太多好的选择,而 Kubernetes 实现了 Docker shim,这是一个额外的层,用作 Kubernetes 和 Docker 之间的接口。然而,现在有很多运行时可以实现 CRI,Kubernetes 不再有必要为 Docker 提供特殊支持。

三、Docker 未来将扮演什么角色?

那么,Docker 的未来会怎样?在云原生时代,它是否已经没有立足之地?答案显然是否定的。

作为容器技术的鼻祖,Docker的历史地位无人可以质疑,虽然K8s默认已经不再与Docker绑定,但是Docker依然可以以其他形式与K8s共存。

首先因为容器镜像格式已经标准化(OCI规范,开放容器计划),Docker镜像在K8s中还是可以正常使用的,原有的开发测试、CI/CD流程不需要改变,我们仍然可以pull Docker Hub,或者写一个Dockerfile来打包应用。

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

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

再次,虽然 K8s 不再包含dockershim,但是 Docker 接管了这部分代码,并建立了一个项目叫cri-dockerdhttps://github.com/mirantis/cri-dockerd),它的工作原理也是类似的,将 Docker Engine 适配成 CRI 接口,这样kubelet就又可以通过它来操作 Docker,就好像这件事从来没有发生过一样。它在 Kubernetes 生态系统和您的工作流程中仍然发挥着作用。

整体来看,Docker 虽然在容器编排大战中落败,被 K8s 挤到了墙角,但它依然拥有强大的生命力,多年积累的众多忠实用户和大量应用镜像是它最大的资本和后盾,足以支撑它走上另一条不与 K8s 硬碰硬的道路。

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

Docker 仍然是开发和构建容器镜像以及在本地运行容器镜像的工具。Kubernetes 仍然可以运行使用 Docker 的开放容器计划 (OCI)镜像格式构建的容器,这意味着您仍然可以使用 Dockerfile 并使用 Docker 构建容器镜像。

Kubernetes 还将继续能够从 Docker 注册表(例如 Docker hub)中提取数据。这意味着 Docker 在管理构建好的镜像方面仍将是一个强大的竞争者。

总而言之,即使您不需要它在生产中在 Kubernetes 下运行容器,Docker 仍将继续成为您开发工作流程和持续集成(CI)系统中的一个有用工具。

  • 6
    点赞
  • 20
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

龙殿殿主

你的打赏是我精心创作的动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值