运行时插件 CRI
最后更新于
最后更新于
容器运行时插件(Container Runtime Interface,简称 CRI)是 Kubernetes v1.5 引入的容器运行时接口,它将 Kubelet 与容器运行时解耦,将原来完全面向 Pod 级别的内部接口拆分成面向 Sandbox 和 Container 的 gRPC 接口,并将镜像管理和容器管理分离到不同的服务。
CRI 最早从从 1.4 版就开始设计讨论和开发,在 v1.5 中发布第一个测试版。在 v1.6 时已经有了很多外部容器运行时,如 frakti 和 cri-o 等。v1.7 中又新增了 cri-containerd 支持用 Containerd 来管理容器。
采用 CRI 后,Kubelet 的架构如下图所示:
CRI 基于 gRPC 定义了 RuntimeService 和 ImageService 等两个 gRPC 服务,分别用于容器运行时和镜像的管理。其定义在
v1.10-v1.13: pkg/kubelet/apis/cri/runtime/v1alpha2
v1.7-v1.9: pkg/kubelet/apis/cri/v1alpha1/runtime
Kubelet 作为 CRI 的客户端,而容器运行时则需要实现 CRI 的服务端(即 gRPC server,通常称为 CRI shim)。容器运行时在启动 gRPC server 时需要监听在本地的 Unix Socket (Windows 使用 tcp 格式)。
开发新的容器运行时只需要实现 CRI 的 gRPC Server,包括 RuntimeService 和 ImageService。该 gRPC Server 需要监听在本地的 unix socket(Linux 支持 unix socket 格式,Windows 支持 tcp 格式)。
一个简单的示例为
对于 Streaming API(Exec、PortForward 和 Attach),CRI 要求容器运行时返回一个 streaming server 的 URL 以便 Kubelet 重定向 API Server 发送过来的请求。在 v1.10 及更早版本中,容器运行时必需返回一个 API Server 可直接访问的 URL(通常跟 Kubelet 使用相同的监听地址);而从 v1.11 开始,Kubelet 新增了 --redirect-container-streaming
(默认为 false),默认不再转发而是代理 Streaming 请求,这样运行时可以返回一个 localhost 的 URL(当然也不再需要配置 TLS)。
详细的实现方法可以参考 dockershim 或者 cri-o。
在启动 kubelet 时传入容器运行时监听的 Unix Socket 文件路径,比如
CRI 容器运行时 | 维护者 | 主要特性 | 容器引擎 |
Dockershim | Kubernetes | 内置实现、特性最新 | docker |
cri-o | Kubernetes | OCI标准不需要Docker | OCI(runc、kata、gVisor…) |
cri-containerd | Containerd | 基于 containerd 不需要Docker | OCI(runc、kata、gVisor…) |
Frakti | Kubernetes | 虚拟化容器 | hyperd、docker |
rktlet | Kubernetes | 支持rkt | rkt |
PouchContainer | Alibaba | 富容器 | OCI(runc、kata…) |
Virtlet | Mirantis | 虚拟机和QCOW2镜像 | Libvirt(KVM) |
目前基于 CRI 容器引擎已经比较丰富了,包括
Docker: 核心代码依然保留在 kubelet 内部(pkg/kubelet/dockershim),是最稳定和特性支持最好的运行时
OCI 容器运行时:
社区有两个实现
Containerd,支持 kubernetes v1.7+
CRI-O,支持 Kubernetes v1.6+
支持的 OCI 容器引擎包括
runc:OCI 标准容器引擎
gVisor:谷歌开源的基于用户空间内核的沙箱容器引擎
Clear Containers:Intel 开源的基于虚拟化的容器引擎
Kata Containers:基于虚拟化的容器引擎,由 Clear Containers 和 runV 合并而来
PouchContainer:阿里巴巴开源的胖容器引擎
Frakti:支持 Kubernetes v1.6+,提供基于 hypervisor 和 docker 的混合运行时,适用于运行非可信应用,如多租户和 NFV 等场景
Virtlet:Mirantis 开源的虚拟机容器引擎,直接管理 libvirt 虚拟机,镜像须是 qcow2 格式
Infranetes:直接管理 IaaS 平台虚拟机,如 GCE、AWS 等
以 Containerd 为例,在 1.0 及以前版本将 dockershim 和 docker daemon 替换为 cri-containerd + containerd,而在 1.1 版本直接将 cri-containerd 内置在 Containerd 中,简化为一个 CRI 插件。
Containerd 内置的 CRI 插件实现了 Kubelet CRI 接口中的 Image Service 和 Runtime Service,通过内部接口管理容器和镜像,并通过 CNI 插件给 Pod 配置网络。
RuntimeClass 是 v1.12 引入的新 API 对象,用来支持多容器运行时,比如
Kata Containers/gVisor + runc
Windows Process isolation + Hyper-V isolation containers
RuntimeClass 表示一个运行时对象,在使用前需要开启特性开关 RuntimeClass
,并创建 RuntimeClass CRD:
然后就可以定义 RuntimeClass 对象
而在 Pod 中定义使用哪个 RuntimeClass: