深入瞭解Kubernetes REST API的工作方式

雲容器大師發表於2018-11-30

關於Kubernetes REST API的工作方式:

在哪裡以及如何定義從REST路徑到處理REST呼叫的函式的對映?

與etcd的互動發生在哪裡?

從客戶端發出請求到儲存在etcd中物件的端到端路徑是怎樣的?

Kubernetes REST框架

Kubernetes REST實現可大致分為三個部分,如下圖所示。

客戶端/伺服器功能通過k8s.io包中的各種庫實現。伺服器端實現分佈在多個包中。

伺服器端的根目錄包是apiserver, 其包含有endpoints,server,registry和storage等重要的包。

客戶端在client-go包中實現,其包含的主要包是rest。

幾個關鍵Kubernetes概念
1)組(Group)

KubernetesREST API以層次結構組織,並以/apis為根。 一個組為根下的一組REST資源集定義一個邏輯名稱。例如API組名為apps,它在層次結構中就表示為/apis/apps。

可以使用如下命令檢查所有可用的API組:

kubectl get --raw/apis | python -mjson.tool

2)版本(Version)

KubernetesREST API使用版本。版本名用於定義REST資源端點,這些資源短點在組內不斷演變。典型的版本名稱有v1,v1alpha1,v1beta1。可以使用如下命令查詢API組的所有可用版本:

kubectl get-raw /apis/

例如,想找apps組下的所有可用版本,可使用如下命令:

kubectl get --raw/apis/apps | python -mjson.tool

3)型別(Type)

表示概念的命名實體(例如:Pod,Deployment,Service等)。

4)種類(Kind)

Kubernetes型別的JSON/YAML表示。

5)資源(Resource)

處理特定種類的REST請求的端點/路徑。資源在api層次結構中通用表示為:

/apis///namespaces//

例如, deployments可表示為

/apis/apps/v1/namespaces/default/deployments

伺服器端

伺服器端集中探究以下問題:

A: 伺服器中註冊了哪些資源?

B: 與etcd的互動發生在哪裡?

1)genericapiserver.go

檔案先定義APIGroupInfo型別用於儲存關於API組的資訊,例如存在哪些版本以及在這些版本中定義了哪些資源。其次,定義GenericAPIServer型別,並實現為API組註冊REST端點的InstallAPIGroup方法。該方法在api組版本例項中內部呼叫InstallREST方法。為執行伺服器端,GenericAPIServer還包含Run()方法。

2)groupversion.go

檔案先定義APIGroupVersion型別,用於承載關於某api組的特定版本的資訊,例如引用提供實際REST端點實現(store.go)的物件的引用。還定義InstallREST方法,內部呼叫安裝程式上的Install方法來註冊該版本的REST資源。

3)installer.go

檔案定義實現Install方法的APIInstaller型別。Install方法使用GroupVersion例項中的REST實現物件(請參見第2點),以將REST路徑註冊到go-restful庫中的處理函式對映。當使用這個庫時,模式是為一個特定的REST路徑定義一個可呼叫的handler函式。該模式在installer.go中用於設定處理對應於不同資源端點。

例如:ws.GET(action.Path).To(handler), 其中handler是從GroupVersion例項的REST實現物件中獲得的函式。它被定義為處理action.Path上的GET請求時被呼叫。

4)master.go

檔案先定義了包含指向GenericAPIServer例項的指標的Master型別。還定義了InstallAPIs方法,通過呼叫genericapiserver的InstallAPIGroup方法啟動註冊工作流程。在建立Master的新例項時,InstallAPIs方法被呼叫。

5)registry/rest/rest.go

檔案定義了不同的各種介面,應該被任何想要提供Kubernetes-like REST端點的後端實現。該檔案中的關鍵介面是:Storage和StandardStorage。REST實現物件的引用屬於rest.Storage介面型別,該物件由在groupversion.go中的APIGroupVersion維護。

6)registry/generic/registry/store.go

檔案定義了實現rest.StandardStorage介面的Store型別。方法實現在由Store型別維護的Storage物件上的呼叫。

7)storage/Interface.go

檔案定義了一個名為Interface的介面,包含一些方法。如果我們想可用於實際持久化的store,必須實現這些方法。對於’Interface’介面中所有方法,一個關鍵點是它們只返回error而沒有其他的內容。如果任何資料需要由方法返回,將通過一個指標作為引數傳遞的物件返回。作為一個例子,檢查簽名的Get方法。
8)storage/etcd3/store.go

檔案定義了實現storage.Interface的Store型別它使用etcd 的clientv3庫與etcd3進行互動。

客戶端

在客戶端,我們主要探究REST呼叫如何進行?

1)request.go

檔案定義了Request型別,實現用於在資源上進行REST呼叫的方法。進行呼叫的模式是先建立一個NewRequest物件,然後使用流式樣方法鏈來呼叫REST方法(GET,POST,PUT,DELETE)。資源和名稱空間的名稱是建立完整端點所必需的,它們通過鏈式方法呼叫進行定義。

2)client.go

檔案首先定義了一個名為Interface的介面,它包含返回Request物件指標(在request.go中定義)的REST方法包裝器。其次定義了實現Interface介面的REST Client型別。

進行REST呼叫的模式是首先建立一個NewRESTClient,然後通過其中一個REST方法包裝體獲取NewRequest物件。一旦NewRequest物件可用,REST呼叫就像上面解釋的那樣使用方法鏈進行。

探究

Kubernetes程式碼擁有豐富的文件,這有助於理解一段程式碼作用。

包含型別隱含地實現方法的地方,可以很方便的在Interfaces中統計所有方法,進而很容易明白該型別實現了哪些方法。 (登錄檔包很好地實現了這一點,但installer.go是一個不會發生這種情況的例子。)

Golang匯入別名可以幫助確定一個方法來自哪個包。雖然程式碼確實使用了別名,但還有更廣泛的使用它們的空間。
---------------------
 

相關文章