当前位置: 首页 > web >正文

Kubernetes控制平面组件:Kubelet详解(三):CRI 容器运行时接口层

云原生学习路线导航页(持续更新中)

  • kubernetes学习系列快捷链接
    • Kubernetes架构原则和对象设计(一)
    • Kubernetes架构原则和对象设计(二)
    • Kubernetes架构原则和对象设计(三)
    • Kubernetes控制平面组件:etcd(一)
    • Kubernetes控制平面组件:etcd(二)
    • Kubernetes控制平面组件:API Server详解(一)
    • Kubernetes控制平面组件:API Server详解(二)
    • Kubernetes控制平面组件:调度器Scheduler(一)
    • Kubernetes控制平面组件:调度器Scheduler(二)
    • Kubernetes控制平面组件:Controller Manager详解
    • Kubernetes控制平面组件:Controller Manager 之 内置Controller详解
    • Kubernetes控制平面组件:Controller Manager 之 NamespaceController 全方位讲解
    • Kubernetes控制平面组件:Kubelet详解(一):API接口层介绍
    • Kubernetes控制平面组件:Kubelet详解(二):核心功能层

本文是 kubernetes 的控制面组件 kubelet 系列文章第三篇,主要讲解了CRI容器运行时接口相关内容,包括CRI是什么、核心功能、高级/低级运行时、如何选择运行时、cai-api/cri-client源码目录梳理等

  • 希望大家多多 点赞 关注 评论 收藏,作者会更有动力继续编写技术文章
  • 在前面两节中,我们已经对 kubelet 做了简要介绍,给出了kubelet架构,并对API接口层、核心功能层 做了介绍,本文将对 kubelet 的 CRI 容器运行时接口层 做详细讲解

在这里插入图片描述

  • API 接口层
    • kubelet API
    • cAdvisor API
    • 只读API
    • 健康检查 API
  • 核心功能层,可分为3个模块:
    • 核心管理模块:PLEG、cAdvisor、GPUManager、OOMWatcher、ProbeManager、DiskSpaceManager、EvictionManager
    • 运行时协调模块:syncLoop、PodWorker
    • 容器生命周期管理模块:StatusManager、VolumeManager、ImageGC、ContainerGC、ImageManager、CertificateManager
  • CRI 接口层
    • 容器执行引擎接口,作为grpc client 与真正的容器运行时(Dockershim/rkt/containerd)交互

1.容器运行时(CR)是什么

1.1.CRI 简介

在这里插入图片描述

  • CRI 是 Kubernetes 中用于与容器运行时(如 Docker、containerd、CRI-O 等)交互的接口标准。
  • CRI位于 kubelet 与 container 之间,它抽象了 Kubernetes 对容器生命周期的管理操作,允许 Kubernetes 支持多种容器运行时,而无需修改核心代码。
  • 发展历史
    • 在早期 Kubernetes 中,直接依赖 Docker 的 API(通过 dockershim),导致与 Docker 强耦合,难以支持其他容器运行时。
    • 为了解决这一问题,Kubernetes 在 1.5 版本 引入了 CRI,将容器运行时与 Kubernetes 核心组件解耦。

1.2.CRI 的核心功能

在这里插入图片描述

  • 如上图,kubelet会启动一个grpc-client,CRI的具体实现会启动一个grpc-server,二者通过protobuf协议传输数据,CRI的具体实现会通过调用oci runtime,实现对容器的操作

1.3.运行时的层级

在这里插入图片描述

  • 高层级运行时:dockershim、containerd、cri-o等
    • 负责启动grpc-server,对上层提供具体的容器、镜像服务,主要用于为kubelet提供cri接口实现
  • 低层级运行时:runc、kata-runtime、gVisor等
    • 负责容器真正的服务,比如设置ns、设置cgroups等
    • runc是容器运行时;kata-runtime是虚拟机运行时,通过启动一个虚拟机然后再虚机中再启动容器,隔离性好但是消耗大;gVisor是谷歌提供的安全运行时

1.4.容器运行时的选择

