如何在GO語言中使用Kubernetes API?

來源:互聯網
上載者:User

標籤:GO   KUbernetes   Kubernetes API   微服務   控制器   

Rancher Labs首席軟體工程師Alena Prokharchyk受邀在2017年12月6-8日的CNCF主辦的Kubernetes領域頂級盛會KubeCon + CloudNativeCon 2017北美峰會上進行演講,本文由演講內容整理而成。

 

隨著Kubernetes越來越受歡迎,圍繞它的整合和監控服務的數量也在不斷增長。Golang編寫的所有此類服務的關鍵組件是kubernetes / client-go——一個用於與Kubernetes叢集API通訊的軟體包。在本文中,我們將討論client-go使用的基本知識,以及如何為開發人員節約編寫實際應用程式邏輯所需的時間。我們還將展示使用該軟體包的最佳實務,並從每天與Kubernetes進行整合工作的開發人員的角度,分享我們已有的經驗。內容將包括: 

●  叢集中的用戶端認證 vs. 叢集外的用戶端認證

●   基本欄表,使用client-go去建立和刪除Kubernetes對象的操作

●  如何使用ListWatch和Informers監視K8s事件並做出反應

●  如何管理軟體包依賴

 

Kubernetes是一個平台

Kubernetes有很多受歡迎的地方。使用者喜歡它的豐富功能、穩定性和效能。對貢獻者來說,Kubernetes開源社區不僅規模龐大,還易於上手、反饋迅速。而真正讓Kubernetes吸引了第三方開發人員的是它的可擴充性。該項目提供了很多方式來添加新功能、擴充現有功能而且不會中斷主程式碼程式庫。正是這些,使得Kubernetes發展成為了一個平台。

這裡有一些方式來擴充Kubernetes:

所示,你可以發現每個Kubernetes叢集組件無論是Kubelet還是API伺服器,都可以以某種方式進行擴充。今天我們將重點介紹一種“自訂控制器”的方式,從現在起我將它稱為Kubernetes控制器(Kubernetes Controller),或者簡單地稱為控制器(Controller)。


Kubernetes控制器究竟是什麼


控制器最常見的定義是:使得系統的目前狀態達到所期望的狀態的代碼。但這究竟是什麼意思呢?我們以Ingress控制器為例。Ingress是一個Kubernetes資源,它能夠對叢集中服務的外部存取進行定義。通常採用HTTP並且有負載平衡支援。然而Kubernetes的核心代碼中並沒有ingress的實現。第三方控制器的實現將包含:


1.      監控ingress/services/endpoint 資源的事件(建立、更新、刪除)

2.      程式內部或外部的負載平衡器

3.      使用負載平衡器的地址來更新Ingress


“所期望的狀態”在Ingress這裡指的是IP地址指向運行著的負載平衡器,該均衡器由使用者根據ingress規範定義的規則實現。並且由外部Ingress控制器負責將ingress資源轉移到這一狀態。

對相同的資源,控制器的實現以及部署他們的方式也可能會有所不同。你可以選擇nginx控制器並將其部署到叢集中的每個節點上作為守護進程集(Daemon Set),也可以選擇在Kubernetes叢集外部運行ingress控制器並且對F5編程作為負載平衡器。這裡沒有嚴格的規定,Kubernetes就是如此靈活。


Client-go


這裡有幾種獲得Kubernetes叢集及其資源相關資訊的方法,你可以使用Dashboard、kubectl或者使用對Kubernetes API的編程式訪問來實現。Client-go所有用Go語言編寫的工具中使用最為廣泛的庫,還有許多其他語言的版本(java、python等)。如果你還沒自己寫過控制器,我推薦你首先去嘗試go/client-go。Kubernetes是用Go編寫的,而且我發現使用和主專案相同的語言來開發外掛程式會更加方便。


我們來搭建吧…


要熟悉相關的平台和工具,最好的辦法就是去實踐,去實現一些東西。我們從簡單入手,先實現一個如下的控制器:

1.      監控Kubernetes節點

2.      當節點上的鏡像佔用儲存空間時進行警報,並且可以更改


這部分的實現,源碼可以在這裡找到:https://github.com/alena1108/kubecon2017


基本流程


設定項目

作為一名開發人員,我和Rancher Labs的同事們更願意使用輕便簡易的工具,在這裡我將分享3個我最喜歡的工具,它們將協助我們完成第一個項目。

1.      go-skel – Go語言的微服務skeleton,只需執行run ./skel.sh test123即可,它會為新的go項目test123建立skeleton。

2.      trash – Go語言的供應商管理工具。實際上這兒有很多依賴項管理工具,但是在臨時依賴項管理方面,trash使用起來非常出色,而且簡單。

3.      dapper – 在一致性環境中對任何現有構建工具進行封裝的一種工具


添加client-go作為一個依賴項

