CRI(Container Runtime Interface)为 Kubernetes 提供了标准化的容器运行时抽象层,支持多种运行时后端,极大提升了平台的灵活性和可扩展性。
容器运行时接口(CRI)是一个插件接口,使 kubelet 能够在无需重新编译 Kubernetes 组件的情况下,支持多种容器运行时。CRI 由 Protocol Buffer 定义和 gRPC API 组成,规定了 Kubernetes 与容器运行时实现之间的契约。
CRI 不是通用的容器运行时 API,它专为 kubelet 与运行时通信以及节点级故障排查工具(如 crictl)设计。API 设计以 Kubernetes 为中心,可能包含 kubelet 所需的调用顺序或参数假设。
在 CRI 出现之前,集成新的容器运行时需要修改和重新编译 kubelet 代码。这种紧耦合导致:
CRI 引入了抽象层,将编排(kubelet)与容器生命周期管理(运行时实现)分离。
下图展示了 CRI 作为抽象层的演进过程:
```mermaid “CRI 作为抽象层”
graph TB
subgraph “CRI 之前”
KB1[“Kubelet
(含运行时代码)”]
KB1 –>|”紧耦合”| RT1[“容器运行时”]
end
subgraph "有了 CRI"
KB2["Kubelet<br/>(运行时无关)"]
CRI["CRI API<br/>Protocol Buffer 定义<br/>gRPC 接口"]
RT2A["containerd"]
RT2B["CRI-O"]
RT2C["其他运行时"]
KB2 -->|"gRPC 调用"| CRI
CRI -->|"由实现"| RT2A
CRI -->|"由实现"| RT2B
CRI -->|"由实现"| RT2C
end ```
{width=1920 height=506}
抽象层允许运行时实现独立演进,同时为 kubelet 保持稳定接口。
CRI 定义了两个主要的 gRPC 服务,各自职责如下:
RuntimeService 管理 Pod 沙箱和容器的完整生命周期。Pod 沙箱是 Kubernetes Pod 的运行时表示,提供容器共享的环境(如网络、IPC 等)。
ImageService 独立处理所有镜像相关操作,允许运行时分别使用不同后端存储镜像和运行容器。
下图展示了 CRI 的两大服务及其主要操作:
```mermaid “CRI 的两大服务及其操作” graph TB CRI[“容器运行时接口”]
subgraph RS["RuntimeService"]
direction TB
PS["Pod 沙箱操作<br/>RunPodSandbox<br/>StopPodSandbox<br/>RemovePodSandbox<br/>PodSandboxStatus<br/>ListPodSandbox<br/>UpdatePodSandboxResources"]
CT["容器操作<br/>CreateContainer<br/>StartContainer<br/>StopContainer<br/>RemoveContainer<br/>ContainerStatus<br/>ListContainers<br/>UpdateContainerResources"]
EX["执行操作<br/>ExecSync<br/>Exec<br/>Attach<br/>PortForward<br/>ReopenContainerLog<br/>CheckpointContainer"]
OBS["可观测性<br/>ContainerStats<br/>ListContainerStats<br/>PodSandboxStats<br/>ListPodSandboxStats<br/>GetContainerEvents<br/>ListMetricDescriptors<br/>ListPodSandboxMetrics"]
CFG["配置<br/>Version<br/>Status<br/>RuntimeConfig<br/>UpdateRuntimeConfig"]
end
subgraph IS["ImageService"]
IMG["镜像操作<br/>ListImages<br/>ImageStatus<br/>PullImage<br/>RemoveImage<br/>ImageFsInfo"]
end
CRI --> RS
CRI --> IS
PS -.->|"容器运行于其中"| CT ```
{width=1920 height=962}
RuntimeService 与 ImageService 的分离为运行时管理镜像和容器提供了灵活性。
CRI 基于两项核心技术:
下图展示了 gRPC 与 Protocol Buffers 在 CRI 中的作用和调用关系:
```mermaid “gRPC 与 Protocol Buffers 在 CRI 中的作用” graph BT subgraph “消费者” KUBELET(“kubelet”) CRICTL(“crictl CLI”) end
subgraph "CRI API 层"
GRPC_DEF("gRPC 服务定义<br/>RuntimeService<br/>ImageService")
PB_MSG("Protocol Buffer 消息<br/>PodSandboxConfig<br/>ContainerConfig<br/>ContainerStatus<br/>...")
end
subgraph "运行时实现"
CONTAINERD("containerd CRI 插件")
CRIO("CRI-O")
OTHER("其他运行时")
end
KUBELET -->|"gRPC 客户端调用"| GRPC_DEF
CRICTL -->|"gRPC 客户端调用"| GRPC_DEF
GRPC_DEF -->|"序列化使用"| PB_MSG
GRPC_DEF -->|"由实现"| CONTAINERD
GRPC_DEF -->|"由实现"| CRIO
GRPC_DEF -->|"由实现"| OTHER ```
{width=1920 height=1473}
Pod 沙箱是 Kubernetes Pod 的运行时表示,提供容器共享的执行环境,包括:
RunPodSandbox RPC 创建并启动 Pod 沙箱,确保其就绪后才能在其中创建容器。
容器在 Pod 沙箱内创建,生命周期如下:
CreateContainer 在沙箱内分配容器资源StartContainer 启动容器StopContainer 优雅停止容器(带超时)RemoveContainer 删除容器并释放资源所有生命周期操作均为幂等,例如对已停止容器调用 StopContainer 也会返回成功。
CRI 通过 Version RPC 支持版本协商,返回:
version:CRI API 版本(如 “v1”)runtime_name:容器运行时名称(如 “containerd”)runtime_version:运行时实现版本runtime_api_version:运行时支持的 CRI API 版本kubelet 可据此校验与运行时的兼容性。
CRI 专为以下两类场景设计:
CRI 的主要消费者是 kubelet,使用该 API 实现:
kubelet 期望特定的调用模式,并可能根据操作顺序优化。
crictl 命令行工具通过 CRI 实现节点级调试与排查:
CRI 不适用于:
| 运行时 | 维护者 | 特点 | 使用场景 |
|---|---|---|---|
| containerd | CNCF | 轻量级、高性能、生产就绪 | 云原生环境、生产部署 |
| CRI-O | Red Hat/CNCF | 专为 Kubernetes 设计、OCI 兼容 | OpenShift、企业环境 |
虽然以下运行时不直接实现 CRI 接口,但通过适配器可以与 Kubernetes 集成:
以下示例展示了如何通过 RuntimeClass 集成 Kata Containers 等安全增强型运行时:
# 通过 RuntimeClass 使用不同的容器运行时
apiVersion: node.k8s.io/v1
kind: RuntimeClass
metadata:
name: kata-containers
handler: kata
---
apiVersion: v1
kind: Pod
metadata:
name: secure-pod
spec:
runtimeClassName: kata-containers
containers:
- name: app
image: nginx
在日常运维和故障排查中,建议结合 crictl 工具对容器运行时进行监控和诊断。常见操作包括:
以下为常用 crictl 命令示例:
# 查看 CRI 运行时状态
crictl info
# 列出容器
crictl ps
# 查看容器日志
crictl logs <container-id>
# 执行容器命令
crictl exec -it <container-id> /bin/bash
| 方面 | 详情 |
|---|---|
| 目的 | kubelet 插件接口,支持多种容器运行时 |
| 技术 | Protocol Buffers v3 + gRPC |
| 服务 | RuntimeService(40+ 方法)、ImageService(5 方法) |
| 消费者 | kubelet、crictl |
| 实现者 | containerd、CRI-O 及其他容器运行时 |
| 设计理念 | 以 Kubernetes 为中心,非通用接口 |
| 定义位置 | api.proto |
CRI 让 Kubernetes 生态支持多样化容器运行时实现,同时为 kubelet 保持稳定接口。这一架构决策使容器运行时技术能独立于 Kubernetes 编排逻辑持续演进。