为啥要解释Docker
OpenShift 4.1发布时间是2019年6月4日,记住这个时间点。
OpenShift4(后面简称OCP4)与OpenShift3很大的一个变化是:OCP3中容器运行时用的是docker(内部是runC),而OCP4使用CRI-O。如官方Blog所述:
OCP4.1推出以后,不再使用Docker信息一公布,炸锅了:
有人问为OCP4啥不用Docker;
有人问CRI-O是个啥;
有人问现有的Docker镜像还怎么在OCP4上运行。
有的友商攻击OCP4不使用Docker,不好不好。。。
虽然彼时我一遍一遍地阐述如下观点:
现有docker镜像运行在OCP4上没有问题
podman命令行与docker的体验一致,功能也覆盖。
如果docker进程出问题,pod会出问题,用了CIO-O就没这个隐患。
.........
但,还是有人不信、还是会有一些悲剧发生,据我所知某个企业不选OCP4的原因之一就是因为OCP4没使用Docker。。。。
解释Docker和CRI-O的工作可能还会继续下去......
直到最近Kubernetes 1.20 ChangeLog的出现:
https://github.com/kubernetes/kubernetes/blob/master/CHANGELOG/CHANGELOG-1.20.md
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) [SIG Node]
翻译下:kubelet中的Docker支持现已弃用,并将在以后的版本中删除。Kubelet使用一个名为“ dockershim”的模块,该模块实现了对Docker的CRI支持,并且在Kubernetes社区中看到了维护问题。我们鼓励您评估向容器运行时的迁移,该运行时是CRI(v1alpha1或v1兼容)的完整实现。(#94624,@ dims)[SIG节点]
上面描述提到的CRI是一种标准,CRI-O是CRI的标准实现。那么,CRI-O 是什么时候出现的呢?
请看红帽2019年4月的官方blog。
没错,红帽在2019年就针对CRI接口进行了接口实现,做出了CRI-O。
看到K8S ChangeLog这段描述后,我想,我以后终于不用再解释为何OCP4不用Docker用CRI-O了,因为K8S不建议用Docker建议用CRI。虽然OCP4不用Docker的这个Action,比K8S不建议用Docker的这个Suggestion,早了一年半。或许,这就叫做技术的vision吧。
长出一口气。
=============================================
接下来,把之前发过的关于容器发展史的文章的部分内容再应景发一遍(因为很多信关注公众号的朋友没看到),这个文章是去年8月1日发的。已经读过的朋友请忽略。
- 最早的容器格运行时是lxc
- Docker最早让容器火起来,docker最开始用lxc,觉得隔离性差,开发libcontainer,最终形成runc。所以说,runc是docker的独生子。
- K8S时,发现市面上docker挺火,因此就用docker。
- docker越做越重,CoreOS做了rkt容器格式。rkt与K8S协同工作比较好。
- 容器运行时格式有点多了,linux基金会主导的开源项目说:我们要做一个container runtime标准。叫OCI。以后容器运行时要符合这个标准。docker的独生子runc在第一时间符合了OCI标准。
- K8S为了与容器运行时解耦(主要是docker),提出了CRI(Container Runtime Interface)标准。它是一组与K8S与container runtime进行交互的接口。所以说,CRI和OCI并不冲突:K8S定义的是它调用容器运行时的标准接口,OCI定义的是容器运行时本身的标准。
- OCI关于容器运行时的标准提出来以后,红帽想可以专门为K8S做一个轻量级的容器运行时。红帽自然会考虑到它自己全力投入的K8S发布的CRI标准(K8S红帽代码贡献第二),因此决定重用了runc等基本组件来启动容器, 并实现了一个最小的 CRI 接口。它叫CRI-O。所以说,CRI-O是CRI的一种标准实现。
- 当Red Hat正在开发其CRI-O,Docker也在研究CRI标准,这导致创建了另一个名为containerd的运行时(实际上是从docker engine剥离出来的)。所以新版本的docker会多一层containerd。kubernetes将containerd接入到cri的标准中。即cri-containerd。
![e2776a765eda1539ca8ee9d2e7d2b5d7.png](https://i-blog.csdnimg.cn/blog_migrate/bd4eb4db19001e68af0b7548d9e4dc6f.png)
![0db19426fac069f3ce53d897586cab55.png](https://i-blog.csdnimg.cn/blog_migrate/478df2394889eb9d170e181f087bc723.png)
Orchestration API ->ContainerEngine API ->Kernel API
现有pass平台的调用架构(OpenShift3的模式,调用了docker):
KubernetesMaster->Kubelet->DockerEngine-> containerd -> runc -> Linux Kernel
红帽的主张是(OpenShift4的模式):
KubernetesMaster->Kubelet-> CRI-O -> runc ->Linux kernel
有一些开发者想用如下的模式:
KubernetesMaster->Kubelet->CRI-containerd->containerd -> runc ->Linux kernel
结论:
- lxc容器运行时基本下课了。runc容器运行时受到大佬们的青睐
- docker engine将下课基本也是事实,这事儿谷歌和红帽联手干的。但docker急中生智,最终containerd 也被K8S社区采纳了。
- rkt与K8S协同工作不错,但与OCI的认证还没测试完。
- 红帽OpenShift目前在全球企业容器市场的占有率将近1/3。Containerd能否火起来,后面也得看K8S社区的态度。
知识点
主流的容器运行时有:- lxc是Linux上老牌的容器runtime。Docker最初也是用lxc作为runtime的。LXC 容器目前还不能同 kubernetes 进行整合,也没有实现对 OCI 标准的支持
- runc是Docker自己开发的runtime。目前Docker的默认runtime。符合oci规范。
- rkt是CoreOS开发的容器runtime。它与K8S对接很好。目前正在和OCI认证中(面向 CRI(容器运行时接口)的 rklet 仍在开发中)。
- lxd是lxc对应的管理工具。
- runc的管理工具是Docker engine,包括后台deamon和cli两部分,我们通常提到的Docker一般就是指docker engine。
- rkt的管理工具是rkt cli。
故事
Docker是第一个推广容器的厂商。最初,Docker使用LXC,但其隔离层不完整,因此Docker编写了libcontainer,最终成为runc。随后,Docker成为部署容器的事实标准。在它2014年问世时,Kubernetes自然地使用了Docker,因为Docker是当时唯一可用的运行时。但Docker是一家雄心勃勃的公司,一直致力于开发新功能。例如,Docker Compose与Kubernetes同时达到1.0,两个项目之间存在一些重叠。虽然有很多方法可以使用诸如Kompose之类的工具来使两个工具互操作,但Docker通常被视为一个做太多事情的大项目。这种情况导致CoreOS以rkt的形式发布了一个更简单的独立运行时,这是通过这种方式解释的:rkt的一个创新是通过appc规范标准化镜像格式。rkt的Kubernetes兼容层(rktlet) ),没有通过所有Kubernetes集成测试,仍在开发中。 CRI-O: 看到这些新标准,红帽认为应该创建一个更简单的运行时,只能做Kubernetes所需要的。那个“skunkworks”项目最终被称为CRI-O并实现了一个最小的CRI接口。 Red Hat负责其OpenShift平台的2016年底启动,该项目也得益于英特尔和SUSE的支持,红帽主持CRI-O开发人员Mrunal Patel主持了此次演讲。CRI-O与CRI(运行时)规范以及OCI和Docker镜像格式兼容。 CRI-O重用了runc等基本组件来启动容器,以及为skopeo项目创建的容器/图像和容器/存储等软件库,以提取容器图像和创建容器文件系统。一个名为oci-runtime-tool的独立库准备容器配置。 containerd:Docker的运行时获取API 当Red Hat正在开发其OCI的实现时,Docker也在研究该标准,这导致创建了另一个名为containerd的运行时。新守护进程是对内部Docker组件的重构,以组合OCI特定的位,如执行,存储和网络接口管理。它已经在1.12 Docker版本中有所体现。虽然我们将containerd称为“运行时”,但它并不直接实现CRI接口,该接口由另一个名为cri-containerd的守护进程覆盖。所以容器需要比Kubernetes的CRI-O更多的守护进程(5个,而CRI-O为三个)。kubernetes将containerd接入到cri的标准中。![967feb2600a35fe7bf5cda81d617e9e2.png](https://i-blog.csdnimg.cn/blog_migrate/973cb7bb417004f27031604f56d60462.png)
RHEL8中的podman和runc
目前,OCI支持runc。用podman进行管理。 Podman曾经是CRI-O项目中的一部分,后来被分离出成为一个独立项目,libpod.Podman(Pod Manager)的目标是提供一个跟Docker相似体验的容器CLI,提供给使用者创立和运行容器。 podman不需要守护程序,利用用户命名空间模拟容器中的 root,所以 Podman 不需要接入具有 root 权限的 socket![af75bff1a114cc335f0a420989c6a015.png](https://i-blog.csdnimg.cn/blog_migrate/2c0f362cf7b20843a24c82e6748118aa.jpeg)
- buildah实现的是dockerfile的脚本化执行。
- podman对标的是docker命令的代替。
![9e21208fb6befb0f0b1152ce809afe79.png](https://i-blog.csdnimg.cn/blog_migrate/5224d347e0cde41e5d137f7198e48f02.png)
![da309df19b00ac3222c1b0a50899c13f.png](https://i-blog.csdnimg.cn/blog_migrate/ae9af6cacc9921b45ffc0197103141ae.png)
![95f06433e5a48023b54979ffae50ed11.png](https://i-blog.csdnimg.cn/blog_migrate/356d189640ed0e07a252b3a6207e0132.png)
![c949063f4e29a5f0946ca18a1bdaa4d4.png](https://i-blog.csdnimg.cn/blog_migrate/670c9ad2aebca1607050ad3eacdf73ac.png)
![4274399dfc7b92d2fc438b2057f8ff7d.png](https://i-blog.csdnimg.cn/blog_migrate/facad4bd152a571b8be497b1445d8b86.jpeg)
![9e56b2a786126bf35c6430d8747e5bb2.png](https://i-blog.csdnimg.cn/blog_migrate/febb968402a70183482a5ca475c52268.png)