CRI
# CRI
## Container Runtime Interface
容器运行时(Container Runtime),运行于Kubernetes (K8s)集群的每个节点中,负责容器的整
个生命周期。其中Docker是目前应用最广的。随着容器云的发展,越来越多的容器运行时涌现。
为了解决这些容器运行时和Kubernetes的集成问题,在Kubernetes 1. .5版本中,社区推出了CRI(Container Runtime Interface,容器运行时接口)以支持更多的容器运行时。

CRI是Kubernetes定义的一组gRPC服务。kubelet 作为客户端,基于gRPC框架,通过Socket和容器运行时通信。
它包括两类服务:镜像服务(Image Service)和运行时服务(Runtime Service)。镜像服务提供下载、检查和删除镜像的远程程序调用。运行时服务包含用于管理容器生命周期,以及与容器交互的调用(exec / attach / port-forward)的远程程序调用。

## 运行时的层级
Dockershim, containerd 和CRI-O都是遵循CRI的容器运行时,我们称他们为高层级运行时(High-level Runtime)。
OCI (Open Container Initiative,开放容器计划)定义了创建容器的格式和运行时的开源行业标准,包括镜像规范(Image Specification)和运行时规范(Runtime Specification)。
镜像规范定义了OCI镜像的标准。高层级运行时将会下载一个OCI镜像,并把它解压成OCI运行时文件系统包(filesystem bundle)。
运行时规范则描述了如何从OCI运行时文件系统包运行容器程序,并且定义它的配置、运行环境和生命周期。如何为新容器设置命名空间(namepsaces) 和控制组(cgroups) ,以及挂载根文件系统等等操作,都是在这里定义的。它的一个参考实现是runC。我们称其为低层级运行时(Low-level Runtime)。除runC以外,也有很多其他的运行时遵循OCI标准,例如kata-runtime。
## CRI
容器运行时是真正起删和管理容器的组件。
容器运行时可以分为高层和低层的运行时。
高层运行时主要包括Docker, containerd 和CRI-O,低层的运行时,包含了runc, kata,以及gVisor。
低层运行时kata和gVisor都还处于小规模落地或者实验阶段,其生态成熟度和使用案例都比较欠缺,所以除非有特殊的需求,否则runc几乎是必然的选择。因此在对容器运行时的选择上,主要是聚焦于上层运行时的选择。
Docker内部关于容器运行时功能的核心组件是containerd,后来containerd也可直接和kubelet通过CRI对接,独立在Kubernetes中使用。
相对于Docker而言,containerd 减少了Docker 所需的处理模块Dockerd和Docker-shim,并且对Docker支持的存储驱动进行了优化,因此在容器的创建启动停止和删除,以及对镜像的拉取上,都具有性能上的优势。
架构的简化同时也带来了维护的便利。当然Docker也具有很多containerd不具有的功能,例如支持zfs存储驱动,支持对日志的大小和文件限制,在以overlayfs2做存储驱动的情况下,可以通过xfs_quota来对容器的可写层进行大小限制等。
尽管如此,containerd目前也基本上能够满足容器的众多管理需求,所以将它作为运行时的也越来越多。


## 开源运行时的比较
Docker的多层封装和调用,导致其在可维护性.上略逊一筹,增加了线上问题的定位难度;几乎除了重启Docker,我们就毫无他法了。
containerd和CRI-O的方案比起Docker简洁很多。

### Docker 和Containerd的差异细节

### 多种运行时性能比较
containerd在各个方面都表现良好,除了启动容器这项。从总用时来看,containerd 的用时还是要比CRI-O要短的。

### 运行时劣势对比
功能性来讲,containerd 和CRI-O都符合CRI和OCI的标准;
在稳定性上,containerd 略胜一筹;
从性能上讲,containerd 胜出。