為了方便使用client-go的代碼,我們必須要將其設定為項目的依賴項。將它添加到vendor.conf檔案中:

接著運行trash。它會將vendor.conf中定義的所有依賴項都拉到項目的vendor檔案夾中。在這裡需要確保client-go與你叢集對應的Kubernetes版本是相容的。


建立一個用戶端

在建立與Kubernetes API通訊的用戶端之前,我們必須要先決定如何運行我們的工具:是在Kubetnetes叢集內部還是外部。當應用程式在叢集內部運行時,對它進行容器化,部署成為Kubernetes pod。它還提供了一些額外的功能:你可以選擇部署它的方式(Deamon set運行在每個節點上,或者作為n個副本的部署),配置針對它的健全狀態檢查等等。當應用程式在叢集外部運行時,就需要自己來管理它。下面的配置可以讓我們的工具變得更靈活,並且支援基於config flag定義用戶端的兩種方式:

我們將在調試應用程式時使用叢集外部啟動並執行方式,這樣你不需要每次都構建鏡像並且將其重新部署成Kubernetes pod。在測試好應用程式後,我們就可以構建鏡像並將其部署到叢集中。

正如在中看到的那樣,正在構建配置,並將其傳遞到kubernetes.NewForConfig來產生用戶端。


使用基本的CRUDs

我們的工具需要監控節點。在實現邏輯流程之前,我們先來熟悉使用client-go執行CRUD操作:

上面的展示了:

1.      List節點minikube,是經過FieldSelector過濾器實現的

2.      用新的標註來更新節點

3.      使用gracePerios=10秒指令刪除節點—意思是從該命令執行後10秒才會執行刪除操作

上面所有的步驟都是使用我們之前建立的使用者集(clientset)進行的。

我們還需要節點上鏡像的相關資訊;它可以通過訪問相應的欄位來檢索:

使用Informer來進行監控/通知

現在我們知道了如何從Kubernetes APIs中擷取節點並從中得到鏡像資訊。那麼我們該如何監控鏡像大小的變化呢?最簡單的方法是周期性輪詢節點,計算當前的鏡像儲存容量,並將其和先前輪詢的結果比較。這裡的不足之處在於:無論節點是否發生變化,我們執行的列表調用都會擷取所有的節點,這可能會很費資源——特別是當輪詢間隔很短的時候。而我們真正想要實現的是—在節點發生變化時得到通知,只有在這之後才執行我們的邏輯流程。這些就是client-go的Informer來做的。

在這個例子中,我們經過watchList指令為節點對象建立Informer來監控節點,設定物件類型為api.Node和30秒的同步周期來周期性地輪詢節點,無論節點是否發生改變——這種方式在更新事件出於某種原因發生終止時可以很好的進行撤回。在最後一個參數,我們傳遞了2個回呼函數——handleNodeAdd和handleNodeUpdate。這些回呼函數具有實際的邏輯,並且在節點上的鏡像佔用儲存發生改變時觸發。NewInformer返回2個對象——controller和store。一旦controller啟動,將會開始對node.update和node.add的監控,並且調用回呼函數。這部分代碼的儲存區位於記憶體緩衝中,由informer負責更新,另外你可以在緩衝區中擷取節點對象而不用直接調用Kubernetes APIs:

我們的項目中只有一個控制器,使用常規的Informer就足夠了。不過,如果未來你的項目最終同一個對象擁有了多個控制器,我建議你使用SharedInformer。這樣一來你不用再一個一個為每個控制器配上Informer,只需要註冊一個Shared informer即可,並且讓每個控制器註冊自己的一組回呼函數,返回共用快取,這可以減少記憶體佔用:


部署時間

是時候來部署和測試代碼了!對於第一次運行,我們只需要建立一個go的二進位檔案並且在叢集外模式下運行它即可:

如要更改訊息輸出,那麼使用鏡像部署一個pod,該鏡像是沒有在當前節點顯示的鏡像。

在基本的功能通過測試之後,接下來就是按照叢集模式嘗試運行它了。為此我們必須先建立鏡像,定義它的Dockerfile:

並使用docker build建立一個鏡像,該命令將產生一個可用在Kubernetes中部署pod的鏡像。現在你的應用程式可以作為一個pod運行在Kubernetes叢集上了。這裡是一個部署定義的例子,在之前的中,我使用了該例部署我們的應用程式:

在本文中我們做了如下工作:

1.      建立go項目

2.      為項目添加client-go包的依賴項

3.      建立用於和Kubernetes api通訊的用戶端

4.      定義一個用於監控節點對象改變,並且一旦發生就執行回呼函數的Informer

5.      在回呼函數中實現一個實際的邏輯

6.      在叢集外運行二進位檔案來測試代碼,並把它部署到叢集中


如何在GO語言中使用Kubernetes API?

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.