在这里插入图片描述

1.5.CRI 提供的方法

在这里插入图片描述

  • CRI 支持的rpc方法如下:
// Runtime service defines the public APIs for remote container runtimes
service RuntimeService {rpc Version(VersionRequest) returns (VersionResponse) {}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 UpdateContainerResources(UpdateContainerResourcesRequest) returns (UpdateContainerResourcesResponse) {}rpc ReopenContainerLog(ReopenContainerLogRequest) returns (ReopenContainerLogResponse) {}rpc ExecSync(ExecSyncRequest) returns (ExecSyncResponse) {}rpc Exec(ExecRequest) returns (ExecResponse) {}rpc Attach(AttachRequest) returns (AttachResponse) {}rpc PortForward(PortForwardRequest) returns (PortForwardResponse) {}rpc ContainerStats(ContainerStatsRequest) returns (ContainerStatsResponse) {}rpc ListContainerStats(ListContainerStatsRequest) returns (ListContainerStatsResponse) {}rpc PodSandboxStats(PodSandboxStatsRequest) returns (PodSandboxStatsResponse) {}rpc ListPodSandboxStats(ListPodSandboxStatsRequest) returns (ListPodSandboxStatsResponse) {}rpc UpdateRuntimeConfig(UpdateRuntimeConfigRequest) returns (UpdateRuntimeConfigResponse) {}rpc Status(StatusRequest) returns (StatusResponse) {}rpc CheckpointContainer(CheckpointContainerRequest) returns (CheckpointContainerResponse) {}rpc GetContainerEvents(GetEventsRequest) returns (stream ContainerEventResponse) {}rpc ListMetricDescriptors(ListMetricDescriptorsRequest) returns (ListMetricDescriptorsResponse) {}rpc ListPodSandboxMetrics(ListPodSandboxMetricsRequest) returns (ListPodSandboxMetricsResponse) {}rpc RuntimeConfig(RuntimeConfigRequest) returns (RuntimeConfigResponse) {}
}// ImageService defines the public APIs for managing images.
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.开源运行时的比较

通过对比开源运行时的实现,可以知道为什么kubenetes抛弃了docker

2.1.三种运行时对比

  • 三种运行时对比:docker、containerd、cri-o
    在这里插入图片描述

  • docker 和 containerd 差异细节
    在这里插入图片描述

  • 早期内置dockershim,kubelet调用dockershim后,需要依次经过dockershim、docker daemon、containerd之后,才能调用到oci runtime,非常厚重,而且docker本身包含很多kubernetes用不到的功能组件(如storage、networking等),由于代码内置在kubernetes中而不得不携带

  • 后来谷歌带头为cr定义了cri规范之后,docker不得不将container和image的部分抽取出来成为独立的containerd组件,去除了kubelet调用 dockershim和docker daemon 的两层,效率大大提升

  • cri-o是专为 Kubernetes 优化的轻量级运行时,仅实现 CRI 接口。支持 OCI 标准镜像,与 Docker 镜像兼容。

2.2.多种运行时性能比较

在这里插入图片描述

  • 运行时优劣对比
    在这里插入图片描述

  • 虽然在架构上cri-o比containerd更加轻量,但是性能比较上发现containerd反而更优秀,且containerd是从docker切出来的,兼容性更好,维护人员技能过渡也更平滑,所以决定使用containerd作为运行时

3.CRI项目目录

3.1. cri-api

3.1.1.代码树状结构

  • github项目地址:https://github.com/kubernetes/cri-api
  • cri-api 是 Kubernetes 官方维护的 容器运行时接口(CRI) 的核心定义库,它定义了 Kubernetes 与容器运行时交互的 gRPC 协议和接口规范。
