同理去理解CRI
在k8s刚出来的时候,除了docker之外并没有几个runtime(运行时,就是管理容器的东西),所以呢在k8s里就内置了代码来适配docker,如下图。
后来除了docker之外又有了其他的runtime,比如rkt。然后呢在kubernetes代码里也内置了代码来适配rkt。
后来又有了越来越多的runtime,比如cri-o、containerd等,他们也想集成到kubernetes里让kubernetes以他们作为runtime。
这样一来,kubernetes发现,这样不行啊,这样没完没了的,我这代码太臃肿了不好维护。干脆我就开发一个叫做CRI(容器运行时接口)的标准,并对这些运行时说:“你们也别都想着让把你们整合到我的代码里了,我这开发了一个接口叫做CRI,你们这些runtime只要符合CRI标准就能连接到我了。当然了,如果你们不符合CRI标准的话,你们自己就弄一个转接口转接一下就行了。这个转接口就称之为shim(垫片)吧”。
然后呢有些runtime就开发了符合CRI标准的转接线就是一个shim,叫做CRI-shim。当然有些runtime本身就符合CRI接口了,那么这个runtime就是CRI-shim。
但是呢docker说,我没有CRI接口也开发不出来符合CRI接口的shim。那咋办呢?没办法,因为docker太强大了,所以kubernetes(其实是kubelet)里仍然内置了连接docker的代码叫做(dockershim)。
除了dockershim是内置的,其他的shim一律称之为remote。所以在使用除docker之外的runtime,kubelet都会有一个选项叫做KUBELET_EXTRA_ARGS=–container-runtime=remote。
又过了几年,这时kubernetes已经足够强大了,而且也有了很多其他runtime可选,也不是非docker不可了,所以他必须要一视同仁,所以呢从kubernetes 1.24版本里就把dockershim从kubernetes(其实是kubelet)的代码中移除了。
这下完了,docker不能再作为kubernetes的runtime了。如果要非想让docker作为kubernetes的runtime的话,那么就必须要找一个符合CRI标准的转接口了,这个就是cri-docker,他是一个符合CRI标准的shim(转接口),他可以作为一个转接口连接kubernetes和docker。
1.1 什么是runc
要理解runc,我们需要了解容器标准OCI(Open Container Initiative)可以理解为容器运行标准,是由多个组织共同成立,主要是维护runc的标准协议和相关的开发工作。所谓的runc主要是负责容器生命周期的管理,以及对容器状态的描述。runc的实现标准主要是根据OCI相关的规范来实现容器生命周期的管理,也是所有容器运行的基础功能。runc容器可以说实现了cgroup/linux kernel相关的隔离抽象接口。自从docker项目改为moby以后,docker按OCI标准抽出runc的项目,docker根据containerd直接调用了runc的api。总结,runc抽象出来的一个容器运行标准的api,主要是容器生命周期管理的一个项目。
1.2 runc与docker,k8s
- runc for docker docker主要在docker engine上实现了对runc的调用,通过docker的contanerd来对runc api相关的调用操作。runc主要是containerd底层的实现逻辑。如图:
- runc for k8s k8s我们其实可以理解为一个强档的调度系统,可以实现灵活的容器调度。在k8s初期的版本中,是可以实现对docker的兼容方式,k8s通过docker engine的api直接调用来实现容器的周期管理。但是在k8s 1.5+版本之后,k8s实现了自己的CRI(containcer runtime interface),实现CRI之后一个非常大的好处就是对容器的调度实现了自主管理,这样很多时候久不依赖docker engine的api接口了,同k8s引入了pod的概念,pod是k8s运行的基础单元,对于k8s pod解析可以放到后面。 docker调用runc主要是通过contained来实现对容器的周期管理,k8s同时也实现了CRI的containerd,然后CRI contanerd调用docker的containerd。如图:
当然我们可以发现市场上还有很多容器方案,比如阿里的pouch实现的容器方案,也是给予runc来实现。
综上,基于runc标准实现,给我们容器镜像的迁移兼容变得非常简单。
1.3 runc 实现解析
runc实现了容器的init,run,create,ps...我们在运行容器所需要的cmd。runc的项目可以分为2个部分,第一个就是底层隔离,网络等实现,这个主要在libcontainer中实现,这一层主要是对操作系统调用的封装,还有就是对docker文件系统的实现。第二层就是提供基础容器cmd调用,比如提到的create,ps等cmd. 基本runc主要是这2块功能,其实只要有这2大块功能,其实就可以自己实现对container生命周期管理了。以下我将解析几个cmd来说明怎么调用的libcontainer。
当然了,这也不能说docker不行了,docker仍然是非常有用的,比如构建镜像、搭建仓库等。
————————————————
版权声明:本文为CSDN博主「老段工作室」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/lduan_001/article/details/125301335