3. k8sAPI設計規範
Kubernetes API 是叢集系統中的重要組成部分,Kubernetes 中各種資源(對象)的資料通過該 API 被傳送到後端的持久化存儲(ETCD)中。Kubernetes 叢集中的各部件之間通過該 API實作解耦合,KubernetesAPI中的資源對象都擁有通用的中繼資料,資源對象也可能存在嵌套現象,比如在一個 Pod中嵌套多個 Container。建立一個API 對象是指通過 API 調用建立一條有意義的記錄,該記錄一旦被建立,Kubernetes 将確定對應的資源對象會被自動建立并托管維護。在Kubernetes系統中,大多數情況下, API定義和實作都符合标準的 HTTPREST格式,如通過标準的 HTTP動作(POST、PUT、GET、DELETE)來完成對相關資源對象的查詢、修改、删除等操作。但同時Kubernetes也為某些非标準的REST行為提供了附加的 API,例如,監聽某個資源變化的 Watch接口等。另外,某些 API可能違背嚴格的REST模式,因為接口不是傳回單一的 JSON對象,而是傳回其他類型的資料,如 JSON對象流(Stream)或非結構化的文本日志資料等。 從上面的 CRD定義中可以發現,在 Kubernetes中要想完成一個 CRD,需要指定 Group、Version和 Kind,這在 Kubernetes的 APIServer中簡稱為 GVK。當我們在 Kubernetes中談論API時,經常會提起 4個術語:Groups、Versions、Kinds和 Resources。
(1) Groups/Versions
Kubernetes中的 API 組簡單來說就是相關功能的集合。每個組都有一個或多個版本,它允許我們随着時間的推移改變 API的職責。
(2) Kinds/Resources
每個 API組 - 版本包含一個或多個API類型,我們稱之為 Kinds。雖然一個Kind可以在不同版本之間改變表單内容,但每個表單必須能夠以某種方式存儲其他表單的所有資料(我們可以将資料存儲在字段或者注釋中)。 這意味着,使用舊的API版本不會導緻新的資料丢失或損壞。
Resources隻是 API中的一個 Kind 的使用方式。通常情況下,Kind和 Resources之間是一對一的映射。 例如,Pods資源對應于 Pod 種類。但是有時同一類型可能由多個資源傳回。例如,ScaleKind是由所有 Scale子資源傳回的,它由 Deployments/Scale或Replicasets/Scale組成。這就是允許 KubernetesHPA(HorizontalPodAutoscaler)與不同資源互動的原因。然而,使用 CRD每個 Kind 都将對應一個 Resource。
GVK 是定義一種類型的方式。例如,Daemonsets就是 Kubernetes中的一種資源,當我們要求 Kubernetes建立一個 Daemonsets的時候,Kubectl是如何知道該怎麼向APIServer發送這個資訊呢?是所有的不同資源都發向同一個URL,還是每種資源都是不同的?例如Daemonsets資源内容(見代碼清單2-5)。
apiVersion:apps/v1kind:DaemonSetmetadata:
name:node-exporter
這裡聲明了 apiVersion是 apps/v1,其實就是隐含了 Group是 apps,Version是v1,Kind就是定義的 DaemonSet,而 Kubectl 接收到這個聲明之後,就可以根據這個聲明去調用 APIServer對應的 URL來擷取資訊。例如,/api/apps/v1/daemonset這樣的 API 就是由上面的設計規則實作的。Kubernetes 以符合 REST規範的 URI來組織資源。
前面介紹了 GVK(Group、Version、Kind),接下來介紹APIServer的第二個概念GVR(Group、Version、Resource)。其實了解了GVK 之後再了解GVR 就很容易了,這就是面向對象程式設計中的類和對象的概念是一樣的。Kind 相當于一個類,Resource是具體的 Kind,可以了解為一個類的對象資源。那麼 GVR資源如何對應到GVK?這就是RESTMapping 的功能:RESTMapping 可以将指定的一個GVR(如 Daemonset資源)通過轉換映射傳回對應的GVK 以及支援的操作等。
(3) API版本
為了在相容舊版本的同時不斷更新 API,Kubernetes提供了多版本 API 的支援能力,每個版本的API通過一個版本号路徑字首加以區分,例如 /api/v1beta3。通常情況下,新舊幾個不同的 API版本都能涵蓋所有的 Kubernetes資源對象,在不同的版本之間這些 API存在一些細微差别。Kubernetes開發團隊基于 API級别選擇版本而不是基于資源和域級别來選擇版本,是為了確定API能夠描述一個清晰、連續的系統資源和行為的視圖,能夠控制通路的整個過程和實驗性API的通路 。
API 詳細說明如下。
① GET/<資源名的複數格式>:獲得某一類型的資源清單,例如GET/Pods傳回一個 Pod資源清單。
② POST/<資源名的複數格式>:建立一個資源,該資源來自使用者提供的JSON 對象。
③ GET/<資源名複數格式 >/<名字 >:通過給出的名稱(Name)獲得單個資源,例如 GET /pods/podname傳回一個名稱為“podname”的 Pod。
④ DELETE/< 資源名複數格式 >/< 名字 >:通過給出的名字删除單個資源。删除選項(DeleteOptions)中可以指定的優雅删除(GraceDeletion)的時間(GracePeriodSeconds),該可選項表明了從服務端接收删除請求到資源被删除的時間間隔(機關為s)。不同的類别(Kind)可能為優雅删除時間(Grace Period)申明預設值。使用者送出的優雅删除時間将覆寫該預設值,包括值為0 的優雅删除時間。
⑤ PUT/<資源名複數格式 >/<名字>:通過給出的資源名和用戶端提供的 JSON對象來更新或建立資源。
⑥ PATCH/<資源名複數格式 >/<名字>:選擇修改資源詳細指定的域。此外,KubernetesAPI 添加了資源變動的“觀察者”模式的API。
① GET/watch/<資源名複數格式>:随時間變化,不斷接收一連串的JSON對象,這些JSON 對象記錄了給定資源類别内所有資源對象的變化情況。
② GET/watch/<資源名複數格式 >/:随時間變化,不斷接收一連串的JSON對象,這些JSON 對象記錄了某個給定資源對象的變化情況。