Menu

CRI(Container Runtime Interface)为 Kubernetes 提供了标准化的容器运行时抽象层,支持多种运行时后端,极大提升了平台的灵活性和可扩展性。

总览

容器运行时接口(CRI)是一个插件接口,使 kubelet 能够在无需重新编译 Kubernetes 组件的情况下,支持多种容器运行时。CRI 由 Protocol Buffer 定义和 gRPC API 组成,规定了 Kubernetes 与容器运行时实现之间的契约。

CRI 不是通用的容器运行时 API,它专为 kubelet 与运行时通信以及节点级故障排查工具(如 crictl)设计。API 设计以 Kubernetes 为中心,可能包含 kubelet 所需的调用顺序或参数假设。

CRI 解决的问题

在 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 ```

CRI 作为抽象层 {width=1920 height=506}

抽象层允许运行时实现独立演进,同时为 kubelet 保持稳定接口。

CRI 服务架构

CRI 定义了两个主要的 gRPC 服务,各自职责如下:

RuntimeService

RuntimeService 管理 Pod 沙箱和容器的完整生命周期。Pod 沙箱是 Kubernetes Pod 的运行时表示,提供容器共享的环境(如网络、IPC 等)。

ImageService

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 ```

CRI 的两大服务及其操作 {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 ```

gRPC 与 Protocol Buffers 在 CRI 中的作用 {width=1920 height=1473}

关键概念

Pod 沙箱

Pod 沙箱是 Kubernetes Pod 的运行时表示,提供容器共享的执行环境,包括:

RunPodSandbox RPC 创建并启动 Pod 沙箱,确保其就绪后才能在其中创建容器。

容器生命周期

容器在 Pod 沙箱内创建,生命周期如下:

  1. 创建CreateContainer 在沙箱内分配容器资源
  2. 启动StartContainer 启动容器
  3. 停止StopContainer 优雅停止容器(带超时)
  4. 删除RemoveContainer 删除容器并释放资源

所有生命周期操作均为幂等,例如对已停止容器调用 StopContainer 也会返回成功。

版本协商

CRI 通过 Version RPC 支持版本协商,返回:

kubelet 可据此校验与运行时的兼容性。

预期应用场景

CRI 专为以下两类场景设计:

1. kubelet 集成

CRI 的主要消费者是 kubelet,使用该 API 实现:

kubelet 期望特定的调用模式,并可能根据操作顺序优化。

2. 节点级故障排查

crictl 命令行工具通过 CRI 实现节点级调试与排查:

CRI 不适用于

主流 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

总结

CRI 核心要点总结

方面 详情
目的 kubelet 插件接口,支持多种容器运行时
技术 Protocol Buffers v3 + gRPC
服务 RuntimeService(40+ 方法)、ImageService(5 方法)
消费者 kubelet、crictl
实现者 containerd、CRI-O 及其他容器运行时
设计理念 以 Kubernetes 为中心,非通用接口
定义位置 api.proto

CRI 让 Kubernetes 生态支持多样化容器运行时实现,同时为 kubelet 保持稳定接口。这一架构决策使容器运行时技术能独立于 Kubernetes 编排逻辑持续演进。

参考文献


Menu