写点什么

Docker 真的被 Kubernetes 放弃了吗?

用户头像
蔡超
关注
发布于: 2021 年 01 月 13 日
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,其实看它的两句口号就行。

"Build, Ship and Run"

"Build once,Run anywhere"


关于 Kubernetes

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


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




但是这样的简单连接会带来一个问题,如果 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 标准。



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



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


传说中的 Docker 继任者

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

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



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 兼容的。


发布于: 2021 年 01 月 13 日阅读数: 92
用户头像

蔡超

关注

程序员是我的终身职业 2017.10.19 加入

蔡超,SpotMax创始人,Mobvista 集团副总裁/首席架构师,前亚马逊(中国)首席架构师,前HP(中国)软件架构师

评论

发布
暂无评论
Docker真的被Kubernetes放弃了吗?