成人免费xxxxx在线视频软件_久久精品久久久_亚洲国产精品久久久_天天色天天色_亚洲人成一区_欧美一级欧美三级在线观看

使用Go構(gòu)建Kubernetes應(yīng)用

系統(tǒng) Linux
本篇文章介紹了如何使用kubernetes client-go實(shí)踐一個(gè)簡(jiǎn)單的與K8s交互過(guò)程。

 Kubernetes項(xiàng)目使用Go語(yǔ)言編寫(xiě),對(duì)Go api原生支持非常便捷。本篇文章介紹了如何使用kubernetes client-go實(shí)踐一個(gè)簡(jiǎn)單的與K8s交互過(guò)程。

kubernetes 的Go Client項(xiàng)目(client-go)

go client是k8s client中最古老的一個(gè),具有很多特性。Client-go 沒(méi)有使用Swagger生成器,它使用的是源于k8s項(xiàng)目中的源代碼生成工具,這個(gè)工具的目的是要生成k8s風(fēng)格的對(duì)象和序列化程序。

該項(xiàng)目是一組包的集合,該包能夠滿足從REST風(fēng)格的原語(yǔ)到復(fù)雜client的不同的編程需求。

RESTClient是一個(gè)基礎(chǔ)包,它使用api-machinery庫(kù)中的類型作為一組REST原語(yǔ)提供對(duì)API的訪問(wèn)。作為對(duì)RESTClient之上的抽象,_clientset_將是你創(chuàng)建k8s client工具的起點(diǎn)。它暴露了公開(kāi)化的API資源及其對(duì)應(yīng)的序列化。

注意:在 client-go中還包含了如discovery, dynamic, 和 scale這樣的包,雖然本次不介紹這些包,但是了解它們的能力還是很重要的。

一個(gè)簡(jiǎn)單的k8s client 工具

讓我們?cè)俅位仡櫸覀儗⒁獦?gòu)建的工具,來(lái)說(shuō)明go client的用法。pvcwatch是一個(gè)簡(jiǎn)單的命令行工具,它可以監(jiān)聽(tīng)集群中聲明的PVC容量。當(dāng)總數(shù)到達(dá)一個(gè)閾值的時(shí)候,他會(huì)采取一個(gè)action(在這個(gè)例子中是在屏幕上通知顯示)

你能在github上找到完整的例子

這個(gè)例子是為了展示k8s的go client的以下幾個(gè)方面:- 如何去連接 - 資源列表的檢索和遍歷 - 對(duì)象監(jiān)聽(tīng)

Setup

client-go支持Godep和dep作為vendor的管理程序,我覺(jué)得dep便于使用所以繼續(xù)使用dep。例如,以下是client-go v6.0和k8s API v1.9所需最低限度的Gopkg.toml。 

  1. [[constraint]]  
  2.   name = "k8s.io/api"  
  3.   version = "kubernetes-1.9.0"  
  4. [[constraint]]  
  5.   name = "k8s.io/apimachinery"  
  6.   version = "kubernetes-1.9.0"  
  7. [[constraint]]  
  8.   name = "k8s.io/client-go"  
  9.   version = "6.0.0" 

運(yùn)行dep ensure確保剩下的工作。

連接 API Server

