Docker真的被Kubernetes放弃了吗?

引子

随着Kubernetes 1.20的发布,关于“kubernetes不再支持Docker!Docker不能用了!以前的Docker镜像不能用了!”等声音不绝于耳,事实真的是这样吗?

 

“ Docker support in the kubelet is now deprecated and will be removed in a future release. 

The kubelet uses a module called "dockershim" which implements CRI support for Docker and it has seen maintenance issues in the Kubernetes community. We encourage you to evaluate moving to a container runtime that is a full-fledged implementation of CRI (v1alpha1 or v1 compliant) as they become available. (#94624, @dims)  ”

 

深入细节

要了解事情的真相,就要深入其细节。那就让我们来看看于此相关的细节吧。

关于容器

容器 = cgroup + namespace + rootfs + 容器运行时

  • cgroup:资源控制

  • namespace:访问隔离

  • rootfs:文件系统隔离。镜像的本质就是一个rootfs文件

  • 容器运行时:生命周期控制

cgroup

 cgroup 是 control group 的简称,是 Linux 内核提供的一个特性,用于限制和隔离一组进程对系统资源的使用,如:CPU,内存的使用等。

 

Namespace

Namespace 是将内核的全局资源做封装,使得每个namespace 都有一份独立的资源,因此不同的进程在各自的namespace内对同一种资源的使用互不干扰,例如,hostname,进程ID和用户组等在各个namespace里都是独立的。

 

关于Docker

其实与很多人的认识不同,Docker本身并不是容器,它是创建容器的工具,是容器运行时。想要搞懂Docker,其实看它的两句口号就行。

"Build, Ship and Run"

"Build once,Run anywhere"

 

关于Kubernetes

Kubernetes是一个容器编排平台,用于容器应用的自动化发布,伸缩和管理。

图片

那么Kubernetes是如何实现容器管理的呢?

Docker真的被Kubernetes放弃了吗?_第1张图片

如我们所知container/pod是运行在node上的,kubernetes在每一个node上都有一个kubelet用于管理node的container/pod。所以,最直观的想法就是kubelet直接调用一个容器运行时(container runtime),如Docker去创建和管理node上的container。

Docker真的被Kubernetes放弃了吗?_第2张图片

但是这样的简单连接会带来一个问题,如果Kubernetes要去支持更多不同的容器运行时实现, 就要为不同容器运行时开发不同的kubelet去适配。为了解决这个扩展性问题,Kubernetes 1.5里引入了CRI(Container Runtime Interface)。CRI定义了kubelet支持的容器运行时的标准接口(一组gRPC调用),这样就变成了容器运行时要通过支持CRI来主动适配Kubernetes。

 

另一方面,Docker也在发生着改变,为了避免容器的生态分裂为“小生态王国”,确保一个引擎上构建的容器可以运行在其他引擎之上,2015年由多家公司共同成立的项目OCI (Open Container Initiative),并由linux基金会进行管理,致力于容器运行时标准的制定。

Docker从原有的libcontainer中演化出了支持OCI的runC。容器运行时管理也从Docker Daemon中抽离出来,放到了一个叫containerd的进程中,containerd是一系列容器操作的facade,并最终通过runC来完成容器的操作。由此最终kubernetes和docker的关系变成了下面这样。内置在kubelet中Docker shim是为了让Docker Daemon适配CRI标准。

Docker真的被Kubernetes放弃了吗?_第3张图片

从上图大家发现Containrd已经是一个容器运行时了,那么Docker Daeamon显得冗余,这样Kubernetes就可以进行1.20版本中提到的简化。

Docker真的被Kubernetes放弃了吗?_第4张图片

这样的结构将变得更加简化且合理,containerd的适配也通过在其中增加CRI-plugin来实现了,这样containerd就变成了一个支持CRI的容器运行时了。

 

传说中的Docker继任者

在一片Docker被放弃了的呼声中,大家听到最多还有CRI-O和Podman,他们似乎是Docker的继任者。

首先,我们来看看CRI-O,由上面的内容可以知道其实,和kubernetes协同工作并支持现有的标准容器,就需要一个容器运行时能够桥接CRI和OCI,那么整个架构就可以大大简化,Redhat推出的CRI-O就是这样情况定制的容器运行时。

Docker真的被Kubernetes放弃了吗?_第5张图片

 

Podman是Redhat公司推出的容器管理工具(CRI-O并没有提供创建镜像,推送镜像至镜像库等功能),Podman起初是CRI-O的一部分,后来单独分离出来叫做libpod,使用Podman的命令几乎和docker类似,事实上podman可以说兼容了docker的CLI,您甚至通过alias docker=podman来简单的替换Docker。

 

结论

Docker并没有被抛弃,未来kubernetes实际要去除的是对现有Docker运行时(Docker Daemon)的支持,通过去除了kubelet中Docker Shim来实现。这是kubernetes的一种标准化和简化,同时,应该注意到Docker实际在这些相关标准的制定中一直以来起着非常重要的作用。并且Docker给出的相关参考实现,如containerd,runC将继续被使用。

  1. Docker运行时1.20中只是deprecated而不是removed,即Docker运行时可以正常使用。

  2. 即使在1.22版本kubelet移除docker shim后,docker 镜像还是可以使用的(docker镜像是符合OCI的)

  3. 这个影响主要是运维和管理,对于开发的影响极小。即使要替换为podman,podman也是docker cli兼容的。

(更多技术分享,请关注公众号“蔡超谈软件”)

 

你可能感兴趣的:(云原生,Docker,Kubernetes)