学习gRPC - 3.深入学习一个成熟的gRPC应用

前面2篇介绍了 gRPC 的关键概念以及演示程序。了解工作的基础知识后, 将了解 k8s 在其容器运行时接口技术。

gRPC的应用范围

自从2015年作为开源项目发布以来,gRPC 在大大小小的企业中都取得了成长。然而,尽管 gRPC 作为一种服务器端技术很受欢迎,但它在面向公众的 api 中几乎没有出现。这主要有两个原因。首先,gRPC 依赖 HTTP/2作为其传输协议。虽然主要的客户端浏览器自2015年以来一直支持 HTTP/2,但截至2020年7月,互联网上只有不到一半的网站支持服务器端的协议。在客户端和 web 服务器之间使用 gRPC 的认同还没有到来。面向公众采用 gRPC 的进展缓慢的第二个原因是,使用特定的基于 gRPC 的 API 的客户机需要访问服务器使用的相同模式定义

与像 REST 这样使用 HTTP/1.1的 API 格式相比,必须共享一个共同的 protobuf 文件是一个重要的约束,并且需要客户端对 API 提供的数据结构没有预先知识。使用 REST,只需调用 URL,然后以自描述数据格式(如 JSON、 XML 或 YAML)返回一些数据。

简而言之,gRPC 的复杂性使其难以适用于标准、商业网站和公共 api。然而,这项技术在服务器端正在蓬勃发展。

许多客户在 gRPC 上建立数据图。在一个典型的公司里,你现在已经有了上百个服务,而且 gRPC 是针对这些微服务的 api 的最佳技术,因为它是如此集中,如此高效。它是为“数据中心内部”的用例设计的,但它不是连接到应用程序的正确技术.

现在你明白了吧。确实使用了很多,但是大部分是隐藏在公众视野之外的。它用于促进服务器端后端服务之间闪电般的快速、高效的通信,通常用于数据中心资源根据实时波动的负载自动伸缩的情况。

而且,在现实世界中如何使用 gRPC 的一个主要例子是在 Kubernetes 容器运行时接口(K8S CRI)中,这项技术实际上就是这种自动缩放的同义词。K8s 的一个关键特性是容器编排。K8S CRI 是在 Kubernetes 下管理集装箱的关键组件。而且,gRPC 已经融入了编曲技术的结构中。让我们来看看。

在容器运行时接口中使用 gRPC

为了理解如何使用 gRPC 作为容器运行时接口的通信机制,需要对 Kubernetes 的工作方式有一个高层次的理解,特别是对容器在其体系结构中所扮演的角色。

Kubernetes 是一种服务管理和容器编排技术,旨在支持以 web 规模运行的分布式应用程序。K8s系结构背后的基本逻辑是,应用程序或 API 的功能在 Kubernetes 通过一种称为service的资源来表示。service是网络上应用程序的抽象。给定服务表示的实际逻辑驻留在另一个称为 pod 的抽象资源中。

理解k8s的 service和pod

比如一个应用程序中存在的三个服务的示例。一个服务提供访问功能。另一个提供目录信息,第三个提供购买功能。这些服务都可以通过 IP 地址或 DNS 名称在网络上进行标识。因此,使用应用程序的使用者将相应地调用网络上的服务。然而,该服务没有自己的功能。相反,service的功能是由驻留在服务绑定到的一个或多个pod中的逻辑提供的。

学习gRPC - 3.深入学习一个成熟的gRPC应用

如上所述,pod 是一种抽象资源。Pod 是一个托管 Linux 容器的组织单元。容器是封装和隔离执行编程逻辑的进程的机制。(见下图2)

学习gRPC - 3.深入学习一个成熟的gRPC应用

在容器中运行的进程的示例有 web 服务器、消息代理、数据库和其他类型的可执行二进制文件。一个吊舱可以容纳一个或多个容器,其中每个容器的功能都是独一无二的。换句话说,同时拥有 web 服务器容器和数据库容器的 pod 是非常有可能的。然而,需要注意的是,配置一个 pod 并不仅仅是包含随机数量的容器来承载。定义具有多个容器的 pod 的结构是一项复杂的工作。

需要知道的重要事情是: 在 Kubernetes,服务代表网络的功能。这种功能存在于POD中。给定 pod 中功能的实现是在 pod 中承载的容器中执行的。

这就把我们带到了集装箱。集装箱在 Kubernetes 不是凭空出现的。它们需要被制造出来,而且需要以一种短暂的方式制造出来。K8s是一种动态技术。它可以上下调整资源规模以满足当前的需求。这包括根据需要创建和销毁容器。

在 Kubernetes 有一种抽象的资源叫做部署(deployment)。部署的任务是保证在给定的 Kubernetes 部署中应该运行的所有容器确实正在运行。这一点很重要,因为 Kubernetes 保证为集群定义的状态将始终得到维护

集装箱实现的机制

在进入容器运行时以及 gRPC 在容器实现过程中所扮演的角色之前,了解容器实现背后的机制是有用的。
在 Kubernetes,虚拟机被称为节点。Kubernetes 集群由控制器节点组成,控制一组组成的工作者节点中的活动。简而言之,控制器节点是老板,工作节点是工作者。

