前面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中的邏輯提供的。
![](https://img.laitimes.com/img/_0nNw4CM6IyYiwiM6ICdiwiIwIjNx8CX39CXy8CXycXZpZVZnFWbp9zZlBnauUTOmlDNxEWN2AjYhFzM4QTYmNjM4EjMzMGO4ImY2UjYvwFN0cTMyUTMtUGall3LcVmdhNXLwRHdo9CXt92YucWbpRWdvx2Yx5yazF2Lc9CX6MHc0RHaiojIsJye.jpeg)
如上所述,pod 是一種抽象資源。Pod 是一個托管 Linux 容器的組織單元。容器是封裝和隔離執行程式設計邏輯的程序的機制。(見下圖2)
在容器中運作的程序的示例有 web 伺服器、消息代理、資料庫和其他類型的可執行二進制檔案。一個吊艙可以容納一個或多個容器,其中每個容器的功能都是獨一無二的。換句話說,同時擁有 web 伺服器容器和資料庫容器的 pod 是非常有可能的。然而,需要注意的是,配置一個 pod 并不僅僅是包含随機數量的容器來承載。定義具有多個容器的 pod 的結構是一項複雜的工作。
需要知道的重要事情是: 在 Kubernetes,服務代表網絡的功能。這種功能存在于POD中。給定 pod 中功能的實作是在 pod 中承載的容器中執行的。
這就把我們帶到了集裝箱。集裝箱在 Kubernetes 不是憑空出現的。它們需要被制造出來,而且需要以一種短暫的方式制造出來。K8s是一種動态技術。它可以上下調整資源規模以滿足目前的需求。這包括根據需要建立和銷毀容器。
在 Kubernetes 有一種抽象的資源叫做部署(deployment)。部署的任務是保證在給定的 Kubernetes 部署中應該運作的所有容器确實正在運作。這一點很重要,因為
Kubernetes 保證為叢集定義的狀态将始終得到維護
。
集裝箱實作的機制
在進入容器運作時以及 gRPC 在容器實作過程中所扮演的角色之前,了解容器實作背後的機制是有用的。
在 Kubernetes,虛拟機被稱為節點。Kubernetes 叢集由控制器節點組成,控制一組組成的工作者節點中的活動。簡而言之,控制器節點是老闆,工作節點是工作者。
叢集中的每個工作者節點都有一個名為 kubelet 的代理。可以将 kubelet 視為節點的主管。它接受來自控制器平面的指令,在其節點上執行一些工作,然後確定完成工作。Kubelet 的一個任務是在其工作節點上建立和銷毀容器。
為什麼一個節點直接與容器一起工作? 我認為一個 pod 是容器的父節點
- Pod 是綁定到服務的邏輯組織單元。服務表示網絡上的應用程式邏輯。
。Pod 為服務提供邏輯
- 雖然 pod 确實是組織機關,是容器的父級,但是建立和銷毀容器的實際工作是由容器所在的工作節點完成的。
- 把一個節點想象成一個家具工廠。有許多勞動者(集裝箱)在許多工作台(工作艙)上勞動。一個工作台可能正在做椅子,另一個桌子。在工廠的前門是一個執行訂單的雇員。這個“訂單填充器”知道每個工作台的位置以及它生成的産品。可以将訂單
。當客戶來到工廠并請求一把椅子時,訂單填充器調用生産椅子的工作台,并為客戶拿到一把椅子。填充器看作是一個 Kubernetes 服務
- 雖然一個勞動者被配置設定到一個特定的工作台(一個吊艙) ,工作台并沒有雇傭任何勞動者。相反,工廠的工頭負責雇傭和配置設定勞工到工作台上。你可以把工頭想象成 K8S 的 kubelet。
然而,kubelet 不做這項工作。(記住,kubelet 是一個包工頭)相反,它告訴容器運作時接口(CRI)來完成這項工作。
在每個 Kubernetes 工作節點中運作的 kubelet 執行個體告訴 CRI 建立容器,以響應來自運作在 Kubernetes Controller 節點上的 API 伺服器的通知
gRPC 和CRI
Kubelet 告訴 CRI 要做什麼的方式是通過與嵌入在 CRI 中的 grc 伺服器進行互動。
kubelet 使用 gRPC 在工作節點上建立和銷毀容器,與 Container Runtime Interface 進行互動
當需要在一個節點上建立或者銷毀一個容器時,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 就符合條件
。