cri-api]# tree
.
├── code-of-conduct.md
├── CONTRIBUTING.md
├── doc.go
├── go.mod
├── go.sum
├── LICENSE
├── OWNERS
├── pkg
│   ├── apis
│   │   ├── runtime
│   │   │   └── v1
│   │   │       ├── api.pb.go  # 根据api.proto,使用protoc-gen-gogo工具生成的 Go 协议缓冲区代码,提供 gRPC 客户端和服务端的实现基础
│   │   │       ├── api.proto  # Protocol Buffers 接口定义文件(支持的grpc方法、请求体、响应体)
│   │   │       └── constants.go  # cri定义的所有常量
│   │   ├── services.go  # 
│   │   └── testing
│   │       ├── fake_image_service.go
│   │       ├── fake_runtime_service.go
│   │       └── utils.go
│   └── errors
│       ├── doc.go
│       ├── errors.go
│       └── errors_test.go
├── README.md
└── SECURITY_CONTACTS6 directories, 19 files

3.1.2.核心代码文件

3.1.2.1.api.proto 接口定义文件
  • 作用:Protocol Buffers 接口定义文件,定义CRI 支持的grpc方法、请求体、响应体
// Runtime service defines the public APIs for remote container runtimes
service RuntimeService {rpc Version(VersionRequest) returns (VersionResponse) {}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 UpdateContainerResources(UpdateContainerResourcesRequest) returns (UpdateContainerResourcesResponse) {}rpc ReopenContainerLog(ReopenContainerLogRequest) returns (ReopenContainerLogResponse) {}rpc ExecSync(ExecSyncRequest) returns (ExecSyncResponse) {}rpc Exec(ExecRequest) returns (ExecResponse) {}rpc Attach(AttachRequest) returns (AttachResponse) {}rpc PortForward(PortForwardRequest) returns (PortForwardResponse) {}rpc ContainerStats(ContainerStatsRequest) returns (ContainerStatsResponse) {}rpc ListContainerStats(ListContainerStatsRequest) returns (ListContainerStatsResponse) {}rpc PodSandboxStats(PodSandboxStatsRequest) returns (PodSandboxStatsResponse) {}rpc ListPodSandboxStats(ListPodSandboxStatsRequest) returns (ListPodSandboxStatsResponse) {}rpc UpdateRuntimeConfig(UpdateRuntimeConfigRequest) returns (UpdateRuntimeConfigResponse) {}rpc Status(StatusRequest) returns (StatusResponse) {}rpc CheckpointContainer(CheckpointContainerRequest) returns (CheckpointContainerResponse) {}rpc GetContainerEvents(GetEventsRequest) returns (stream ContainerEventResponse) {}rpc ListMetricDescriptors(ListMetricDescriptorsRequest) returns (ListMetricDescriptorsResponse) {}rpc ListPodSandboxMetrics(ListPodSandboxMetricsRequest) returns (ListPodSandboxMetricsResponse) {}rpc RuntimeConfig(RuntimeConfigRequest) returns (RuntimeConfigResponse) {}
}// ImageService defines the public APIs for managing images.
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.1.2.1.api.pb.go:自动生成的 gRPC 协议代码
  • 作用

    • protoc 编译器根据 api.proto 文件自动生成,包含以下内容:
      • gRPC 服务端和客户端的底层代码:例如 RuntimeServiceServerRuntimeServiceClient 接口,定义了如何通过 gRPC 协议发送/接收请求和响应。
      • 数据结构的序列化/反序列化逻辑:将 Go 结构体(如 CreateContainerRequest)与 Protocol Buffers 二进制格式互转。
      • gRPC 通信的底层实现:包括网络传输、错误处理、元数据传递等。
  • 代码示例(片段):

    // 自动生成的 gRPC 客户端接口(用于调用容器运行时)
    type RuntimeServiceClient interface {RunPodSandbox(ctx context.Context, in *RunPodSandboxRequest, opts ...grpc.CallOption) (*RunPodSandboxResponse, error)CreateContainer(ctx context.Context, in *CreateContainerRequest, opts ...grpc.CallOption) (*CreateContainerResponse, error)// ...其他方法
    }
    
