CRI概述
容器运行时(Container Runtime):顾名思义就是容器从拉取镜像到启动运行再到中止的整个生命周期。 其中最知名的就是Docker了,除此之外市面上还有containerd,rkt等。
(类似于Web服务除了nginx还有apache...)
每个容器运行时都有特点,因此不少用户希望Kubernetes能够支持更多的容器运行时。为了更具扩展性,kubernetes引入了容器运行时插件API,即 Container Runtime Interface,简称CRI。
CRI中定义了容器和镜像的服务的接口。因为容器运行时 与镜像的生命周期是彼此隔离的,因此需要定义两个服务。该接口使用Protocol Buffer, 基于gRPC. 这两种服务定义在 kubernetes/staging/src/k8s.io/cri-api/pkg/apis/runtime/v1alpha2/api.proto 中
Protocol Buffers API(一种更高效的类似json的数据格式)包含两个gRPC服务:
ImageService和RuntimeService。
ImageService提供了从仓库拉取镜像、查看和移除镜像的功能。
RuntimeService负责Pod和容器的生命周期管理,以及与容器的交互 (exec/attach/port-forward)。
rkt和Docker这样的容器运行时可以使用一 个Socket同时提供两个服务,在kubelet中可以用--container-runtime- endpoint和--image-service-endpoint参数设置这个Socket。
Docker的CRI实现, 在Kubernetes 1.6中被更新为Beta版本,并在kubelet启动时默认启动。
可替代的容器运行时支持在Kubernetes中的概念并非首次。在Kubernetes 1.3发布时,rktnetes项目同时发布,让rkt容器引擎成为除Docker外的又一选择。
不管是Docker还是rkt,都需要通过内部、不太稳定的接口直接集成到kubelet的源码中,同kubelet源码纠缠不清。
这种程度的集成需要对kubelet的内部机制有非常深入的了解,还会给社区带来维护管理压力,这就给新生代容器运行时造成了难于跨越的集成壁垒。
CRI的主要组件
CRI包含一组Protocol Buffers、gRPC API、运行库支持! 及开发中的标准规范和工具。CRI目前是v1alpha2版本.
Container Runtime实现了CRI gRPC Server,包括RuntimeService 和ImageService。
该gRPC Server需要监听本地的Unix socket,而kubelet则作为gRPC Client运行。
Kubelet与容器运行时通信(或者是CRI插件填充了容器运行时)时,Kubelet就像是客户端,而CRI插件就像对应的服务器。如图所示。(kubelet组件的主要功能:启动和停止容器。)
kubelet使用 gRPC框架(google 远程过程调用) 通过UNIX Socket与容器运行时(或CRI代 理)进行通信。
名词解释:RPC
注解:一种通过网络从远程计算机程序上请求服务,而不需要了解底层网络技术的协议
CRI在Kubelet与docker之间实现了CRI shim中间层。
1:CRI shim的gRPC server监听unix:///var/run/dockershim.sock,kubelet的gRPC client连接这个socket。
2: kubelet与CRI shim的数据传输使用gRPC、而数据格式采用protobuf。
3:CRI shim使用engine-api建立一个连接unix:///var/run/docker.sock的client,通过docker API控制容器生命周期以及镜像管理。
Pod和容器的生命周期管理
podsandbox:共有环境
Pod由一组应用容器组成,其中包含共有的环境和资源约束。在CRI里,这个环境被称为PodSandbox。
PodSandbox就是Pod的这个环境, 也就是说Pod这个抽象概念的表现就是PodSandbox<共有环境>、应用容器和一些资源约束.
Kubernetes有意为容器运行时 留下一些发挥空间,它们可以根据自己的内部实现来生成不同的PodSandbox:
1:对于基于Hypervisor的运行时,PodSandbox会具体化为一个虚拟机!!!。
2: 其他例如Docker,会是一个Linux命名空间!!!。
kubelet创建cgroup: 资源保障
在v1alpha1版API中,kubelet会创建Pod级别的cgroup 传递给容器运行时,并以此运行所有进程 来满足PodSandbox对Pod的资源保障。
生命周期:
在启动Pod之前,kubelet调用RuntimeService.RunPodSandbox来创建环境。这一过程包括为Pod设置网络资源(分配IP等操作, 涉及CNI)。
PodSandbox被激活之后,就可以独立地创建、启动、停止和删除不同的容器了。
kubelet会在停止和删除PodSandbox之前首先停止和删除其中的容器。
kubelet的职责在于通过RPC!!! 管理容器的生命周期,实现容器生命周期的钩子,存活和健康监测,以及执行Pod的重启策略等。