1. CRI 概述:CRI 的起源、设计目标与架构位置
1.1 起源:从 Docker 依赖到接口解耦
在 Kubernetes 早期版本(v1.5 之前),kubelet 直接通过硬编码调用 Docker API 来管理容器生命周期。这种紧耦合设计带来了三个核心问题:
- 供应商锁定:社区无法替换容器运行时,所有创新都必须围绕 Docker 生态展开。
- 版本依赖:kubelet 与 Docker 的 API 版本必须严格对齐,升级风险高。
- 扩展困难:rkt、containerd、CRI-O 等新兴运行时无法直接接入 Kubernetes。
2016 年,Kubernetes 社区正式提出 CRI(Container Runtime Interface) 规范,将 kubelet 与容器运行时之间的交互抽象为一组 gRPC 接口。这一设计使得 Kubernetes 不再依赖任何特定运行时,任何实现了 CRI 接口的运行时都可以无缝接入集群。
关键里程碑:Kubernetes v1.5 引入 CRI 作为 alpha 特性,v1.6 进入 beta,v1.10 正式 GA。Docker 通过 dockershim 适配器兼容 CRI,直到 v1.24 正式移除 dockershim。
1.2 设计目标:标准化、可插拔、高性能
CRI 的设计围绕三个核心目标展开,下表总结了每个目标对应的关键设计决策:
| 设计目标 | 具体含义 | 关键设计决策 |
|---|---|---|
| 标准化 | 定义统一的容器操作接口,屏蔽运行时差异 | 使用 protobuf 定义 gRPC 服务,版本化接口(v1alpha1 → v1) |
| 可插拔 | 运行时可以独立开发、部署、升级 | kubelet 通过 Unix Socket 与运行时通信,运行时作为独立进程运行 |
| 高性能 | 最小化 kubelet 与运行时之间的调用开销 | 流式 gRPC(exec/attach/port-forward)、批量操作(PodSandbox) |
1.3 在 Kubernetes 架构中的位置
CRI 位于 kubelet 与容器运行时之间,是 Kubernetes 节点代理层的关键抽象边界。下图展示了 CRI 在完整架构中的位置:
1.4 CRI 的核心接口定义
CRI 定义了两个主要的 gRPC 服务:RuntimeService 和 ImageService。下表列出了每个服务的关键 RPC 方法:
| 服务名称 | 关键 RPC 方法 | 功能描述 |
|---|---|---|
| RuntimeService | RunPodSandbox |
创建 Pod 级别的沙箱环境(如 Linux Namespace、Cgroup) |
CreateContainer |
在指定 PodSandbox 中创建容器 | |
StartContainer |
启动已创建的容器 | |
ExecSync |
在容器内同步执行命令并返回结果 | |
| ImageService | PullImage |
拉取容器镜像到本地存储 |
ListImages |
列出本地已存储的镜像列表 | |
RemoveImage |
删除本地存储的指定镜像 |
1.5 CRI 的通信模型
CRI 采用 客户端-服务器 通信模型,kubelet 作为客户端,容器运行时作为服务器。通信细节如下:
- 传输协议:gRPC over Unix Domain Socket(默认路径
/run/containerd/containerd.sock或/var/run/crio/crio.sock) - 序列化格式:Protocol Buffers(protobuf),保证高效二进制序列化
- 认证方式:基于文件系统权限的 Unix Socket 权限控制,无额外认证
- 超时控制:kubelet 为每个 RPC 调用设置超时(默认 2 分钟),防止运行时挂死
测试要点:CRI 接口测试需要关注 gRPC 连接建立、请求/响应序列化、超时重试、以及 Socket 文件权限等边界条件。后续章节将深入每个接口的测试设计。
1.6 CRI 的版本演进
CRI 接口经历了从 v1alpha1 到 v1 的演进,当前稳定版本为 v1。下表总结了主要版本的变化:
| 版本 | Kubernetes 版本 | 主要变化 |
|---|---|---|
| v1alpha1 | v1.5 - v1.9 | 初始设计,包含 PodSandbox、Container 基本操作 |
| v1alpha2 | v1.10 - v1.22 | 引入 PodSandboxStats、ContainerStats 等监控接口 |
| v1 | v1.23+ | 稳定版本,移除 alpha 特性,接口冻结 |
当前所有主流容器运行时(containerd v1.6+、CRI-O v1.23+)均已支持 CRI v1 接口,不再支持 v1alpha2 版本。