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 文件权限控制。
kubelet ↔ CRI Runtime 通信架构 kubelet gRPC 客户端 Pod 生命周期管理 gRPC / HTTP/2 protobuf 序列化 Unix Domain Socket CRI Runtime gRPC 服务端 containerd / CRI-O 通信模型要点 • kubelet 主动发起所有 gRPC 调用,Runtime 被动响应。 • 每个节点上 kubelet 与本地 Runtime 进程一一对应。 • 扩容时 kubelet 通过 CRI 创建 Sandbox(Pod 沙箱)和 Container。

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 接口:

  1. RunPodSandbox:创建 Pod 沙箱(对应一个隔离的 Linux 命名空间集合)。
  2. CreateContainer:在沙箱内创建容器(仅配置,不运行)。
  3. StartContainer:启动容器进程。
  4. (可选)PullImage:如果镜像本地不存在,kubelet 先调用 ImageService 拉取镜像。
Pod 创建 CRI 调用时序 kubelet CRI Runtime 容器进程 1. RunPodSandbox 创建沙箱 命名空间 2. CreateContainer 配置容器 3. StartContainer 启动进程 容器进程 扩容性能关键路径 • RunPodSandbox 耗时取决于网络插件(CNI)配置和内核命名空间创建速度。 • CreateContainer 涉及 OCI 配置生成和存储层挂载,是 IO 密集型操作。 • 准入控制可在 CreateContainer 前拦截并校验资源配额、安全策略。

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 定期调用 Version RPC 检测 Runtime 是否存活。
  • 重试机制:kubelet 内部实现了指数退避重试,默认超时 4 秒,最大重试间隔 32 秒。
  • 连接断开:如果 Runtime 进程重启,kubelet 会自动重连,期间 Pod 操作会暂时失败并重新入队。
扩容最佳实践:
  • 将 Runtime Socket 挂载为 hostPath 卷,确保 kubelet 容器(如果运行在容器中)可以访问。
  • 监控 kubelet_cri_runtime_operations_duration_seconds 指标,关注 RunPodSandbox 和 CreateContainer 的 P99 延迟。
  • 在准入控制 Webhook 中提前校验 Runtime 版本,避免因版本不兼容导致扩容失败。