2. CRI 核心接口定义:RuntimeService 与 ImageService 的 gRPC 服务定义、关键 RPC 方法概览
容器运行时接口(CRI)是 kubelet 与容器运行时之间的核心通信契约。CRI 基于 gRPC 协议,定义了 RuntimeService 和 ImageService 两个独立的 gRPC 服务。理解这两个服务的接口定义与关键 RPC 方法,是掌握容器运行时控制面测试验证的基础。
2.1 服务架构总览
CRI 将容器生命周期管理与镜像管理职责分离为两个独立的 gRPC 服务。RuntimeService 负责 Pod 和容器的创建、启动、停止、删除等核心操作;ImageService 则专注于镜像的拉取、列表、状态查询与删除。两者共享同一 gRPC 通道,但拥有独立的服务名和方法集。
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 | 运行时版本、网络插件状态 |
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 可视为双向流变体) | 流式请求 → 流式响应 | 消息顺序、流同步、并发写入 |
2.6 接口版本协商与兼容性
CRI 接口通过 Version RPC 方法进行版本协商。kubelet 在启动时会调用 Version 获取运行时支持的 CRI 版本号,并选择双方都支持的最高版本进行通信。
Version → 运行时返回 version(如 "0.1.0")和 runtime_name → kubelet 检查版本兼容性 → 如果不兼容,kubelet 拒绝启动并报错。测试验证时,应构造版本不匹配的场景,验证 kubelet 的错误处理逻辑。
CRI 的版本号遵循语义化版本规范:主版本号不兼容时,kubelet 拒绝连接;次版本号不同但主版本号相同时,kubelet 尝试向下兼容。当前主流容器运行时(containerd、CRI-O)均支持 CRI v1 和 v1alpha2 两个版本。