2. CRI 核心接口定义:RuntimeService 与 ImageService 的 gRPC 服务定义、关键 RPC 方法概览

容器运行时接口(CRI)是 kubelet 与容器运行时之间的核心通信契约。CRI 基于 gRPC 协议,定义了 RuntimeService 和 ImageService 两个独立的 gRPC 服务。理解这两个服务的接口定义与关键 RPC 方法,是掌握容器运行时控制面测试验证的基础。

2.1 服务架构总览

CRI 将容器生命周期管理与镜像管理职责分离为两个独立的 gRPC 服务。RuntimeService 负责 Pod 和容器的创建、启动、停止、删除等核心操作;ImageService 则专注于镜像的拉取、列表、状态查询与删除。两者共享同一 gRPC 通道,但拥有独立的服务名和方法集。

CRI 服务架构总览:RuntimeService 与 ImageService CRI 服务架构总览 kubelet (CRI 客户端) gRPC 通道 (同一端口) RuntimeService runtime.v1.RuntimeService ImageService runtime.v1.ImageService 关键 RPC 方法 • RunPodSandbox / StopPodSandbox • CreateContainer / StartContainer • Exec / Attach / PortForward 关键 RPC 方法 • ListImages / ImageStatus • PullImage / RemoveImage • ImageFsInfo
设计原则:CRI 将镜像管理与容器生命周期管理分离,使得容器运行时可以独立升级镜像缓存策略而不影响运行中的容器。测试验证时,应分别针对两个服务构造测试用例。

2.2 RuntimeService 核心 RPC 方法

RuntimeService 是 CRI 中最为复杂的服务,定义了 20+ 个 RPC 方法。按照功能域可划分为:Pod Sandbox 管理、容器管理、流式接口 和 状态查询 四大类。

功能域 RPC 方法 请求/响应核心字段 测试关注点
Pod Sandbox 管理 RunPodSandbox config (PodSandboxConfig), runtime_handler 网络命名空间初始化、DNS 配置
StopPodSandbox pod_sandbox_id 优雅停止超时、残留资源清理
RemovePodSandbox pod_sandbox_id 幂等性、已删除沙箱重复删除
容器管理 CreateContainer pod_sandbox_id, config (ContainerConfig), sandbox_config 资源限制(CPU/Memory)、挂载卷
StartContainer container_id 启动顺序、进程状态转换
StopContainer container_id, timeout SIGTERM/SIGKILL 信号时序
RemoveContainer container_id 正在运行容器的删除行为
流式接口 Exec container_id, cmd, tty, stdin/stdout/stderr TTY 模式、多路复用流
Attach container_id, tty, stdin/stdout/stderr 重连行为、流关闭语义
PortForward pod_sandbox_id, port 端口映射、多会话并发
状态查询 Status verbose 运行时版本、网络插件状态
测试验证要点:RuntimeService 的流式接口(Exec/Attach/PortForward)使用 gRPC 双向流,测试时需要验证流控制、背压机制和连接中断后的重连行为。建议使用 gRPC 反射工具(如 grpcurl)手动验证流式 RPC 的元数据交换。

2.3 ImageService 核心 RPC 方法

ImageService 相对轻量,主要处理镜像的拉取、查询和删除。其 RPC 方法设计强调 幂等性 和 进度反馈。

RPC 方法 请求核心字段 响应核心字段 测试关注点
ListImages filter (image_regexp) repeated Image (id, repo_tags, size) 分页、过滤正则、大镜像列表性能
ImageStatus image (spec), verbose Image, info (map[string]string) 不存在的镜像返回空、verbose 元数据
PullImage image (spec), auth (AuthConfig), sandbox_config image_ref 认证失败、拉取进度、磁盘空间不足
RemoveImage image (spec) Empty 正在被使用的镜像删除、幂等性
ImageFsInfo Empty repeated FilesystemUsage (timestamp, fs_id, used_bytes) 文件系统容量统计准确性
常见陷阱:PullImage 的 sandbox_config 字段用于传递 Pod 级别的代理配置和 DNS 设置。测试时如果忽略该字段,可能导致拉取镜像时无法通过企业代理,造成测试环境与生产环境行为不一致。

2.4 gRPC 服务定义示例(Proto 片段)

以下代码片段展示了 CRI v1 版本中 RuntimeService 和 ImageService 的 gRPC 服务定义核心结构。注意两个服务定义在同一个 runtime.proto 文件中,但拥有独立的 service 关键字。

