2. CRI 接口基础:OCI 运行时规范、CRI 接口定义、CRI 与 kubelet 的交互流程

容器运行时接口(CRI,Container Runtime Interface)是 Kubernetes 与容器运行时之间的核心抽象层。理解 CRI 的前提是掌握其底层依赖的 OCI 规范,以及 kubelet 如何通过 CRI 与运行时交互完成 Pod 生命周期管理。本节从规范、接口定义、交互流程三个层次展开。

2.1 OCI 运行时规范

开放容器倡议(OCI,Open Container Initiative)定义了容器运行时的行业标准,包含两个核心规范:

规范名称 作用 关键内容
OCI 镜像规范 定义容器镜像的文件系统布局与元数据格式 镜像层(Layer)、配置(Config)、清单(Manifest)
OCI 运行时规范 定义容器运行时的生命周期操作与状态模型 创建、启动、停止、删除容器;状态查询;挂载点配置

所有符合 CRI 的容器运行时(如 containerd、CRI-O)底层都必须实现 OCI 运行时规范。这意味着 kubelet 通过 CRI 发出的指令,最终会转化为对 OCI 运行时(如 runc)的调用。

安全要点: OCI 运行时规范中的 Seccomp、AppArmor、Capabilities 等安全配置字段,是 CRI 安全配置方案在节点扩容时必须传递到运行时的关键参数。若 CRI 层未正确透传这些字段,容器将失去安全隔离能力。

2.2 CRI 接口定义

CRI 是 Kubernetes 在 kubelet 与容器运行时之间定义的 gRPC 协议接口,包含两个主要服务:

  • RuntimeService:管理 Pod 和容器的生命周期(创建、启动、停止、删除)。
  • ImageService:管理容器镜像的拉取、列表、删除和状态检查。

以下为 CRI 接口的核心 RPC 方法清单:

服务 RPC 方法 功能描述
RuntimeService RunPodSandbox 创建 Pod 沙箱(通常对应一个隔离的命名空间环境)
StopPodSandbox 停止并清理 Pod 沙箱
CreateContainer 在 Pod 沙箱内创建容器
StartContainer 启动已创建的容器
ContainerStatus 查询容器当前状态与元数据
ImageService PullImage 拉取容器镜像到本地存储
ListImages 列出本地已存储的镜像列表
RemoveImage 删除本地存储中的指定镜像
设计意图: CRI 将 Pod 抽象为 PodSandbox,而非直接管理容器。这种设计使得运行时可以灵活选择隔离技术(如 VM-based 运行时 Kata Containers 使用轻量级虚拟机作为 Sandbox),同时保持 kubelet 侧的接口统一。

2.3 CRI 与 kubelet 的交互流程

当 kubelet 接收到 API Server 下发的 Pod 创建请求时,其与 CRI 运行时的交互遵循严格的时序流程。下图展示了从 Pod 调度到容器启动的完整调用链:

CRI 与 kubelet 交互流程(Pod 创建) kubelet CRI gRPC 接口 容器运行时 1. RunPodSandbox gRPC 请求 创建 Pod 沙箱 OCI 调用 runc 创建沙箱 2. PullImage 拉取镜像 镜像存储 3. CreateContainer 配置容器 OCI 容器创建 4. StartContainer 启动容器 容器进程运行

上述流程中,kubelet 通过 gRPC 调用 CRI 接口,运行时内部再调用 OCI 兼容的运行时工具(如 runc)完成底层操作。关键交互细节如下:

  1. RunPodSandbox:kubelet 请求创建 Pod 沙箱,运行时创建隔离的 cgroup 和 namespace 环境。安全配置(如 Pod 安全策略)在此阶段生效。
  2. PullImage:若镜像不在本地,运行时通过 ImageService 拉取镜像。镜像签名验证和访问凭证在此步骤处理。
  3. CreateContainer:在沙箱内创建容器,传递 OCI 配置(包括 Seccomp 策略、Capabilities 裁剪、只读根文件系统等安全参数)。
  4. StartContainer:启动容器进程,运行时将容器 PID 返回给 kubelet 用于健康检查。
安全风险提示: 在节点扩容场景中,若新节点上的 CRI 运行时版本与 kubelet 版本不匹配,可能导致 RunPodSandbox 或 CreateContainer 调用失败,或安全配置字段被静默忽略。建议在扩容前使用 crictl 工具验证 CRI 接口的版本兼容性。

2.4 CRI 接口版本与安全配置传递

CRI 接口采用 版本协商机制:kubelet 在启动时会通过 Version RPC 获取运行时支持的 CRI 版本列表,并选择双方都支持的最高版本。安全配置的传递依赖于 CRI 版本中定义的字段:

CRI 版本 安全相关字段 说明
v1alpha2 SecurityContext、LinuxContainerConfig 支持 Capabilities、Seccomp(字符串路径)、SELinux
v1 SecurityContext、LinuxContainerConfig、WindowsContainerConfig 新增 Seccomp 结构化配置(Profile 对象)、AppArmor 支持
最佳实践: 在集群节点扩容时,应确保所有节点使用相同的 CRI 运行时版本,并在 kubelet 配置中显式指定 --container-runtime-endpoint 和 --container-runtime 参数。使用 crictl info 命令可快速检查运行时支持的 CRI 版本和安全配置能力。