Kubernetes官方java客戶端之五:proto基本操作
歡迎訪問我的GitHub
github.com/zq2599/blog_demos
內容:所有原創文章分類彙總及配套原始碼,涉及Java、Docker、Kubernetes、DevOPS等;
概覽
- 本文是《Kubernetes官方java客戶端》系列的第五篇,以下提到的java客戶端都是指client-jar.jar;
- 經過前面四篇文章的準備和嘗試,我們對java客戶端有了初步瞭解,也成功執行了hello world,接下來要做的是繼續深入學習和實踐,掌握這門利器;
兩個主要脈絡
- java客戶端的基本功能並不複雜,就是以何種手段發起對K8S資源的增刪改查請求,把握以下兩個主脈絡即可:
- proto主線:用K8S官方的protobuf定義將各種資源生成java類,用少量API處理這些物件(特點,API極少,每個API都通用,處理所有型別的資源物件);
- openapi主線:使用openapi工具,將所有資源都自動生成增刪改查的API(特點:API極多,每個資源都有自身的API);
今天的文章我們們來學習和了解proto主線;
proto主線的核心類ProtoClient
-
前面曾提到proto主線的特點是API極少,我們們來看看這些少量的API的源頭:ProtoClient類
-
如上圖所示,ProtoClient提供了增刪改查介面,我們可以用這些介面實現對K8S資源的操作;
-
有了介面,接下來要搞清楚引數怎麼準備,先看create方法的原始碼,看它需要什麼樣的引數:
-
如上圖所示,create方法的第一個引數就是K8S資源類,該類的特性是在泛型中約束的,必須實現com.google.protobuf.Message的子介面;
-
這些入參Message的子類從哪裡來呢?例如我們要建立一個NameSpace的時候,是自己寫一個Message子類?還是說哪裡有現成的?接下來要做的就是搞清楚K8S資源類來自哪裡?畢竟所有K8S資源的操作都要用上這些java類;
-
一起去java客戶端的原始碼尋找線索,這是父子結構的maven工程,在名為client-java-proto的子工程中,它的README檔案給出了線索,地址是:github.com/kubernetes-client/java/tree/master/proto ,如下圖:
-
上圖紅框中的操作向我們揭示了整個過程:先去下載另一個github倉庫,然後此倉庫裡有指令碼generate.sh,該指令碼根據protobuf配置生成java類,這些java檔案被放置在java/proto/src/main/java目錄下;
-
本文是學習K8S官方java客戶端的文章,有關K8S的protobuf詳情不在這裡展開,只給出一段關鍵指令碼供您參考,這是根據proto自動生成程式碼時執行的指令碼,用於下載protobuf檔案,地址:github.com/kubernetes-client/gen/blob/master/proto/dependencies.sh ,如下圖:
-
上圖紅框中的地址是:raw.githubusercontent.com/kubernetes//api/master/rbac/v1alpha1/generated.proto ,內容如下,java客戶端中的java程式碼就是根據這些內容生成的:
-
結合前面的分析,再回到java客戶端原始碼的子工程client-java-proto,可以找到generate.sh指令碼生成的V1.java,這個java檔案裡面有V1版本的所有protobuf物件,如下圖:
-
上圖紅框中Namespace類是GeneratedMessageV3的子類,來看下GeneratedMessageV3的繼承關係,如下圖,該類實現了Message介面,滿足ProtoClient.create方法對入參的泛型約束:
小結
- ProtoClient類提供的操作K8S資源的增刪改查方法;
- java客戶端的client-java-proto子工程內,有透過K8S官方protobuf生成的物件類,這些類就是ProtoClient的增刪查用到的引數;
- 增刪改查方法有了,涉及的物件也有了,接下來可以實戰了;
實戰前的準備
現在還不能馬上寫程式碼,還差最後一個準備步驟:確認API引數;
- 假設實戰的內容是查詢kube-system這個namespace下面的所有pod列表,那麼API相關資訊在哪獲取:
-
開啟API線上文件,我這裡K8S版本是1.15,地址是:v1-15.docs.kubernetes.io/docs/reference/generated/kubernetes-api/v1.15/
-
如下圖,紅框1是pod列表的介面文件,紅框2顯示了該URL,有了這個URL我們可以編碼了:
-
在今後的操作中,所有資源都可以根據該文件找到對應的API資訊,輔助我們編碼;
-
終於,可以開始實戰了;
原始碼下載
- 如果您不想編碼,可以在GitHub下載所有原始碼,地址和連結資訊如下表所示(github.com/zq2599/blog_demos):
名稱 | 連結 | 備註 |
---|---|---|
專案主頁 | github.com/zq2599/blog_demos | 該專案在GitHub上的主頁 |
git倉庫地址(https) | github.com/zq2599/blog_demos.git | 該專案原始碼的倉庫地址,https協議 |
git倉庫地址(ssh) | :zq2599/blog_demos.git | 該專案原始碼的倉庫地址,ssh協議 |
- 這個git專案中有多個資料夾,本章的應用在kubernetesclient資料夾下,如下圖紅框所示:
開始編碼
- 開啟[《Kubernetes官方java客戶端之一:準備 》]中建立的kubernetesclient工程,在裡面新建子工程protobufclient,其pom.xml內容如下,要注意的是spring-boot-starter-json已經被排除,因此序列化工具會變為Gson(原本預設是jackson):
<?xml version="1.0" encoding="UTF-8"?>
4.0.0com.bolingcavalrykubernetesclient1.0-SNAPSHOT../pom.xmlcom.bolingcavalryprotobufclient0.0.1-SNAPSHOTprotobufclientDemo project for protobuf clientjarorg.springframework.bootspring-boot-starter-weborg.springframework.bootspring-boot-starter-jsonorg.projectlomboklomboktrueio.kubernetesclient-javaorg.springframework.bootspring-boot-maven-plugin2.3.0.RELEASE
- 新增ProtobufApplication.java,這是新工程的引導類,也有透過ProtoClient查詢pod列表的程式碼:
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 ObjectOrStatus createnamespace(@PathVariable("namespace") String namespace) throws Exception {
// 建立namespace資源物件
Namespace namespaceObj =
Namespace.newBuilder().setMetadata(Meta.ObjectMeta.newBuilder().setName(namespace).build()).build();
// 透過ProtoClient的create介面在K8S建立namespace
ObjectOrStatus ns = buildProtoClient().create(namespaceObj, "/api/v1/namespaces", "v1", "Namespace");
// 使用Gson將集合物件序列化成JSON,在日誌中列印出來
log.info("ns info n{}", new GsonBuilder().setPrettyPrinting().create().toJson(ns));
return ns;
}
@RequestMapping(value = "/pods/{namespace}", method = RequestMethod.GET)
public ObjectOrStatus pods(@PathVariable("namespace") String namespace) throws Exception {
// 透過ProtoClient的list介面獲取指定namespace下的pod列表
ObjectOrStatus pods = buildProtoClient().list(PodList.newBuilder(), "/api/v1/namespaces/" + namespace + "/pods");
// 使用Gson將集合物件序列化成JSON,在日誌中列印出來
log.info("pod info n{}", new GsonBuilder().setPrettyPrinting().create().toJson(pods));
return pods;
}
}
- 上述程式碼展示了ProtoClient的API的用法,一個是獲取pod列表,一個是建立namespace;
驗證
-
確保K8S環境的config檔案在本地可以訪問(程式碼中kubeConfigPath變數的值);
-
執行ProtobufApplication;
-
先嚐試獲取kube-system這個namespace下的所有pod列表,在瀏覽器訪問: ,響應如下圖,紅框中的items_陣列就是所有pod資訊:
-
上圖中的items_陣列,展開一個卻name欄位是byte陣列,沒辦法看出真實內容:
-
藉助IDEA的斷點功能,可以看清上述name_欄位的內容,如下圖:
-
再來試試建立namespace的功能,瀏覽器執行: ,就會建立名為aaabbbccc的namespace,並將ProtoClient.create的返回資訊展現到瀏覽器上:
-
SSH登入上K8S伺服器,檢視namespace,如下圖紅框,可以見到新增的namespace:
-
驗證完成,基於ProtoClient的API和K8S官方的線上API文件,我們可以輕鬆操作K8S環境;
ProtoClient的短板
-
ProtoClient的短板其實在前面已經提到了,如下圖紅框4所示,線上API文件中提到查詢pod列表的時候可以輸入一些引數(例如過濾條件),但是ProtoClient提供的API我們們也看過了,並不支援輸入查詢引數:
-
來看下ProtoClient請求K8S Api service的核心程式碼,如下圖紅框所示,請求引數欄位已經寫死,所以外面呼叫ProtoClient的API時根本沒辦法把引數傳進來:
-
我們們可以參考上述程式碼自己寫一段,把紅框位置改為API文件中指定的引數,但是,這樣似乎略微麻煩,還有更好的辦法嗎?
- 當然有,敬請期待下一篇,一起學習和實戰openapi主線;
我是欣宸,期待與您一同暢遊Java世界…
來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/2459/viewspace-2826787/,如需轉載,請註明出處,否則將追究法律責任。
相關文章
- Kubernetes官方java客戶端之六:OpenAPI基本操作Java客戶端API
- Kubernetes官方java客戶端之七:patch操作Java客戶端
- Kubernetes官方java客戶端之八:fluent styleJava客戶端
- Kubernetes官方java客戶端之四:內部應用Java客戶端
- Kubernetes官方java客戶端之一:準備Java客戶端
- Kubernetes官方java客戶端之三:外部應用Java客戶端
- Kubernetes安裝之五:配置kubectl客戶端客戶端
- Kubernetes官方java客戶端之二:序列化和反序列化問題Java客戶端
- Redis客戶端基本操作以及檢視慢查詢Redis客戶端
- Kubernetes客戶端認證(三)—— Kubernetes使用CertificateSigningRequest方式簽發客戶端證書客戶端
- java客戶端查詢ES操作步驟Java客戶端
- gRPC之.Net6中的客戶端和服務端共用proto協議檔案RPC客戶端服務端協議
- java websocket 客戶端JavaWeb客戶端
- 【物件儲存】Minio本地執行和 golang客戶端基本操作物件Golang客戶端
- ETH官方客戶端Geth的使用(一)客戶端
- YouTube Vanced: 替代YouTube官方Android客戶端Android客戶端
- Elasticsearch的PHP客戶端操作ElasticsearchPHP客戶端
- kubernetes 客戶端KubeClient使用及常用api客戶端clientAPI
- Zookeeper Java 客戶端搭建Java客戶端
- VNC客戶端是Windows,VNC客戶端是Windows如何進行操作VNC客戶端Windows
- java版gRPC實戰之四:客戶端流JavaRPC客戶端
- [Redis 客戶端整合] Java 中常用Redis客戶端比較Redis客戶端Java
- InfluxDB 客戶端基礎操作2UX客戶端
- ElasticSearch-命令列客戶端操作Elasticsearch命令列客戶端
- Lens —— 最炫酷的 Kubernetes 桌面客戶端客戶端
- Kubernetes客戶端和管理介面大集合客戶端
- GRpc新增客戶端的五種方式RPC客戶端
- zookeeper的Java客戶端APIJava客戶端API
- 【zookeeper之七】Zookeeper客戶端客戶端
- HTTP客戶端框架之RetrofitHTTP客戶端框架
- zookeeper在Linux客戶端操作命令大全Linux客戶端
- ElasticSearch客戶端簡單操作例項Elasticsearch客戶端
- [jaeger] 二、客戶端使用 (Java版本)客戶端Java
- SSH客戶端常用工具SecureCRT操作客戶端Securecrt
- RMAN之客戶端互動(一)客戶端
- RMAN之客戶端互動(二)客戶端
- Java HTTP 客戶端的比較 - reflectoringJavaHTTP客戶端
- Tars-Java客戶端原始碼分析Java客戶端原始碼