1. CRI 接口概述
CRI(Container Runtime Interface,容器运行时接口)是 Kubernetes 中 kubelet 与容器运行时之间的标准协议层。它定义了 kubelet 如何管理容器生命周期、拉取镜像、传递 Pod 沙箱配置,以及获取运行时指标。在集群升级场景中,CRI 的兼容性与资源协商能力直接影响升级窗口的稳定性和节点容量利用率。
1.1 CRI 在 Kubernetes 架构中的位置
CRI 位于 kubelet 与容器运行时之间,是 kubelet 内部的一个插件式 gRPC 接口。kubelet 通过 CRI 调用 RuntimeService 和 ImageService 两个 gRPC 服务,而不直接依赖 Docker、containerd 或 CRI-O 的具体实现。
架构要点:CRI 使 kubelet 与运行时解耦,升级运行时无需修改 kubelet 代码,只需保证 CRI 版本兼容。
1.2 CRI 的核心定义与接口划分
CRI 定义了两个 gRPC 服务,每个服务包含若干 RPC 方法。kubelet 通过 Unix Socket(默认路径 /var/run/crio/crio.sock 或 /run/containerd/containerd.sock)与运行时通信。
| gRPC 服务 | 主要 RPC 方法 | 功能说明 |
|---|---|---|
| RuntimeService | RunPodSandbox、StopPodSandbox、CreateContainer、StartContainer、StopContainer、RemoveContainer、ContainerStatus、ListContainers |
管理 Pod 沙箱和容器生命周期,包括创建、启动、停止、删除和状态查询 |
| ImageService | PullImage、ListImages、ImageStatus、RemoveImage、ImageFsInfo |
管理容器镜像的拉取、列表、状态查询、删除和文件系统信息 |
升级关注点:在集群升级前,务必确认目标 kubelet 版本与运行时支持的 CRI API 版本是否匹配。kubelet 1.24+ 已移除内置 dockershim,必须使用支持 CRI 的运行时(containerd ≥1.6 或 CRI-O ≥1.24)。
1.3 kubelet 与 CRI 的交互模型
kubelet 与 CRI 的交互遵循同步请求-响应模式,所有调用均通过 gRPC 双向流或一元 RPC 完成。核心交互流程如下:
- Pod 创建阶段:kubelet 调用
RunPodSandbox创建 Pod 沙箱(网络命名空间、cgroup 父目录),然后依次调用CreateContainer和StartContainer启动业务容器。 - 健康检查与状态同步:kubelet 定期调用
ContainerStatus和ListContainers获取运行时状态,用于 Pod 状态更新和就绪探针判断。 - 资源统计:kubelet 通过
ContainerStatsRPC(CRI v1alpha2 起)获取容器 CPU、内存、磁盘等资源使用数据,用于 HPA 和节点压力驱逐。 - 镜像管理:kubelet 在创建容器前调用
PullImage确保镜像存在,并通过ImageFsInfo监控镜像存储占用。
1.4 CRI 版本演进与升级兼容性
CRI 接口本身也经历版本迭代。kubelet 与运行时之间通过 Version RPC 协商兼容的 API 版本。下表列出关键版本节点:
| Kubernetes 版本 | CRI API 版本 | 运行时兼容性要求 |
|---|---|---|
| v1.20 – v1.23 | v1alpha2 | containerd ≥1.4、CRI-O ≥1.20、Docker + dockershim |
| v1.24 – v1.25 | v1alpha2(移除 dockershim) | containerd ≥1.6、CRI-O ≥1.24 |
| v1.26+ | v1(GA,v1alpha2 弃用) | containerd ≥1.7、CRI-O ≥1.26 |
升级风险提示:如果集群从 v1.23 直接升级到 v1.26+,运行时必须同时升级以支持 CRI v1 API。否则 kubelet 将无法与运行时建立连接,导致节点 NotReady。建议在升级前使用
crictl version 和 kubelet --version 验证版本兼容性。
1.5 容量规划视角下的 CRI 关键指标
在集群升级场景中,CRI 接口的以下指标直接影响容量规划和资源分配策略:
- Pod 沙箱创建延迟:
RunPodSandbox的 P99 延迟,决定升级时 Pod 迁移的启动速度。 - 镜像拉取吞吐量:
PullImage的并发能力和带宽限制,影响节点上线时间。 - ContainerStatus 轮询开销:大规模集群中,频繁的
ContainerStatus调用可能成为 kubelet 性能瓶颈。 - ImageFsInfo 磁盘占用:升级前需评估镜像存储空间,避免磁盘压力导致 Pod 驱逐。
最佳实践:在升级窗口前,使用
crictl stats 和 crictl imagefsinfo 采集当前节点运行时负载基线,用于计算升级期间的资源预留量。