在Kubernetes 1.20版本中不推荐使用Docker !

原创 阿良 DevOps技术栈 12月3日

一直在关注Kubernetes动态,眼看着1.20 版本要发布了,抱着好奇的心理去Github看看这个版本更新了啥?结果在弃用位置发现了一个焦点,说要“弃用对Docker支持”,如下:
在Kubernetes 1.20版本中不推荐使用Docker !_Java  翻译:
在Kubernetes 1.20版本中不推荐使用Docker !_Java_02
感觉很诧异,官方为什么会这么做呢?
先从Docker聊起,Docker 1.11开始,Docker容器运行已经不是简单的通过Docker daemon来启动,而是将Docker Daemon被拆分了多个模块,如图所示:

在Kubernetes 1.20版本中不推荐使用Docker !_Java_03


组件介绍:

  • docker:命令行管理工具

  • dockerd:Docker守护进程,负责与docker client交互;

  • containerd:负责镜像管理和容器管理的守护进程,containerd是一个标准的容器运行时,可以独立管理容器生命周期,也就是即使不运行dockerd,容器也能正常工作;
  • containerd-shim:是一个真实运行的容器的载体,每启动一个容器都会起一个新的shim的一个进程;
  • runC:一个命令行工具,根据OCI标准来创建和运行容器。


当我们执行docker run创建一个容器时,大致流程:1、docker工具向dockerd守护进程发送创建容器请求;2、dockerd收到请求后再向containerd请求创建一个容器;3、containerd收到请求后并不会直接创建容器,而让-shim创建容器;4、docker-shim又调用runC创建容器(准备容器所需的namespace和cgroups就退出了),docker-shim就作为了该容器进程的父进程,负责收集容器状态并上报给containerd。
在Kubernetes平台中,为了解决与容器运行时(例如Docker)集成问题,在早期社区推出了CRI(Container Runtime Interface,容器运行时接口),以支持更多的容器运行时,当我们使用Docker作为容器运行时之后,架构是这样的,如图所示:

在Kubernetes 1.20版本中不推荐使用Docker !_Java_04


可以看出,调用链还是很复杂的,多层封装和调用,导致性能降低、提升故障率、不易排查,我想这也是弃用对Docker支持的主要原因吧!
除了docker之外,CRI还支持很多容器运行时,例如:

  • cri-containerd

  • cri-o

  • rktlet

  • frakti

  • ...


如果把容器运行时换成containerd,如图所示:

在Kubernetes 1.20版本中不推荐使用Docker !_Java_05


可见,Containerd 调用链更短,组件更少,占用节点资源也比较少。
Docker作为目前最主流的容器引擎,经过5年的快速发展,在企业中得到广泛应用,并且已经非常成熟了,如果想迁移别的容器运行时还需要一定时间验证!

你怎么看?欢迎留言讨论。
参考:

  • https://github.com/kubernetes/kubernetes/blob/master/CHANGELOG/CHANGELOG-1.20.md

  • https://github.com/kubernetes/kubernetes/pull/94624