用Java开发自己的Kubernetes控制器,想试试吗?
作者 |?Nicolas Fr?nkel
譯者 |?天道酬勤?責編 | 徐威龍
封圖|?CSDN 下載于視覺中國
在本文中,我們將開始開發自己的Kubernetes控制器。?
技術棧可以是Python、NodeJS或Ruby。因為這個博客被命名為為“ Java極客”,因此選擇Java是很正常的。?
作為一個用例,我們將實現sidecar模式:每當一個pod被調度時,sidecar pod也會隨之被調度。如果將前者刪除,則后者也必須刪除。
選擇合適的工具
?
為了用Java執行REST調用,首先需要生成綁定。有幾種方法可以做到這些。最繁瑣的操作是手動執行此操作:需要仔細掌握所有可能的JSON請求和響應組合,開發相應的Java對象,選擇JSON序列化框架以及HTTP客戶端。第二個最佳選擇是使用專有代碼生成器,例如Swagger(https://swagger.io/)或Apiary(https://apiary.io/)。這就要求API提供程序以一種可能的格式提供模型。不利的一面是,需要使用相關工具。有時,格式或多或少是開放的,例如OpenAPI規范(https://swagger.io/specification/)。在這種情況下,可以從實現該格式的工具中選擇工具。在最好的情況下,可能已經提供了綁定。
Kubernetes就是這種情況:該項目為各種語言提供了自己的綁定(https://kubernetes.io/docs/reference/using-api/client-libraries/)。問題在于語言包裝器與REST API非常接近,對于作者來說太熟悉了。例如,這是列出所有名稱空間中所有pod的方式:
ApiClient?client?=?Config.defaultClient(); CoreV1Api?core?=?new?CoreV1Api(client); V1PodList?pods?=core.listPodForAllNamespaces(null,?null,?null,?null,?null,?null,?null,?null);??注意:所有的null參數需要傳遞。
這就是“包裝器代碼非常接近REST API”的意思。幸運的是,還有另一個選擇。Fabric8組織在Github上提供了流暢的Java API。與上述代碼等效的代碼是:
KubernetesClient?client?=?new?DefaultKubernetesClient(); PodList?pods?=?client.pods().inAnyNamespace().list();????注意:無需傳遞無用的null參數。Fabric8組織在Github上提供了流暢的Java API:
https://github.com/fabric8io/kubernetes-client)
Fabric8快速概述
?
簡單來說,使用Fabric8的API,所有Kubernetes資源都可以在KubernetesClient實例上使用,例如:
client.namespaces()
client.services()
client.nodes()
根據資源的性質,它的作用域可以是一個名稱空間,也可以不是:
client.pods().inAnyNamespace()
client.pods().inNamespace("ns")
此時,可以調用這個動作:?
列出所有名稱空間中的所有Pod:
client.pods().inAnyNamespace().list();刪除名稱空間ns中的所有pod:
client.pods().delete(client.pods().inNamespace("ns").list().getItems());創建一個名為ns的新名稱空間:client.namespaces().createNew().withApiVersion("v1").withNewMetadata().withName("ns").endMetadata().done();實現控制循環
注意,Kubernetes控制器只是一個控制循環,它監視集群的狀態,并將其與所需狀態進行協調。為了能夠調度/刪除事件,需要使用Observer模式。應用程序將訂閱此類事件,當他們發生時,相關回調將被觸發。
下圖是一個非常簡單的API圖:? ? ? ?
要真正實現一個監視程序,只需執行以下幾行代碼:
public?class?DummyWatcher?implements?Watcher<Pod>?{@Overridepublic?void?eventReceived(Action?action,?Pod?pod)?{switch?(action)?{case?ADDED:????//注意1????????break;case?MODIFIED:?//注意2???????break;case?DELETED:??//注意3break;case?ERROR:????//注意4???????break;}}@Overridepublic?void?onClose(KubernetesClientException?cause)?{//注意5???????????????} }client.pods().inAnyNamespace().watch(DummyWatcher());注意:添加新pod時起作用
修改現有pod時起作用
刪除pod時起作用
發生錯誤時起作用
清理任何資源。如果客戶端正確關閉,cause將為null
具體細節
?
現在,我們擁有了實現sidecar模式所需的一切。我不會展示全部代碼,它可以在GitHub上找到:https://github.com/nfrankel/jvm-controller,但需要重點強調一些關鍵內容。
1) 標記sidecar
從本質上講,觀察者需要在添加新的pod時添加一個sidecar pod,并在移除它時刪除它。這種基本方法行不通:如果安排了sidecar pod,則將觸發觀察者,并向sidecar添加新的sidecar pod。而且這種情況還會持續下去。因此,標記sidecar pod至關重要。檢測到此類pod時,不應觸發創建邏輯。
有幾種標記sidecar pod的方法:
在sidecar pod的名稱后加上特定的字符串,例如sidecar
添加如下特定標簽:
2) 連同pod一起移除sidecar
pod應只有一個sidecar。如上所述,應在添加Pod時創建它,而在刪除后者時應刪除它。
因此,應將對主pod的引用添加到sidecar中。這樣,當pod被刪除時,如果它不是一個sidecar,我們應該找到分配的sidecar并將其刪除。
第一種簡單的方法是在刪除主pod時顯式刪除sidecar。但是,這是一項繁重的工作,需要花很多時間。Kubernetes允許將pod的生命周期綁定到另一個Pod的生命周期。然后,刪除邏輯由Kubernetes本身處理。這由ownerReference的概念支持。
該API使其易于實現:
client.pods().inNamespace("ns").createNew().withNewMetadata().addNewOwnerReference().withApiVersion("v1").withKind("Pod").withName(podName).withUid(pod.getMetadata().getUid()).endOwnerReference().endMetadata().done();3) 始終保持一個sidecar添加一個sidecar并不意味著它將永遠保持這種方式。例如,可以刪除屬于部署的pod。部署的目標是重新創建一個pod,以達到所需的副本數量。
同樣,如果在保留主pod的同時刪除了sidecar,則應使用正確的引用生成一個新的sidecar。
?
結論
?
在這篇文章中,我們描述了如何在JVM上使用Java語言實現Kubernetes控制器。借助Fabric8的API,實現的操作非常簡單。主要問題來自調度/刪除邏輯中的極端情況。在本系列的下一篇(也是最后一篇)文章中,我們將最終看到如何部署和運行代碼。
這篇文章的完整源代碼可以在Github上以Maven格式找到:
https://github.com/nfrankel/jvm-controller
希望這篇文章對你有用,歡迎評論區和我們討論。
原文:https://blog.frankel.ch/your-own-kubernetes-controller/2/
防疫、復工如何并行?天云數據推出人工智能監測方案!到底如何做到事前預防,而不是事后諸葛亮?本周四晚8點,天云數據VP陳勇為各位揭曉答案!掃描下方二維碼免費報名~
今日福利:點擊閱讀原文,憑優惠碼“AIP1510”都可獲得價值299元的「2020 AI開發者萬人大會」在線直播門票一張。??
推薦閱讀:為什么要在油氣行業中應用 IoT?這 8 個應用場景告訴你 IoT 在油氣行業中可以做什么 生產環境使用HBase,你必須知道的最佳實踐 Java 14 來了! 字節跳動武漢招聘 2000 人,距離大廠 Offer,你還差這篇 Java 干貨!| 原力計劃 數字合約如何將所有權下放?如何使用腳本系統將交易轉換為可編程的智能合約?答案就在這篇文章里! 人生苦短,不光要用Python,還要在VSCode里用 真香,朕在看了!總結
以上是生活随笔為你收集整理的用Java开发自己的Kubernetes控制器,想试试吗?的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 【快讯】呼伦贝尔市人民医院利用Oracl
- 下一篇: 华为发布基于自进化AI的HiSec In