1. 程式人生 > >Kubernetes官方java客戶端之五:proto基本操作

Kubernetes官方java客戶端之五:proto基本操作

### 歡迎訪問我的GitHub [https://github.com/zq2599/blog_demos](https://github.com/zq2599/blog_demos) 內容:所有原創文章分類彙總及配套原始碼,涉及Java、Docker、Kubernetes、DevOPS等; ### 概覽 1. 本文是《Kubernetes官方java客戶端》系列的第五篇,以下提到的java客戶端都是指client-jar.jar; 2. 經過前面四篇文章的準備和嘗試,我們對java客戶端有了初步瞭解,也成功運行了hello world,接下來要做的是繼續深入學習和實踐,掌握這門利器; ### 兩個主要脈絡 - java客戶端的基本功能並不複雜,就是以何種手段發起對K8S資源的增刪改查請求,把握以下兩個主脈絡即可: 1. proto主線:用K8S官方的protobuf定義將各種資源生成java類,用少量API處理這些物件(特點,API極少,每個API都通用,處理所有型別的資源物件); 2. openapi主線:使用openapi工具,將所有資源都自動生成增刪改查的API(特點:API極多,每個資源都有自身的API); 今天的文章咱們來學習和了解proto主線; ### proto主線的核心類ProtoClient 1. 前面曾提到proto主線的特點是API極少,咱們來看看這些少量的API的源頭:ProtoClient類 ![在這裡插入圖片描述](https://img2020.cnblogs.com/other/485422/202101/485422-20210107075101286-2147165189.png) 2. 如上圖所示,ProtoClient提供了增刪改查介面,我們可以用這些介面實現對K8S資源的操作; 3. 有了介面,接下來要搞清楚引數怎麼準備,先看create方法的原始碼,看它需要什麼樣的引數: ![在這裡插入圖片描述](https://img2020.cnblogs.com/other/485422/202101/485422-20210107075102359-560273858.png) 4. 如上圖所示,create方法的第一個引數就是K8S資源類,該類的特性是在泛型中約束的,必須實現com.google.protobuf.Message的子介面; 5. 這些入參Message的子類從哪裡來呢?例如我們要建立一個NameSpace的時候,是自己寫一個Message子類?還是說哪裡有現成的?接下來要做的就是搞清楚K8S資源類來自哪裡?畢竟所有K8S資源的操作都要用上這些java類; 6. 一起去java客戶端的原始碼尋找線索,這是父子結構的maven工程,在名為client-java-proto的子工程中,它的README檔案給出了線索,地址是:https://github.com/kubernetes-client/java/tree/master/proto ,如下圖: ![在這裡插入圖片描述](https://img2020.cnblogs.com/other/485422/202101/485422-20210107075102803-153499015.png) 7. 上圖紅框中的操作向我們揭示了整個過程:先去下載另一個github倉庫,然後此倉庫裡有指令碼generate.sh,該指令碼根據protobuf配置生成java類,這些java檔案被放置在java/proto/src/main/java目錄下; 8. 本文是學習K8S官方java客戶端的文章,有關K8S的protobuf詳情不在這裡展開,只給出一段關鍵指令碼供您參考,這是根據proto自動生成程式碼時執行的指令碼,用於下載protobuf檔案,地址:https://github.com/kubernetes-client/gen/blob/master/proto/dependencies.sh ,如下圖: ![在這裡插入圖片描述](https://img2020.cnblogs.com/other/485422/202101/485422-20210107075103212-1916829817.png) 9. 上圖紅框中的地址是:https://raw.githubusercontent.com/kubernetes//api/master/rbac/v1alpha1/generated.proto ,內容如下,java客戶端中的java程式碼就是根據這些內容生成的: ![在這裡插入圖片描述](https://img2020.cnblogs.com/other/485422/202101/485422-20210107075103686-251290933.png) 10. 結合前面的分析,再回到java客戶端原始碼的子工程client-java-proto,可以找到generate.sh指令碼生成的V1.java,這個java檔案裡面有V1版本的所有protobuf物件,如下圖: ![在這裡插入圖片描述](https://img2020.cnblogs.com/other/485422/202101/485422-20210107075104139-181139688.png) 11. 上圖紅框中Namespace類是GeneratedMessageV3的子類,來看下GeneratedMessageV3的繼承關係,如下圖,該類實現了Message介面,滿足ProtoClient.create方法對入參的泛型約束: ![在這裡插入圖片描述](https://img2020.cnblogs.com/other/485422/202101/485422-20210107075104516-1904284586.png) ### 小結 1. ProtoClient類提供的操作K8S資源的增刪改查方法; 2. java客戶端的client-java-proto子工程內,有通過K8S官方protobuf生成的物件類,這些類就是ProtoClient的增刪查用到的引數; 3. 增刪改查方法有了,涉及的物件也有了,接下來可以實戰了; ### 實戰前的準備 現在還不能馬上寫程式碼,還差最後一個準備步驟:確認API引數; - 假設實戰的內容是查詢kube-system這個namespace下面的所有pod列表,那麼API相關資訊在哪獲取: 1. 開啟API線上文件,我這裡K8S版本是1.15,地址是:https://v1-15.docs.kubernetes.io/docs/reference/generated/kubernetes-api/v1.15/ 2. 如下圖,紅框1是pod列表的介面文件,紅框2顯示了該URL,有了這個URL我們可以編碼了: ![在這裡插入圖片描述](https://img2020.cnblogs.com/other/485422/202101/485422-20210107075104881-1000858394.png) 3. 在今後的操作中,所有資源都可以根據該文件找到對應的API資訊,輔助我們編碼; 4. 終於,可以開始實戰了; ### 原始碼下載 1. 如果您不想編碼,可以在GitHub下載所有原始碼,地址和連結資訊如下表所示(https://github.com/zq2599/blog_demos): | 名稱 | 連結 | 備註| | :-------- | :----| :----| | 專案主頁| https://github.com/zq2599/blog_demos | 該專案在GitHub上的主頁 | | git倉庫地址(https)| https://github.com/zq2599/blog_demos.git | 該專案原始碼的倉庫地址,https協議 | | git倉庫地址(ssh)| [email protected]:zq2599/blog_demos.git | 該專案原始碼的倉庫地址,ssh協議 | 2. 這個git專案中有多個資料夾,本章的應用在kubernetesclient資料夾下,如下圖紅框所示: ![在這裡插入圖片描述](https://img2020.cnblogs.com/other/485422/202101/485422-20210107075105136-491374194.png) ### 開始編碼 1. 開啟[《Kubernetes官方java客戶端之一:準備 》](https://blog.csdn.net/boling_cavalry/article/details/107480015)中建立的kubernetesclient工程,在裡面新建子工程protobufclient,其pom.xml內容如下,要注意的是spring-boot-starter-json已經被排除,因此序列化工具會變為Gson(原本預設是jackson): ```java ``` 2. 新增ProtobufApplication.java,這是新工程的引導類,也有通過ProtoClient查詢pod列表的程式碼: ```java package com.bolingcavalry.protobufclient; import com.google.gson.GsonBuilder; import io.kubernetes.client.ProtoClient; import io.kubernetes.client.ProtoClient.ObjectOrStatus; import io.kubernetes.client.openapi.ApiClient; import io.kubernetes.client.proto.Meta; import io.kubernetes.client.proto.V1.Namespace; import io.kubernetes.client.proto.V1.PodList; import io.kubernetes.client.util.ClientBuilder; import io.kubernetes.client.util.KubeConfig; import lombok.extern.slf4j.Slf4j; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.web.bind.annotation.PathVariable; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestMethod; import org.springframework.web.bind.annotation.RestController; import java.io.FileReader; @SpringBootApplication @RestController @Slf4j public class ProtobufApplication { public static void main(String[] args) { SpringApplication.run(ProtobufApplication.class, args); } /** * 根據配置檔案建立ProtoClient例項 * @return * @throws Exception */ private ProtoClient buildProtoClient() throws Exception { // 存放K8S的config檔案的全路徑 String kubeConfigPath = "/Users/zhaoqin/temp/202007/05/config"; // 以config作為入參建立的client物件,可以訪問到K8S的API Server ApiClient client = ClientBuilder .kubeconfig(KubeConfig.loadKubeConfig(new FileReader(kubeConfigPath))) .build(); // 建立操作類 return new ProtoClient(client); } @RequestMapping(value = "/createnamespace/{namespace}", method = RequestMethod.GET) public Object