Containerd的前世今生

作者:Breeze

Containerd简介

containerd 是一个工业级标准的容器运行时,它强调简单性健壮性可移植性。其诞生于Docker,提供如下功能:

  • 管理容器的生命周期(从创建容器到销毁容器)

  • 拉取/推送容器镜像

  • 存储管理(管理镜像及容器数据的存储)

  • 调用 runc 运行容器(与 runc 等容器运行时交互)

  • 管理容器网络接口及网络

containerd架构图如下:
在这里插入图片描述

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-0JJ54gyf-1632639765783)(https://secure.wostatic.cn/static/pQpT3ynVJVSafhqypKGJXb/image.png)]

Containerd的发展史

Docker

说到Containerd,就必然绕不开Docker。Docker作为一个完整的容器引擎,其包含三个部分: 计算、存储、网络。在早期的时候,这些功能统一由docker daemon进程提供;但从docker 1.11版本开始,这些功功能开始做拆分:

  • 计算:由containerd提供

  • 存储:由docker-volume提供

  • 网络:由docker-network提供

其中计算部分的架构如下:
在这里插入图片描述
当创建容器的请求到达docker api,docker-api会调用containerd执行创建操作,此时containerd会启动一个containerd-shim进程,containerd-shim调用runc执行容器的创建操作。当容器创建完成之后, runc退出,containerd-shim作为容器的父进程收集容器的运行状态,将其上报给containerd,并在容器中 pid 为 1 的进程退出后接管容器中的子进程进行清理, 确保不会出现僵尸进程。

在这里插入图片描述

runc是OCI的一个具体实现。 OCI(open container initivtive)全称为开放容器标准,其主要用于规范容器镜像的结构以及容器需要接收的操作指令,如create、start、stop、delete等命令。除了runc之外,Kata、gVisor也符合OCI规范。

为什么containerd不直接调用runc,而要启动一个containerd-shim调用runc?因为容器进程是需要一个父进程来做状态收集、维持 stdin 等 fd 打开等工作的,假如这个父进程就是 containerd,那如果 containerd 挂掉的话,整个宿主机上所有的容器都会退出。引入containerd-shim则可解决这个问题

所以事实上在早期containerd一直只是作为docker创建容器的子组件而存在。

CRI

在kubernetes早期的时候,由于没法跟docker正面刚,只得通过硬编码的方式在kubelet当中直接调用Docker API创建容器。

在这里插入图片描述

随着容器生态的逐渐发展,市面上出现了更多的容器运行时。 此时kubernetes为了支持更多的容器运行时,Google就和红帽主导了CRI标准,用于将kubernetes平台和特定的容器运行时解耦。

CRI(Container Runtime Interface 容器运行时接口)本质上就是 Kubernetes 定义的一组与容器运行时进行交互的接口,所以只要实现了这套接口的容器运行时都可以对接Kubernetes 。不过 Kubernetes 推出 CRI 这套标准的时候还没有现在的统治地位,所以有一些容器运行时自身没有实现 CRI 接口,于是就有了 shim(垫片), 一个 shim 的职责就是作为适配器将各种容器运行时本身的接口适配到 Kubernetes 的 CRI 接口上,其中 dockershim 就是 Kubernetes 对接 Docker 到 CRI 接口上的一个垫片实现。

Kubelet 通过 gRPC 框架与容器运行时或 shim 进行通信,其中 kubelet 作为客户端,CRI shim(也可能是容器运行时本身)作为服务器。
在这里插入图片描述

由于当时的Docker仍然处于容器生态的统治地位。kubernetes不得不在kubelet当中内置了dockershim:

在这里插入图片描述

再后来,Docker在容器生态大战中败北。在2017年的时候,Docker公司将其容器运行时Containerd捐献给了CNCF。为了将containerd接入到CRI标准中,k8s又搞出了cri-containerd项目,cri-containerd是一个守护进程用来实现kubelet和containerd之间的交互,此时k8s节点上kubelet启动容器就变成了下面这个样子:

在这里插入图片描述

再往后,在Containerd 1.1时,将cri-containerd改成了Containerd的CRI插件,CRI插件位于containerd内部,这让k8s启动Pod时的通信更加高效:
在这里插入图片描述

与此同时 Kubernetes 社区也做了一个专门用于 Kubernetes 的 CRI 运行时 CRI-O,直接兼容 CRI 和 OCI 规范:
在这里插入图片描述

无论是CRI-O还是containerd接入kubernetes的方式都比docker使用dockershim的方式接入kubernetes要来的简单。

在2020年12月份,kubernetes宣布将在1.22版本当中正式从kubelet当中移除docker-shim代码。也就是说,如果docker仍然不支持CRI,则kubernetes将会放弃对docker的支持。而在2021年8月,kubernetes正式发布了1.22版本。

在可预见的未来,Docker最终将走下历史的舞台。而取而代之的,恰是docker自己开发的containerd。

更多资料添加东方瑞通客服老师领取,或者关注我们在B站上的视频动态。
下期直播,我们将会介绍从实践操作掌握K8S架构核心,时间是10月19日晚。敬请期待。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值