学习gRPC - 3.深入学习一个成熟的gRPC应用

集群中的每个工作者节点都有一个名为 kubelet 的代理。可以将 kubelet 视为节点的主管。它接受来自控制器平面的命令,在其节点上执行一些工作,然后确保完成工作。Kubelet 的一个任务是在其工作节点上创建和销毁容器。

为什么一个节点直接与容器一起工作? 我认为一个 pod 是容器的父节点

  • Pod 是绑定到服务的逻辑组织单元。服务表示网络上的应用程序逻辑。Pod 为服务提供逻辑
  • 虽然 pod 确实是组织单位,是容器的父级,但是创建和销毁容器的实际工作是由容器所在的工作节点完成的。
  • 把一个节点想象成一个家具工厂。有许多劳动者(集装箱)在许多工作台(工作舱)上劳动。一个工作台可能正在做椅子,另一个桌子。在工厂的前门是一个执行订单的雇员。这个“订单填充器”知道每个工作台的位置以及它生成的产品。可以将订单填充器看作是一个 Kubernetes 服务。当客户来到工厂并请求一把椅子时,订单填充器调用生产椅子的工作台,并为客户拿到一把椅子。
  • 虽然一个劳动者被分配到一个特定的工作台(一个吊舱) ,工作台并没有雇佣任何劳动者。相反,工厂的工头负责雇佣和分配工人到工作台上。你可以把工头想象成 K8S 的 kubelet。

然而,kubelet 不做这项工作。(记住,kubelet 是一个包工头)相反,它告诉容器运行时接口(CRI)来完成这项工作。

在每个 Kubernetes 工作节点中运行的 kubelet 实例告诉 CRI 创建容器,以响应来自运行在 Kubernetes Controller 节点上的 API 服务器的通知

学习gRPC - 3.深入学习一个成熟的gRPC应用

gRPC 和CRI

Kubelet 告诉 CRI 要做什么的方式是通过与嵌入在 CRI 中的 grc 服务器进行交互。

kubelet 使用 gRPC 在工作节点上创建和销毁容器,与 Container Runtime Interface 进行交互

学习gRPC - 3.深入学习一个成熟的gRPC应用

当需要在一个节点上创建或者销毁一个容器时,kubelet 向运行在该节点 CRI 实例上的 gRPC 服务器发送一条消息来执行该操作,然后 CRI 与安装在工作节点上的容器运行时引擎进行交互,以执行必要的操作。

例如,当 kubelet 想要创建一个容器时,它使用它的 gRPC 客户机将 CreateContainerRequest 消息发送到 CRI 组件上托管的 RPC (远程过程调用)函数 CreateContainer ()。CreateContainer 函数和 CreateContainerRequest.

//用于使用 Kubernetes Container Runtime Interface 创建容器的 gRPC 函数和消息类型
// CreateContainer creates a new container in specified PodSandbox
rpc CreateContainer(CreateContainerRequest) returns (CreateContainerResponse) {}

message CreateContainerRequest {
    // ID of the PodSandbox in which the container should be created.
    string pod_sandbox_id = 1;
    // Config of the container.
    ContainerConfig config = 2;
    // Config of the PodSandbox. This is the same config that was passed
    // to RunPodSandboxRequest to create the PodSandbox. It is passed again
    // here just for easy reference. The PodSandboxConfig is immutable and
    // remains the same throughout the lifetime of the pod.
    PodSandboxConfig sandbox_config = 3;
}

CRI 将创建请求发送到安装在节点上的实际容器运行时。容器运行时创建容器。
允许从一个节点上的各种容器运行时中安装一个。可以安装可靠的 Docker 运行时,但也可以安装其他运行时,例如 containerd、 rkt 或 cri-o、 declared、 cree-oh。(在自定义集群时,选择最适合给定 Kubernetes 安装的容器运行时提供了额外的灵活性。)

一旦容器创建完成,CRI 将返回 protobuf 文件中定义的 CreateContainerResponse 消息,该消息由 gRPC 客户机和服务器共享。CreateContainerResponse 的定义

//CRI grc 服务器返回一个 CreateContainerResponse 消息,其中包含所创建容器的唯一标识符。
message CreateContainerResponse {
    // ID of the created container.
    string container_id = 1;
}

创建和销毁容器只是从 Container Runtime Interface 执行的两个活动。还有其他一些方法,比如停止容器、重新启动容器、将容器列入 pod 中、更新容器的配置信息等等。

gRPC 驱动了 kubelet 和 CRI 之间的所有消息交换。请记住,kubelet 和 CRI 之间的信息交换需要以闪电般的速度进行,有时甚至需要十亿分之一秒的时间。一个典型的以 web 规模运行的 Kubernetes 集群可能有成千上万个容器在数十个、甚至数百个节点中有效地运行。因此,在通信流水线中,速度和效率至关重要, gRPC 就符合条件

readmore

https://kubernetes.io/docs/home/

K8s

https://en.wikipedia.org/wiki/Kubernetes

github博客
微信公众号:chasays, 欢迎关注一起吹牛逼,也可以加微信号「xxd_0225」互吹。

上一篇:惊!Kubernetes 将弃用 Docker,开发者们怎么办?


下一篇:c# – 打开/关闭音乐按钮Console.Beep