Kubernetes CRI容器运行时接口有哪些细节和特性?
摘要:kubernetes CRI分析-k8s CRI分析。kubernetes中有3个功能接口,分别是容器网络接口CNI、容器运行时接口CRI和容器存储接口CSI。本文会对CRI是什么、为什么要有CRI、CRI系统架构做介绍,对CRI所涉及的k
关联博客:kubernetes/k8s CSI分析-容器存储接口分析
kubernetes/k8s CNI分析-容器网络接口分析
概述
kubernetes的设计初衷是支持可插拔架构,从而利于扩展kubernetes的功能。在此架构思想下,kubernetes提供了3个特定功能的接口,分别是容器网络接口CNI、容器运行时接口CRI和容器存储接口CSI。kubernetes通过调用这几个接口,来完成相应的功能。
下面我们来对容器运行时接口CRI来做一下介绍与分析。
在本文中,会对CRI是什么、为什么要有CRI、CRI系统架构做一下介绍,以及k8s对CRI进行相关操作的流程分析,包括了pod创建、删除等操作。
CRI是什么
CRI是Container Runtime Interface(容器运行时接口)的简写。
CRI解耦了kubelet与容器运行时,让kubelet无需重新编译就可以支持多种容器运行时。
kubelet将通过CRI接口来跟第三方容器运行时进行通信,来操作容器与镜像。
实现了 CRI 接口的容器运行时通常称为 CRI shim, 这是一个 gRPC Server,监听在本地的 unix socket 上;而 kubelet 作为 gRPC 的客户端来调用 CRI 接口,来进行Pod 和容器、镜像的生命周期管理。另外,容器运行时需要自己负责管理容器的网络,推荐使用 CNI。
图1:CRI shim通信图
提出了CRI标准以后,意味着在新的版本里需要使用新的连接方式与docker通信,为了兼容以前的版本,k8s提供了针对docker的CRI实现,也就是kubelet包下的dockershim包,dockershim是一个grpc服务,监听一个端口供kubelet连接,dockershim收到kubelet的请求后,将其转化为REST API请求,再发送给docker daemon。
图2:dockershim通信图
为什么要有CRI
在1.5以前的版本中,k8s依赖于docker,为了支持不同的容器运行时,如rkt、containerd等,kubelet从1.5开始加入了CRI标准,它将 Kubelet 与容器运行时解耦,将原来完全面向 Pod 级别的内部接口拆分成面向 Sandbox 和 Container 的 gRPC 接口,并将镜像管理和容器管理分离到不同的服务,方便后续其他容器运行时与k8s对接。
Kubernetes中的容器运行时组成
按照不同的功能可以分为四个部分:
(1)kubelet 中容器运行时的管理,kubeGenericRuntimeManager,它管理与CRI shim通信的客户端,完成容器和镜像的管理(代码位置:pkg/kubelet/kuberuntime/kuberuntime_manager.go);
(2)容器运行时接口CRI,包括了容器运行时客户端接口与容器运行时服务端接口;
(3)CRI shim客户端,kubelet持有,用于与CRI shim服务端进行通信;
(4)CRI shim服务端,即具体的容器运行时实现,包括 kubelet 内置的 dockershim (代码位置:pkg/kubelet/dockershim)以及外部的容器运行时如 cri-containerd(用于支持容器引擎containerd)、rktlet(用于支持容器引擎rkt)等。
CRI架构图
在 CRI 之下,包括两种类型的容器运行时的实现:
(1)kubelet内置的 dockershim,实现了 Docker 容器引擎的支持以及 CNI 网络插件(包括 kubenet)的支持。dockershim代码内置于kubelet,被kubelet调用,让dockershim起独立的server来建立CRI shim,向kubelet暴露grpc server;
(2)外部的容器运行时,用来支持 rkt、containerd 等容器引擎的外部容器运行时。
kubelet中CRI相关的源码分析
kubelet的CRI源码分析包括如下几部分:
(1)kubelet CRI相关启动参数分析;
(2)kubelet CRI相关interface/struct分析;
(3)kubelet CRI初始化分析;
(4)kubelet调用CRI创建pod分析;
(5)kubelet调用CRI删除pod分析。
因篇幅原因,本篇博文先对前三部分做分析,下一篇博文再对CRI创建pod以及CRI删除pod做分析。
