“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)”
随着 Kubernetes 1.20 的公布,对于“kubernetes 不再反对 Docker!Docker 不能用了!以前的 Docker 镜像不能用了!”等声音不绝于耳,事实真的是这样吗?
本文作者:蔡超
Mobvista 团体副总裁兼首席架构师
深刻细节
要理解事件的假相,就要深刻其细节。那就让咱们来看看于此相干的细节吧。
1. 对于容器
容器 = cgroup + namespace + rootfs + 容器运行时
cgroup:资源管制
cgroup 是 control group 的简称,是 Linux 内核提供的一个个性,用于限度和隔离一组过程对系统资源的应用,如:CPU,内存的应用等。
namespace:拜访隔离
Namespace 是将内核的全局资源做封装,使得每个 namespace 都有一份独立的资源,因而不同的过程在各自的 namespace 内对同一种资源的应用互不烦扰,例如,hostname,过程 ID 和用户组等在各个 namespace 里都是独立的。
rootfs:文件系统隔离。镜像的实质就是一个 rootfs 文件
容器运行时:生命周期管制
2. 对于 Docker
其实与很多人的意识不同,Docker 自身并不是容器,它是创立容器的工具,是容器运行时。想要搞懂 Docker,其实看它的两句口号就行。
“Build, Ship and Run”
“Build once,Run anywhere”
3. 对于 Kubernetes
Kubernetes 是一个容器编排平台,用于容器利用的自动化公布,伸缩和治理。
那么 Kubernetes 是如何实现容器治理的呢?
如咱们所知 container/pod 是运行在 node 上的,kubernetes 在每一个 node 上都有一个 kubelet 用于治理 node 的 container/pod。所以,最直观的想法就是 kubelet 间接调用一个容器运行时(container runtime),如 Docker 去创立和治理 node 上的 container。
然而这样的简略连贯会带来一个问题,如果 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 将持续被应用。
Docker 运行时 1.20 中只是 deprecated 而不是 removed,即 Docker 运行时能够失常应用。
即便在 1.22 版本 kubelet 移除 docker shim 后,docker 镜像还是能够应用的(docker 镜像是合乎 OCI 的)
这个影响次要是运维和治理,对于开发的影响极小。即便要替换为 podman,podman 也是 docker cli 兼容的。