天天看點

學習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 就符合條件