2.1.2.3.services.go:CRI Client接口层
  • 作用

    • 定义 CRI Client 具备的所有方法,供client调用
    • api.pb.go 中自动生成的gRPC 服务端和客户端的底层代码,实现了services.go的所有方法
  • 代码示例(片段):

    // 定义 Kubernetes 内部使用的 CRI 接口(与 gRPC 解耦)
    type RuntimeService interface {RunPodSandbox(config *v1.PodSandboxConfig) (string, error)CreateContainer(podSandboxID string, config *v1.ContainerConfig, sandboxConfig *v1.PodSandboxConfig) (string, error)// ...其他方法
    }
    
2.1.2.4.代码文件调用关系
+------------------------+
|   Kubernetes 内部模块    | 使用 grpc-client 调用 services.go 的接口
+------------------------+↓
+------------------------+
|      services.go        | 定义对外暴露的接口 及 方法
+------------------------+↓
+------------------------+
|      api.pb.go          | 自动生成的 gRPC 通信层,实现了 services.go 所有接口方法
+------------------------+↓
+------------------------+
|  容器运行时(如 containerd) | 通过 gRPC 接收请求
+------------------------+

3.2.cri-client

3.2.1.代码树状结构

  • github项目地址:https://github.com/kubernetes/cri-client.git
  • cri-client 是一个基于 cri-api 实现的 客户端工具或库,用于直接与容器运行时(如 containerd、CRI-O)交互
cri-client]# tree
.
├── code-of-conduct.md
├── CONTRIBUTING.md
├── go.mod
├── go.sum
├── LICENSE
├── OWNERS
├── pkg
│   ├── doc.go
│   ├── fake
│   │   ├── doc.go
│   │   ├── endpoint.go
│   │   ├── endpoint_windows.go
│   │   ├── fake_image_service.go
│   │   └── fake_runtime.go
│   ├── internal
│   │   └── log.go
│   ├── logs
│   │   ├── logs.go
│   │   ├── logs_other.go
│   │   ├── logs_test.go
│   │   ├── logs_windows.go
│   │   ├── tail.go
│   │   └── tail_test.go
│   ├── remote_image.go
│   ├── remote_image_test.go
│   ├── remote_runtime.go
│   ├── remote_runtime_test.go
│   ├── util
│   │   ├── util_unix.go
│   │   ├── util_unix_test.go
│   │   ├── util_unsupported.go
│   │   ├── util_windows.go
│   │   └── util_windows_test.go
│   ├── utils.go
│   └── utils_test.go
├── README.md
└── SECURITY_CONTACTS5 directories, 32 files

3.2.2.核心代码文件

3.2.2.1.remote_image.go 远程调用 image 的 client
  • 封装 cri-api api.pb.go 的 底层client,实现对 cri service.go 文件所有接口及方法的调用细节封装,使得使用方可以直接使用 cri-client 实现对 cri-api 的操作
  • 代码片段示例:
    • remoteImageService 携带 api.pb.go 的 ImageServiceClient
    • remoteImageService 实现了service.go 文件中 ImageManagerService 接口的 ListImages 方法。实现细节:使用ImageServiceClient发起grpc调用,list images
// remoteImageService is a gRPC implementation of internalapi.ImageManagerService.
type remoteImageService struct {timeout     time.DurationimageClient runtimeapi.ImageServiceClientlogger      *klog.Logger
}// ListImages lists available images.
func (r *remoteImageService) ListImages(ctx context.Context, filter *runtimeapi.ImageFilter) ([]*runtimeapi.Image, error) {ctx, cancel := context.WithTimeout(ctx, r.timeout)defer cancel()return r.listImagesV1(ctx, filter)
}func (r *remoteImageService) listImagesV1(ctx context.Context, filter *runtimeapi.ImageFilter) ([]*runtimeapi.Image, error) {resp, err := r.imageClient.ListImages(ctx, &runtimeapi.ListImagesRequest{Filter: filter,})if err != nil {r.logErr(err, "ListImages with filter from image service failed", "filter", filter)return nil, err}return resp.Images, nil
}
3.2.2.2.remote_runtime.go 远程调用 runtime 的 client
  • 封装 cri-api api.pb.go 的 底层client,实现对 cri service.go 文件所有接口及方法的调用细节封装,使得使用方可以直接使用 cri-client 实现对 cri-api 的操作
  • 代码片段示例:
    • remoteRuntimeService 携带 api.pb.go 的 RuntimeServiceClient
    • remoteRuntimeService 实现了service.go 文件中 RuntimeManagerService 接口的 Version 方法。实现细节:使用RuntimeServiceClient发起grpc调用,获取版本
