這篇文章將為大家詳細講解有關(guān)如何在GO語言中使用Kubernetes API,文章內(nèi)容質(zhì)量較高,因此小編分享給大家做個參考,希望大家閱讀完這篇文章后對相關(guān)知識有一定的了解。
創(chuàng)新互聯(lián)成立于2013年,先為瀍河等服務(wù)建站,瀍河等地企業(yè),進行企業(yè)商務(wù)咨詢服務(wù)。為瀍河企業(yè)網(wǎng)站制作PC+手機+微官網(wǎng)三網(wǎng)同步一站式服務(wù)解決您的所有建站問題。
隨著Kubernetes越來越受歡迎,圍繞它的集成和監(jiān)控的數(shù)量也在不斷增長。Golang編寫的所有此類功能的關(guān)鍵組件是kubernetes / client-go——一個用于與Kubernetes集群API通信的軟件包。本文中,我們將討論client-go使用的基本知識,以及如何為開發(fā)人員節(jié)約編寫實際應(yīng)用程序邏輯所需的時間。我們還將展示使用該軟件包的最佳實踐,并從每天與Kubernetes進行集成工作的開發(fā)人員的角度,分享我們已有的經(jīng)驗。內(nèi)容將包括:
● 集群中的客戶端認證 vs. 集群外的客戶端認證
● 基本列表,使用client-go去創(chuàng)建和刪除Kubernetes對象的操作
● 如何使用ListWatch和Informers監(jiān)視K8s事件并做出反應(yīng)
● 如何管理軟件包依賴
Kubernetes有很多受歡迎的地方。用戶喜歡它的豐富功能、穩(wěn)定性和性能。對貢獻者來說,Kubernetes開源社區(qū)不僅規(guī)模龐大,還易于上手、反饋迅速。而真正讓Kubernetes吸引了第三方開發(fā)者的是它的可擴展性。該項目提供了很多方式來添加新功能、擴展現(xiàn)有功能而且不會中斷主代碼庫。正是這些,使得Kubernetes發(fā)展成為了一個平臺。
這里有一些方式來擴展Kubernetes:
上圖所示,你可以發(fā)現(xiàn)每個Kubernetes集群組件無論是Kubelet還是API server,都可以以某種方式進行擴展。今天我們將重點介紹一種“自定義控制器”的方式,從現(xiàn)在起我將它稱為Kubernetes控制器(Kubernetes Controller),或者簡單地稱為控制器(Controller)。
控制器最常見的定義是:使得系統(tǒng)的當(dāng)前狀態(tài)達到所期望的狀態(tài)的代碼。但這究竟是什么意思呢?我們以Ingress控制器為例。Ingress是一個Kubernetes資源,它能夠?qū)褐衧ervices的外部訪問進行定義。通常采用HTTP并且有負載均衡支持。然而Kubernetes的核心代碼中并沒有ingress的實現(xiàn)。第三方控制器的實現(xiàn)將包含:
監(jiān)控ingress/services/endpoint 資源的事件(創(chuàng)建、更新、刪除)
程序內(nèi)部或外部的負載均衡器
使用負載均衡器的地址來更新Ingress
“所期望的狀態(tài)”在Ingress這里指的是IP地址指向運行著的負載均衡器,該均衡器由用戶根據(jù)ingress規(guī)范定義的規(guī)則實現(xiàn)。并且由外部Ingress控制器負責(zé)將ingress資源轉(zhuǎn)移到這一狀態(tài)。
對相同的資源,控制器的實現(xiàn)以及部署他們的方式也可能會有所不同。你可以選擇nginx控制器并將其部署到集群中的每個節(jié)點上作為守護進程集(Daemon Set),也可以選擇在Kubernetes集群外部運行ingress控制器并且對F5編程作為負載均衡器。這里沒有嚴(yán)格的規(guī)定,Kubernetes就是如此靈活。
這里有幾種獲得Kubernetes集群及其資源相關(guān)信息的方法,你可以使用Dashboard、kubectl或者使用對Kubernetes API的編程式訪問來實現(xiàn)。Client-go所有用Go語言編寫的工具中使用最為廣泛的庫,還有許多其他語言的版本(java、python等)。如果你還沒自己寫過控制器,我推薦你首先去嘗試go/client-go。
Kubernetes是用Go編寫的,而且我發(fā)現(xiàn)使用和主項目相同的語言來開發(fā)插件會更加方便。
要熟悉相關(guān)的平臺和工具,最好的辦法就是去實踐,去實現(xiàn)一些東西。我們從簡單入手,先實現(xiàn)一個如下的控制器:
監(jiān)控Kubernetes節(jié)點
當(dāng)節(jié)點上的鏡像占用存儲空間時進行警報,并且可以更改
這部分的實現(xiàn),源碼可以在這里找到:https://github.com/alena1108/kubecon2017
配置項目
作為一名開發(fā)者,我和Rancher Labs的同事們更愿意使用輕便簡易的工具,在這里我將分享3個我最喜歡的工具,它們將幫助我們完成第一個項目。
go-skel – Go語言的MicroService skeleton,只需執(zhí)行run ./skel.sh test123即可,它會為新的go項目test123創(chuàng)建skeleton。
trash – Go語言的供應(yīng)商管理工具。實際上這兒有很多依賴項管理工具,但是在臨時依賴項管理方面,trash使用起來非常出色,而且簡單。
dapper – 在一致性環(huán)境中對任何現(xiàn)有構(gòu)建工具進行封裝的一種工具
添加client-go作為一個依賴項
為了方便使用client-go的代碼,我們必須要將其設(shè)置為項目的依賴項。將它添加到vendor.conf文件中:
接著運行trash。它會將vendor.conf中定義的所有依賴項都拉到項目的vendor文件夾中。在這里需要確證client-go與你集群對應(yīng)的Kubernetes版本是兼容的。
創(chuàng)建一個客戶端
在創(chuàng)建與Kubernetes API通信的客戶端之前,我們必須要先決定如何運行我們的工具:是在Kubetnetes集群內(nèi)部還是外部。當(dāng)應(yīng)用程序在集群內(nèi)部運行時,對它進行容器化,部署成為Kubernetes pod。它還提供了一些額外的功能:你可以選擇部署它的方式(Deamon set運行在每個節(jié)點上,或者作為n個副本的部署),配置針對它的檢查等等。當(dāng)應(yīng)用程序在集群外部運行時,就需要自己來管理它。下面的配置可以讓我們的工具變得更靈活,并且支持基于config flag定義客戶端的兩種方式:
我們將在調(diào)試應(yīng)用程序時使用集群外部運行的方式,這樣你不需要每次都構(gòu)建鏡像并且將其重新部署成Kubernetes pod。在測試好應(yīng)用程序后,我們就可以構(gòu)建鏡像并將其部署到集群中。
正如在截圖中看到的那樣,正在構(gòu)建配置,并將其傳遞到kubernetes.NewForConfig來生成客戶端。
我們的工具需要監(jiān)控節(jié)點。在實現(xiàn)邏輯流程之前,我們先來熟悉使用client-go執(zhí)行CRUD操作:
上面的截圖展示了:
List節(jié)點minikube,是經(jīng)過FieldSelector過濾器實現(xiàn)的
用新的標(biāo)注來更新節(jié)點
使用gracePerios=10秒指令刪除節(jié)點—意思是從該命令執(zhí)行后10秒才會執(zhí)行刪除操作
上面所有的步驟都是使用我們之前創(chuàng)建的用戶集(clientset)進行的。
我們還需要節(jié)點上鏡像的相關(guān)信息;它可以通過訪問相應(yīng)的字段來檢索:
現(xiàn)在我們知道了如何從Kubernetes APIs中獲取節(jié)點并從中得到鏡像信息。那么我們該如何監(jiān)控鏡像大小的變化呢?最簡單的方法是周期性輪詢節(jié)點,計算當(dāng)前的鏡像存儲容量,并將其和先前輪詢的結(jié)果比較。這里的不足之處在于:無論節(jié)點是否發(fā)生變化,我們執(zhí)行的列表調(diào)用都會獲取所有的節(jié)點,這可能會很費資源——特別是當(dāng)輪詢間隔很短的時候。而我們真正想要實現(xiàn)的是—在節(jié)點發(fā)生變化時得到通知,只有在這之后才執(zhí)行我們的邏輯流程。這些就是client-go的Informer來做的。
在這個例子中,我們經(jīng)過watchList指令為節(jié)點對象創(chuàng)建Informer來監(jiān)控節(jié)點,設(shè)置對象類型為api.Node和30秒的同步周期來周期性地輪詢節(jié)點,無論節(jié)點是否發(fā)生改變——這種方式在更新事件出于某種原因發(fā)生終止時可以很好的進行撤回。在最后一個參數(shù),我們傳遞了2個回調(diào)函數(shù)——handleNodeAdd和handleNodeUpdate。這些回調(diào)函數(shù)具有實際的邏輯,并且在節(jié)點上的鏡像占用存儲發(fā)生改變時觸發(fā)。NewInformer返回2個對象——controller和store。一旦controller啟動,將會開始對node.update和node.add的監(jiān)控,并且調(diào)用回調(diào)函數(shù)。這部分代碼的存儲區(qū)位于內(nèi)存緩存中,由informer負責(zé)更新,另外你可以在緩存區(qū)中獲取節(jié)點對象而不用直接調(diào)用Kubernetes APIs:
我們的項目中只有一個控制器,使用常規(guī)的Informer就足夠了。不過,如果未來你的項目最終同一個對象擁有了多個控制器,我建議你使用SharedInformer。這樣一來你不用再一個一個為每個控制器配上Informer,只需要注冊一個Shared informer即可,并且讓每個控制器注冊自己的一組回調(diào)函數(shù),返回共享緩存,這可以減少內(nèi)存占用:
是時候來部署和測試代碼了!對于第一次運行,我們只需要創(chuàng)建一個go的二進制文件并且在集群外模式下運行它即可:
如要更改消息輸出,那么使用鏡像部署一個pod,該鏡像是沒有在當(dāng)前節(jié)點顯示的鏡像。
在基本的功能通過測試之后,接下來就是按照集群模式嘗試運行它了。為此我們必須先創(chuàng)建鏡像,定義它的Dockerfile:
并使用docker build創(chuàng)建一個鏡像,該命令將生成一個可用在Kubernetes中部署pod的鏡像?,F(xiàn)在你的應(yīng)用程序可以作為一個pod運行在Kubernetes集群上了。這里是一個部署定義的例子,在之前的截圖中,我使用了該例部署我們的應(yīng)用程序:
在本文中我們做了如下工作:
創(chuàng)建go項目
為項目添加client-go包的依賴項
創(chuàng)建用于和Kubernetes api通信的客戶端
定義一個用于監(jiān)控節(jié)點對象改變,并且一旦發(fā)生就執(zhí)行回調(diào)函數(shù)的Informer
在回調(diào)函數(shù)中實現(xiàn)一個實際的邏輯
在集群外運行二進制文件來測試代碼,并把它部署到集群中
關(guān)于如何在GO語言中使用Kubernetes API就分享到這里了,希望以上內(nèi)容可以對大家有一定的幫助,可以學(xué)到更多知識。如果覺得文章不錯,可以把它分享出去讓更多的人看到。