K8s、Docker、Containerd、CRI之间到底是什么关系

a84dcbc3d31f407bb8fff034e90cf569.gif

0

前言

容器化、kubernetes、云计算等等技术应用已经越来越广泛,我们经常会听到诸如 kubernetes 弃用 docker、containerd、libcontainer、runc、OCI 等等,本文就此做一下梳理。

1

docker发展史

Docker 可以将应用程序及其依赖打包成一个容器镜像,这个镜像就可以在几乎任何服务器上运行。是 docker 把容器技术推向了巅峰。

从 docker 1.11 版本开始,docker 容器运行就不是简单通过 docker daemon 来启动了,而是通过集成 containerd、runc 等多个组件来完成的。下面是 docker 的架构视图。

69d3858b80b52e7c5f712b2b795b1817.png

当我们使用 docker 创建一个容器的时候,docker daemon 作为客户端去请求 containerd 来创建一个容器。containerd 收到请求后,也并不会直接去操作容器,而是创建一个 containerd-shim 进程,让这个进程去操作容器、作为容器的父进程来进行状态收集、维持 stdin 等 fd 打开等工作。引入 containerd 和 containerd-shim的目的,都是防止 dockerd、containerd 挂掉,导致整个宿主机上所有的容器退出的问题。

我们知道创建容器需要做一些 namespaces 和 cgroups 的配置,以及挂载容器的文件系统等操作,这些操作都是有标准规范的,那就是 OCI(开放容器标准)。这个标准主要规定了容器镜像的结构、以及容器需要接收哪些操作指令,比如 create、start、stop、delete 等。runc 就是按照这个 OCI 文档的一个实现,根据标准创建一个符合规范的容器(docker 将 libcontainer 捐献并改名为 runc)。

所以真正启动容器是通过 containerd-shim 去调用 runc 来启动容器的,runc 启动完容器后本身会直接退出,containerd-shim 则会成为容器进程的父进程, 负责收集容器进程的状态, 上报给 containerd, 并在容器中 pid 为 1 的进程退出后接管容器中的子进程进行清理, 确保不会出现僵尸进程。

2

Kubernetes 与容器

CRI(Container Runtime Interface 容器运行时接口)是 Kubernetes 定义的一组与容器运行时进行交互的接口,所以只要实现了这套接口的容器运行时都可以对接到 Kubernetes 平台上来。由于 docker 没有实现 CRI 接口,于是就有了 shim(垫片), 一个 shim 的职责就是作为适配器将各种容器运行时本身的接口适配到 Kubernetes 的 CRI 接口上,dockershim 就是 Kubernetes 对接 docker 到 CRI 接口上的一个垫片实现,是内置在 kubelet 代码中的。

当我们在 Kubernetes 中创建一个 Pod 的时候,首先就是 kubelet 通过 CRI 接口调用 dockershim,请求创建一个容器,dockershim 收到请求后, 转化成 docker daemon 能识别的请求, 发到 docker daemon 上请求创建一个容器,后续就是 docker 去调用 containerd,然后创建 containerd-shim 进程,通过该进程去调用 runc 去创建容器。

23bce44646e3d50a8e40dc857361af8f.png

不难发现使用 docker 的调用链比较长,真正容器相关的操作其实 containerd 就完全足够了,但是由于 docker 深受用户欢迎,所以 kubernetes 从最开始采用了 dockershim 的方案。但是对于 Kubernetes 来说并不需要 docker 的功能,因为都是通过接口去操作容器的,所以自然也就可以将容器运行时切换到 containerd 来,而 containerd 在1.1版本也内置了 CRI 插件,kubernetes 直接使用 containerd 的调用链也更加简洁。这就是 kubernetes 弃用 docker 的原因,并不是说 kubernetes 要弃用容器,而是简化操作容器的链路。kubernetes 1.24版本从kubelet 中删除了 dockershim 的代码。

然而,还是会有一些影响。如果 kubernetes 直接使用 containerd 来操作容器,那么它就是一个独立于 docker 的工作环境,两者都无法访问对方管理的容器和镜像。换句话说,使用 docker ps 命令将不会看到 kubernetes 中运行的容器。但是 kubectl 命令不受影响。

参考: https: //blog.csdn.net/easylife206/article/details/119745457

点个赞

9c2bd983e0e0858ae6c6d6c7ff4e370c.gif

再走吧

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值