3. CRI Runtime 插件架构:kubelet 与 CRI Runtime 的通信模型与 gRPC 协议
CRI(Container Runtime Interface)是 Kubernetes 定义的一组标准 gRPC 接口,用于解耦 kubelet 与具体的容器运行时实现。理解 CRI 的通信模型与协议细节,是掌握节点扩容、运行时切换和准入控制集成的基础。
3.1 通信模型:kubelet 作为 gRPC 客户端,Runtime 作为服务端
在 CRI 架构中,kubelet 扮演 gRPC 客户端 角色,容器运行时(如 containerd、CRI-O)则作为 gRPC 服务端。两者通过本地 Unix Domain Socket(UDS)或 TCP 进行通信,默认使用 UDS 以保证低延迟和高安全性。
关键通信特征:
- 协议:gRPC over HTTP/2,支持双向流、多路复用。
- 传输层:默认 Unix Domain Socket(路径如
/run/containerd/containerd.sock)。 - 序列化:Protocol Buffers(protobuf),高效且强类型。
- 认证:无内置认证,依赖本地 Socket 文件权限控制。
3.2 gRPC 协议核心:RuntimeService 与 ImageService
CRI 协议定义了两个独立的 gRPC 服务:
| 服务名称 | gRPC 服务定义 | 核心 RPC 方法 | 用途 |
|---|---|---|---|
| RuntimeService | runtime.v1.RuntimeService |
RunPodSandbox, CreateContainer, StartContainer, StopPodSandbox, RemovePodSandbox |
Pod 沙箱与容器生命周期管理 |
| ImageService | runtime.v1.ImageService |
PullImage, ListImages, RemoveImage, ImageStatus |
容器镜像拉取与仓库管理 |
扩容场景关注点:节点扩容时,kubelet 会高频调用
RunPodSandbox 和 CreateContainer。Runtime 的响应延迟直接影响 Pod 启动速度。建议在准入控制层提前校验镜像是否存在,避免 PullImage 阻塞扩容流程。
3.3 关键 RPC 调用流程:从 Pod 创建到容器运行
当 kubelet 调度一个新 Pod 到节点时,会按以下顺序调用 CRI 接口:
- RunPodSandbox:创建 Pod 沙箱(对应一个隔离的 Linux 命名空间集合)。
- CreateContainer:在沙箱内创建容器(仅配置,不运行)。
- StartContainer:启动容器进程。
- (可选)PullImage:如果镜像本地不存在,kubelet 先调用 ImageService 拉取镜像。
3.4 CRI 接口版本演进与兼容性
CRI 协议从 v1alpha1 演进到 v1,目前主流运行时均支持 runtime.v1。kubelet 与 Runtime 之间通过版本协商确保兼容性。
| CRI 版本 | Kubernetes 版本 | 状态 | 主要变更 |
|---|---|---|---|
| v1alpha1 | v1.5 – v1.9 | 已废弃 | 初始设计,接口不稳定 |
| v1alpha2 | v1.10 – v1.23 | 已废弃 | 引入 PodSandbox 概念,接口趋于稳定 |
| v1 | v1.24+ | 当前稳定版 | 移除 alpha 接口,统一命名规范,增强错误码 |
兼容性警告:从 v1.24 开始,kubelet 移除了内置的 dockershim,所有运行时必须通过 CRI v1 接口接入。如果使用旧版运行时(如 Docker Engine 未安装 cri-dockerd),节点将无法注册到集群。扩容前务必确认运行时支持 CRI v1。
3.5 gRPC 连接管理与重试策略
kubelet 与 CRI Runtime 之间的 gRPC 连接采用长连接模式,但需要处理连接中断和超时场景:
- 连接建立:kubelet 启动时通过
--container-runtime-endpoint参数指定的 Socket 路径建立连接。 - 健康检查:kubelet 定期调用
VersionRPC 检测 Runtime 是否存活。 - 重试机制:kubelet 内部实现了指数退避重试,默认超时 4 秒,最大重试间隔 32 秒。
- 连接断开:如果 Runtime 进程重启,kubelet 会自动重连,期间 Pod 操作会暂时失败并重新入队。
扩容最佳实践:
- 将 Runtime Socket 挂载为
hostPath卷,确保 kubelet 容器(如果运行在容器中)可以访问。 - 监控
kubelet_cri_runtime_operations_duration_seconds指标,关注RunPodSandbox和CreateContainer的 P99 延迟。 - 在准入控制 Webhook 中提前校验 Runtime 版本,避免因版本不兼容导致扩容失败。