我們Go client的第一步就是建立一個(gè)與API Server的連接。為了做到這一點(diǎn),我們要使用實(shí)體包中的clientcmd,如下代碼所示: 

  1. import (  
  2. ...  
  3.     "k8s.io/client-go/tools/clientcmd"  
  4.  
  5. func main() {  
  6.     kubeconfig :filepath.Join(  
  7.          os.Getenv("HOME"), ".kube", "config",  
  8.     )  
  9.     config, err :clientcmd.BuildConfigFromFlags("", kubeconfig)  
  10.     if err != nil {  
  11.         log.Fatal(err)  
  12.     }  
  13. ...  

_Client-go_通過(guò)提供實(shí)體功能來(lái)從不同的上下文中獲取你的配置,從而使之成為一個(gè)不重要的任務(wù)。

從config文件

正如上面的例子所做的那樣,你能從kubeconfig文件啟動(dòng)配置來(lái)連接API server。當(dāng)你的代碼運(yùn)行在集群之外的時(shí)候這是一個(gè)理想的方案。clientcmd.BuildConfigFromFlags("", configFile)

從集群

當(dāng)你的代碼運(yùn)行在這個(gè)集群中的時(shí)候,你可以用上面的函數(shù)并且不使用任何參數(shù),這個(gè)函數(shù)就會(huì)通過(guò)集群的信息去連接api server。

clientcmd.BuildConfigFromFlags("", "")

或者我們可以通過(guò)rest包來(lái)創(chuàng)建一個(gè)使用集群中的信息去配置啟動(dòng)的(譯者注:k8s里所有的Pod都會(huì)以Volume的方式自動(dòng)掛載k8s里面默認(rèn)的ServiceAccount,所以會(huì)用默認(rèn)的ServiceAccount的授權(quán)信息),如下: 

  1. import "k8s.io/client-go/rest"  
  2. ...  
  3. rest.InClusterConfig() 

創(chuàng)建一個(gè)clientset

我們需要?jiǎng)?chuàng)建一個(gè)序列化的client為了讓我們獲取API對(duì)象。在kubernetes包中的Clientset類型定義,提供了去訪問(wèn)公開(kāi)的API對(duì)象的序列化client,如下: 

  1. type Clientset struct {  
  2.     *authenticationv1beta1.AuthenticationV1beta1Client  
  3.     *authorizationv1.AuthorizationV1Client  
  4. ...  
  5.     *corev1.CoreV1Client  

一旦我們有正確的配置連接,我們就能使用這個(gè)配置去初始化一個(gè)clientset,如下: 

  1. func main() {  
  2.     config, err :clientcmd.BuildConfigFromFlags("", kubeconfig)  
  3.     ...  
  4.     clientset, err :kubernetes.NewForConfig(config)  
  5.     if err != nil {  
  6.         log.Fatal(err)  
  7.     }  

對(duì)于我們的例子,我們使用的是v1的API對(duì)象。下一步,我們要使用clientset通過(guò)CoreV1()去訪問(wèn)核心api資源,如下: 

  1. func main() {  
  2.     ...  
  3.     clientset, err :kubernetes.NewForConfig(config)  
  4.     if err != nil {  
  5.         log.Fatal(err)  
  6.     }  
  7.     api :clientset.CoreV1()  

你能在這里看到可以獲得clientsets。

獲取集群的PVC列表

我們對(duì)clientset執(zhí)行的最基本操作之一獲取存儲(chǔ)的API對(duì)象的列表。在我們的例子中,我們將要拿到一個(gè)namespace下面的pvc列表,如下: 

  1. import (  
  2. ...  
  3.     metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"  
  4.  
  5. func main() {  
  6.     var ns, label, field string  
  7.     flag.StringVar(&ns, "namespace", "", "namespace")  
  8.     flag.StringVar(&label, "l", "", "Label selector")  
  9.     flag.StringVar(&field, "f", "", "Field selector")  
  10. ...  
  11.     api :clientset.CoreV1()  
  12.     // setup list options  
  13.     listOptions :metav1.ListOptions{  
  14.         LabelSelector: label,   
  15.         FieldSelector: field,  
  16.     }  
  17.     pvcs, err :api.PersistentVolumeClaims(ns).List(listOptions)  
  18.     if err != nil {  
  19.         log.Fatal(err)  
  20.     }  
  21.     printPVCs(pvcs)  
  22. ...  

在上面的代碼中,我們使用ListOptions指定 label 和 field selectors (還有namespace)來(lái)縮小pvc列表的范圍,這個(gè)結(jié)果的返回類型是v1.PeristentVolumeClaimList。下面的這個(gè)代碼展示了我們?nèi)绾稳ケ闅v和打印從api server中獲取的pvc列表。 

  1. func printPVCs(pvcs *v1.PersistentVolumeClaimList) {  
  2.     template :"%-32s%-8s%-8s\n"  
  3.     fmt.Printf(template, "NAME", "STATUS", "CAPACITY")  
  4.     for _, pvc :range pvcs.Items {  
  5.         quant :pvc.Spec.Resources.Requests[v1.ResourceStorage]  
  6.         fmt.Printf(  
  7.             template,   
  8.             pvc.Name,   
  9.             string(pvc.Status.Phase),   
  10.             quant.String())  
  11.     }  

監(jiān)聽(tīng)集群中pvc

k8s的Go client框架支持為指定的API對(duì)象在其生命周期事件中監(jiān)聽(tīng)集群的能力,包括創(chuàng)建,更新,刪除一個(gè)指定對(duì)象時(shí)候觸發(fā)的CREATED,MODIFIED,DELETED事件。對(duì)于我們的命令行工具,我們將要監(jiān)聽(tīng)在集群中已經(jīng)聲明的PVC的總量。

對(duì)于某一個(gè)namespace,當(dāng)pvc的容量到達(dá)了某一個(gè)閾值(比如說(shuō)200Gi),我們將會(huì)采取某個(gè)動(dòng)作。為了簡(jiǎn)單起見(jiàn),我們將要在屏幕上打印個(gè)通知。但是在更復(fù)雜的實(shí)現(xiàn)中,可以使用相同的辦法觸發(fā)一個(gè)自動(dòng)操作。

啟動(dòng)監(jiān)聽(tīng)功能

現(xiàn)在讓我們?yōu)镻ersistentVolumeClaim這個(gè)資源通過(guò)Watch去創(chuàng)建一個(gè)監(jiān)聽(tīng)器。然后這個(gè)監(jiān)聽(tīng)器通過(guò)ResultChan從go的channel中訪問(wèn)事件通知。 

  1. func main() {  
  2. ...  
  3.     api :clientset.CoreV1()  
  4.     listOptions :metav1.ListOptions{  
  5.         LabelSelector: label,   
  6.         FieldSelector: field,  
  7.     }  
  8.     watcher, err :=api.PersistentVolumeClaims(ns). 
  9.        Watch(listOptions)  
  10.     if err != nil {  
  11.       log.Fatal(err)  
  12.     }  
  13.     ch :watcher.ResultChan()  
  14. ...  

循環(huán)事件

接下來(lái)我們將要處理資源事件。但是在我們處理事件之前,我們先聲明resource.Quantity類型的的兩個(gè)變量為maxClaimsQuant和totalClaimQuant來(lái)分別表示我們的申請(qǐng)資源閾值(譯者注:代表某個(gè)ns下集群中運(yùn)行的PVC申請(qǐng)的上限)和運(yùn)行總數(shù)。 

  1. import(  
  2.     "k8s.io/apimachinery/pkg/api/resource"  
  3.     ...  
  4.  
  5. func main() {  
  6.     var maxClaims string  
  7.     flag.StringVar(&maxClaims, "max-claims", "200Gi",   
  8.         "Maximum total claims to watch")  
  9.     var totalClaimedQuant resource.Quantity  
  10.     maxClaimedQuant :resource.MustParse(maxClaims)  
  11. ...  
  12.     ch :watcher.ResultChan()  
  13.     for event :range ch {  
  14.         pvc, ok :event.Object.(*v1.PersistentVolumeClaim)  
  15.         if !ok {  
  16.             log.Fatal("unexpected type")  
  17.         }  
  18.         ...  
  19.     }  

在上面的for-range循環(huán)中,watcher的channel用于處理來(lái)自服務(wù)器傳入的通知。每個(gè)事件賦值給變量event,并且event.Object的類型被聲明為PersistentVolumeClaim類型,所以我們能從中提取出來(lái)。

處理ADDED事件

當(dāng)一個(gè)新的PVC創(chuàng)建的時(shí)候,event.Type的值被設(shè)置為watch.Added。然后我們用下面的代碼去獲取新增的聲明的容量(quant),將其添加到正在運(yùn)行的總?cè)萘恐校╰otalClaimedQuant)。最后我們?nèi)z查是否當(dāng)前的容量總值大于當(dāng)初設(shè)定的最大值(maxClaimedQuant),如果大于的話我們就觸發(fā)一個(gè)事件。 

  1. import(  
  2.     "k8s.io/apimachinery/pkg/watch"  
  3.     ...  
  4.  
  5. func main() {  
  6. ...  
  7.     for event :range ch {  
  8.         pvc, ok :event.Object.(*v1.PersistentVolumeClaim)  
  9.         if !ok {  
  10.             log.Fatal("unexpected type")  
  11.         }  
  12.         quant :pvc.Spec.Resources.Requests[v1.ResourceStorage]  
  13.         switch event.Type {  
  14.             case watch.Added:  
  15.                 totalClaimedQuant.Add(quant)  
  16.                 log.Printf("PVC %s added, claim size %s\n",  
  17.                     pvc.Name, quant.String())  
  18.                 if totalClaimedQuant.Cmp(maxClaimedQuant) == 1 {  
  19.                     log.Printf(  
  20.                         "\nClaim overage reached: max %s at %s",  
  21.                         maxClaimedQuant.String(),  
  22.                         totalClaimedQuant.String())  
  23.                     // trigger action  
  24.                     log.Println("*** Taking action ***")  
  25.                 }  
  26.             }  
  27.         ...  
  28.         }  
  29.     }  

處理DELETED事件

代碼也會(huì)在PVC被刪除的時(shí)候做出反應(yīng),它執(zhí)行相反的邏輯以及把被刪除的這個(gè)PVC申請(qǐng)的容量在正在運(yùn)行的容量的總值里面減去。 

  1. func main() {  
  2. ...  
  3.     for event :range ch {  
  4.         ...  
  5.         switch event.Type {  
  6.         case watch.Deleted:  
  7.             quant :pvc.Spec.Resources.Requests[v1.ResourceStorage]  
  8.             totalClaimedQuant.Sub(quant)  
  9.             log.Printf("PVC %s removed, size %s\n",   
  10.                pvc.Name, quant.String())  
  11.             if totalClaimedQuant.Cmp(maxClaimedQuant) <= 0 { 
  12.                 log.Printf("Claim usage normal: max %s at %s",  
  13.                     maxClaimedQuant.String(),  
  14.                     totalClaimedQuant.String(),  
  15.                 )  
  16.                 // trigger action  
  17.                 log.Println("*** Taking action ***")  
  18.             }  
  19.         }  
  20.         ...  
  21.     }  

運(yùn)行程序

當(dāng)程序在一個(gè)運(yùn)行中的集群被執(zhí)行的時(shí)候,首先會(huì)列出PVC的列表。然后開(kāi)始監(jiān)聽(tīng)集群中新的PersistentVolumeClaim事件。 

  1. $> ./pvcwatch  
  2. Using kubeconfig:  /Users/vladimir/.kube/config  
  3. --- PVCs ----  
  4. NAME                            STATUS  CAPACITY  
  5. my-redis-redis                  Bound   50Gi  
  6. my-redis2-redis                 Bound   100Gi  
  7. -----------------------------  
  8. Total capacity claimed: 150Gi  
  9. -----------------------------  
  10. --- PVC Watch (max claims 200Gi) ----  
  11. 2018/02/13 21:55:03 PVC my-redis2-redis added, claim size 100Gi  
  12. 2018/02/13 21:55:03  
  13. At 50.0% claim capcity (100Gi/200Gi)  
  14. 2018/02/13 21:55:03 PVC my-redis-redis added, claim size 50Gi  
  15. 2018/02/13 21:55:03  
  16. At 75.0% claim capcity (150Gi/200Gi) 

下面讓我們部署一個(gè)應(yīng)用到集群中,這個(gè)應(yīng)用會(huì)申請(qǐng)75Gi容量的存儲(chǔ)。(例如,讓我們通過(guò)helm去部署一個(gè)實(shí)例influxdb)。 

  1. helm install --name my-influx \  
  2. --set persistence.enabled=true,persistence.size=75Gi stable/influxdb 

正如下面你看到的,我們的工具立刻反應(yīng)出來(lái)有個(gè)新的聲明以及一個(gè)警告因?yàn)楫?dāng)前的運(yùn)行的聲明總量已經(jīng)大于我們?cè)O(shè)定的閾值。 

  1. --- PVC Watch (max claims 200Gi) ----  
  2. ...  
  3. 2018/02/13 21:55:03  
  4. At 75.0% claim capcity (150Gi/200Gi)  
  5. 2018/02/13 22:01:29 PVC my-influx-influxdb added, claim size 75Gi  
  6. 2018/02/13 22:01:29  
  7. Claim overage reached: max 200Gi at 225Gi  
  8. 2018/02/13 22:01:29 *** Taking action ***  
  9. 2018/02/13 22:01:29  
  10. At 112.5% claim capcity (225Gi/200Gi) 

相反,從集群中刪除一個(gè)PVC的時(shí)候,該工具會(huì)相應(yīng)展示提示信息。 

  1. ...  
  2. At 112.5% claim capcity (225Gi/200Gi)  
  3. 2018/02/14 11:30:36 PVC my-redis2-redis removed, size 100Gi  
  4. 2018/02/14 11:30:36 Claim usage normal: max 200Gi at 125Gi  
  5. 2018/02/14 11:30:36 *** Taking action *** 

總結(jié)

這篇文章是進(jìn)行的系列的一部分,使用Go語(yǔ)言的官方k8s客戶端與API server進(jìn)行交互。和以前一樣,這個(gè)代碼會(huì)逐步的去實(shí)現(xiàn)一個(gè)命令行工具去監(jiān)聽(tīng)指定namespace下面的PVC的大小。這個(gè)代碼實(shí)現(xiàn)了一個(gè)簡(jiǎn)單的監(jiān)聽(tīng)列表去觸發(fā)從服務(wù)器返回的資源事件。 

 

責(zé)任編輯:龐桂玉 來(lái)源: 馬哥Linux運(yùn)維
相關(guān)推薦

2023-12-26 00:58:53

Web應(yīng)用Go語(yǔ)言

2025-05-06 08:09:02

2022-10-27 18:03:04

GogRPC云原生

2021-04-16 20:43:18

Go區(qū)塊鏈編程

2024-05-17 09:00:45

SwiftUIvisionOS

2014-10-15 11:01:02

Web應(yīng)用測(cè)試應(yīng)用

2025-04-18 08:37:09

2025-02-04 13:53:18

NixGogRPC

2021-12-07 10:04:34

Azure Kuber場(chǎng)景應(yīng)用

2023-11-03 13:20:13

Kubernetes

2023-05-06 08:00:00

KubernetesK8s數(shù)據(jù)服務(wù)自動(dòng)化

2023-12-01 08:01:33

GoValidator

2023-12-14 08:01:08

事件管理器Go

2023-12-01 07:06:14

Go命令行性能

2025-04-28 01:22:00

2010-06-13 09:22:37

jQuery

2024-01-05 07:41:34

OpenLLM大語(yǔ)言模型LLM

2009-01-03 14:54:36

ibmdwWebSphere

2021-11-07 14:29:13

ChromeAPI 藍(lán)牙

2023-01-16 00:12:20

Go語(yǔ)言Web
點(diǎn)贊
收藏

51CTO技術(shù)棧公眾號(hào)

主站蜘蛛池模板: 欧美精品一区二区在线观看 | 亚洲天堂av网 | 国产精品美女久久久久久久网站 | 国产乱码精品1区2区3区 | 亚洲图片一区二区三区 | 美女爽到呻吟久久久久 | 亚洲综合色视频在线观看 | 国产精品视频一区二区三区 | 99国产精品久久久 | 免费精品久久久久久中文字幕 | 亚洲色图综合 | a欧美| 国产成人精品网站 | 久草综合在线视频 | a级毛片免费高清视频 | 欧洲精品码一区二区三区免费看 | 国产二区在线播放 | 91精品久久久久久久久久入口 | 久久久精品天堂 | 91高清在线| 亚洲精品久久久久久一区二区 | 日韩一区二区精品 | 97免费在线视频 | 国产一区二区三区在线看 | 久99久视频 | 做a视频 | 成人精品系列 | 激情五月综合网 | 久久伊人亚洲 | 日韩一二区在线观看 | 亚洲福利 | 天天插日日操 | 自拍偷拍亚洲视频 | 日韩一区二区三区av | 麻豆国产精品777777在线 | 久久精品亚洲国产 | 国精产品一区一区三区免费完 | 一区二区三区国产在线观看 | 久久国| 中文字幕人成乱码在线观看 | 九九热精品在线视频 |