// remoteRuntimeService is a gRPC implementation of internalapi.RuntimeService.
type remoteRuntimeService struct {timeout       time.DurationruntimeClient runtimeapi.RuntimeServiceClient// Cache last per-container error message to reduce log spamlogReduction *logreduction.LogReductionlogger       *klog.Logger
}// Version returns the runtime name, runtime version and runtime API version.
func (r *remoteRuntimeService) Version(ctx context.Context, apiVersion string) (*runtimeapi.VersionResponse, error) {r.log(10, "[RemoteRuntimeService] Version", "apiVersion", apiVersion, "timeout", r.timeout)ctx, cancel := context.WithTimeout(ctx, r.timeout)defer cancel()return r.versionV1(ctx, apiVersion)
}func (r *remoteRuntimeService) versionV1(ctx context.Context, apiVersion string) (*runtimeapi.VersionResponse, error) {typedVersion, err := r.runtimeClient.Version(ctx, &runtimeapi.VersionRequest{Version: apiVersion,})if err != nil {r.logErr(err, "Version from runtime service failed")return nil, err}r.log(10, "[RemoteRuntimeService] Version Response", "apiVersion", typedVersion)if typedVersion.Version == "" || typedVersion.RuntimeName == "" || typedVersion.RuntimeApiVersion == "" || typedVersion.RuntimeVersion == "" {return nil, fmt.Errorf("not all fields are set in VersionResponse (%q)", *typedVersion)}return typedVersion, err
}
http://www.xdnf.cn/news/6139.html

相关文章:

  • 国产 ETL 数据集成厂商推荐—谷云科技 RestCloud
  • 【C++设计模式之Decorator装饰模式】
  • 砷化镓太阳能电池:开启多元领域能源新篇
  • 什么是SparkONYarn模式?
  • 【解析:新能源汽车芯片主要玩家及技术发展】
  • 聊聊JetCache的缓存构建
  • 基于自校准分数的扩散模型在并行磁共振成像中联合进行线圈灵敏度校正和运动校正|文献速递-深度学习医疗AI最新文献
  • SVM在医疗设备故障维修服务决策中的应用:策略、技术与实践
  • NineData 社区版 V4.1.0 正式发布,新增 4 条迁移链路,本地化数据管理能力再升级
  • 不借助 Cursor,如何开发第一款 ios 产品并做到付费榜 Top 2
  • C# 通过脚本实现接口
  • C++:二叉搜索树
  • 【C++】map和set的模拟实现
  • vscode调试c/c++
  • Python笔记:在环境变量中增加了dll加载路径,python提示DLL加载失败
  • HTML:入门
  • Angular 知识框架
  • 【SQL】如何在 SQL 中统计结构化字符串的特征频率
  • 【位运算】常见算法公式使用
  • 360智语:以全栈技术重塑企业级智能体开发新标杆
  • 银行卡真伪验证助力金融合规-银行卡实名认证接口
  • 电机的导程和脉冲之间的关系
  • Ansible Roles 是一种用于层次化和结构化组织 Ansible Playbook 的机制。
  • SVG 知识详解:从入门到精通
  • 鸿蒙5.0项目开发——鸿蒙天气项目的实现(主页1)
  • 《Effective Python》第2章 字符串和切片操作——Python 字符串格式化的现代选择f-strings
  • Python 之 Flask 入门学习
  • 《P4391 [BalticOI 2009] Radio Transmission 无线传输 题解》
  • 完整的 CentOS 6.10 虚拟机安装启动脚本
  • spark中的转换算子