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 调度到容器启动的完整调用链:
上述流程中,kubelet 通过 gRPC 调用 CRI 接口,运行时内部再调用 OCI 兼容的运行时工具(如 runc)完成底层操作。关键交互细节如下:
- RunPodSandbox:kubelet 请求创建 Pod 沙箱,运行时创建隔离的 cgroup 和 namespace 环境。安全配置(如 Pod 安全策略)在此阶段生效。
- PullImage:若镜像不在本地,运行时通过 ImageService 拉取镜像。镜像签名验证和访问凭证在此步骤处理。
- CreateContainer:在沙箱内创建容器,传递 OCI 配置(包括 Seccomp 策略、Capabilities 裁剪、只读根文件系统等安全参数)。
- 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 版本和安全配置能力。