概述

为了保证 CRI 可以正常工作,Kubernetes 集群中的每个节点都需要有一个实现了 CRI 的具体容器运行时 (例如 containerd),这样 kubelet 可以直接对 Pod 及其内部容器进行操作。
下面以 containerd 为例进行说明,containerd 是来自 Docker 的高级容器运行时,实现了 CRI 规范
notion image
containerd 实现了 CRI

宏观接口模型

因为 Pod 是 Kubernetes 中应用运行的最小单位,此外容器运行时除了运行、重启、停止 Pod 操作外,还有容器对应的镜像拉取、删除等操作, 结合两者,我们可以给出一个粗糙的 CRI 模型示例图:
notion image
然后就可以直接将上述接口模型转化成伪代码 (Go 语言实现):
通过上面的伪代码,我们可以对 CRI 有一个基础的认识,下面我们一起看看 Kubernetes 中 CRI 的代码,学习一下成熟的方案和设计思路。

Kubernetes 中的 CRI

Kubernetes 中的 CRI 功能对应的源代码位于 Kubernetes 项目的 staging/src/k8s.io/cri-api 目录,本文以 Kubernetes v1.28 版本源代码进行分析。
CRI 定义和实现使用的是 gRPC 协议,在对应的 gRPC 定义文件中,可以看到两个 Service:
  1. RuntimeService: 定义了容器运行时的相关操作 API
  1. ImageService: 定义了容器镜像管理的相关操作 API
上面的 Service 对应的 Go 代码如下:

containerd

notion image
containerd, Docker 和 CRI 交互
这里以 containerd 为例,看看其内部关于 CRI 接口的具体代码结构,时间所限,这里只留下相关代码骨架截图,具体的源代码不再进行分析。
notion image
remote_image.go 实现了容器镜像相关操作
notion image
remote_runtime.go 实现了容器运行时相关操作

Reference

扩展阅读

转载申请

本作品采用 知识共享署名 4.0 国际许可协议 进行许可,转载时请注明原文链接,图片在使用时请保留全部内容,商业转载请联系作者获得授权。
 

gRPC 是一个高性能、开源和通用的 RPC 框架,由 Google 主导开发,基于 HTTP/2 协议传输,使用 Protocol Buffers(protobuf)作为接口描述语言。gRPC 旨在使客户端和服务器应用程序之间的通信更加简单和高效。以下是 gRPC 的一些关键特性和组成部分的详细解释:

核心特性:

  1. HTTP/2:gRPC 基于 HTTP/2 协议,这意味着它可以利用 HTTP/2 的一些先进特性,如头部压缩、多路复用(单个TCP连接上的多个请求)、服务器推送等。
  1. Protocol Buffers:gRPC 默认使用 Protocol Buffers,这是一种轻量级的、与语言无关的数据交换格式。protobuf 用于定义服务方法和消息格式,并且具有高效的编码和解码能力。
  1. 多种语言支持:gRPC 支持多种编程语言,包括 C/C++、Java、Python、Go、Ruby、C# 等,这使得不同语言编写的服务可以轻松地进行交互。
  1. 四种服务方法类型
      • Unary RPCs:一种简单的一请求一响应模式。
      • Server streaming RPCs:客户端发送一个请求到服务器,然后获取一个流式的响应。
      • Client streaming RPCs:客户端发送一个流式的请求到服务器,然后获取一个响应。
      • Bidirectional streaming RPCs:两端都可以流式地发送请求和响应。

组件和概念:

  1. Service Definition:使用 protobuf 定义服务,指定可远程调用的方法以及它们的请求和响应类型。
  1. Server:实现了 protobuf 文件中定义的服务接口,并运行一个 gRPC 服务器来处理客户端调用。
  1. Client:可以是任何能够调用远程 gRPC 服务的客户端。客户端有一个存根(通常是自动生成的),提供与服务器相同的方法。
  1. Channel:gRPC 客户端用于连接到 gRPC 服务的通道。在 HTTP/2 的基础上,Channel 能够提供多路复用、流控制等功能。

工作流程:

  1. 定义服务和消息:首先使用 protobuf 定义服务接口和消息格式。
    1. 生成代码:使用 protobuf 编译器(protoc)生成客户端和服务器端代码。
    1. 实现服务:在服务器端实现 protobuf 文件中定义的服务接口。
    1. 启动服务器:运行 gRPC 服务器,监听客户端的调用。
    1. 创建客户端存根:客户端通过存根调用服务器端的方法。
    1. 调用服务:客户端使用存根向服务器发送请求,并接收响应。

    性能和效率:

    由于 gRPC 基于 HTTP/2 和 Protocol Buffers,它在传输效率和速度方面通常优于传统的 HTTP/JSON RESTful 接口。HTTP/2 提供的多路复用允许在单个连接上并行传输多个请求和响应,减少了延迟。而 Protocol Buffers 提供了一种更紧凑和高效的方式来序列化数据。

    使用场景:

    gRPC 适用于微服务架构、云服务和任何需要高效通信的分布式系统。它特别适合需要严格服务定义和跨语言服务交互的场景。

    总结:

    gRPC 是一个现代的、高效的 RPC 框架,它通过利用 HTTP/2 和 Protocol Buffers 的强大功能,提供了一种简单、跨语言的方式来设计和实现服务之间的交互。无论是在微服务架构中,还是在需要高性能通信的系统中,gRPC 都是一个非常有吸引力的选择。