// runtime.proto (CRI v1 核心片段)
syntax = "proto3";
package runtime.v1;
option go_package = "k8s.io/cri-api/pkg/apis/runtime/v1";

// RuntimeService 定义:Pod 和容器生命周期管理
service RuntimeService {
    // Pod Sandbox 管理
    rpc RunPodSandbox(RunPodSandboxRequest) returns (RunPodSandboxResponse) {}
    rpc StopPodSandbox(StopPodSandboxRequest) returns (StopPodSandboxResponse) {}
    rpc RemovePodSandbox(RemovePodSandboxRequest) returns (RemovePodSandboxResponse) {}
    rpc PodSandboxStatus(PodSandboxStatusRequest) returns (PodSandboxStatusResponse) {}
    rpc ListPodSandbox(ListPodSandboxRequest) returns (ListPodSandboxResponse) {}

    // 容器管理
    rpc CreateContainer(CreateContainerRequest) returns (CreateContainerResponse) {}
    rpc StartContainer(StartContainerRequest) returns (StartContainerResponse) {}
    rpc StopContainer(StopContainerRequest) returns (StopContainerResponse) {}
    rpc RemoveContainer(RemoveContainerRequest) returns (RemoveContainerResponse) {}
    rpc ListContainers(ListContainersRequest) returns (ListContainersResponse) {}
    rpc ContainerStatus(ContainerStatusRequest) returns (ContainerStatusResponse) {}

    // 流式接口(双向流)
    rpc Exec(ExecRequest) returns (stream ExecResponse) {}
    rpc Attach(AttachRequest) returns (stream AttachResponse) {}
    rpc PortForward(PortForwardRequest) returns (stream PortForwardResponse) {}

    // 运行时状态
    rpc Status(StatusRequest) returns (StatusResponse) {}
    rpc Version(VersionRequest) returns (VersionResponse) {}
}

// ImageService 定义:镜像管理
service ImageService {
    rpc ListImages(ListImagesRequest) returns (ListImagesResponse) {}
    rpc ImageStatus(ImageStatusRequest) returns (ImageStatusResponse) {}
    rpc PullImage(PullImageRequest) returns (PullImageResponse) {}
    rpc RemoveImage(RemoveImageRequest) returns (RemoveImageResponse) {}
    rpc ImageFsInfo(ImageFsInfoRequest) returns (ImageFsInfoResponse) {}
}

2.5 关键 RPC 方法的通信模式对比

CRI 中的 RPC 方法采用三种不同的 gRPC 通信模式。理解这些模式对于测试验证中的 mock 构造和超时控制至关重要。

通信模式 代表方法 gRPC 流类型 测试验证难点
一元 RPC (Unary) RunPodSandbox, CreateContainer, PullImage 单请求 → 单响应 超时重试、幂等性、请求体大小限制
服务端流式 RPC Exec, Attach, PortForward 单请求 → 流式响应 流关闭信号、背压、连接中断恢复
双向流式 RPC (CRI 中较少使用,但 Exec 可视为双向流变体) 流式请求 → 流式响应 消息顺序、流同步、并发写入
CRI 中三种 gRPC 通信模式对比 CRI 中三种 gRPC 通信模式对比 一元 RPC (Unary) 客户端 → 单请求 服务端 → 单响应 例: RunPodSandbox, PullImage 服务端流式 RPC 客户端 → 单请求 服务端 → 流式响应 例: Exec, Attach 双向流式 RPC 客户端 → 流式请求 服务端 → 流式响应 例: (CRI 中较少) 测试验证提示 一元 RPC 重点测试超时和幂等性;流式 RPC 重点测试流关闭、背压和连接中断恢复。

2.6 接口版本协商与兼容性

CRI 接口通过 Version RPC 方法进行版本协商。kubelet 在启动时会调用 Version 获取运行时支持的 CRI 版本号,并选择双方都支持的最高版本进行通信。

版本协商流程:kubelet 调用 Version → 运行时返回 version(如 "0.1.0")和 runtime_name → kubelet 检查版本兼容性 → 如果不兼容,kubelet 拒绝启动并报错。测试验证时,应构造版本不匹配的场景,验证 kubelet 的错误处理逻辑。

CRI 的版本号遵循语义化版本规范:主版本号不兼容时,kubelet 拒绝连接;次版本号不同但主版本号相同时,kubelet 尝试向下兼容。当前主流容器运行时(containerd、CRI-O)均支持 CRI v1 和 v1alpha2 两个版本。