client-go獲取k8s集群內部連接,實現deployment的增刪改查


一開始寫了一個client-java版本的,但是java放在k8s集群上跑需要裝jvm而且java的包比較大,client-go版本更適合主機端,下面是整個實現

原文地址:https://www.cnblogs.com/darope/p/12097013.html

說明:k8s官方維護的客戶端庫只有go和python版本,所以為了穩定性建議使用這兩個版本,考慮到k8s是go實現的,我這里也就選擇go版本。至於客戶端連接k8s集群,在具體的生產環境中不建議外部連接訪問。原因一是生產環境中的k8s配置文件重要,一般如果對接其他公司的業務,雖然有鑒權,人家也不願意把配置文件拷貝給你,因為有了集群的配置文件,外部的這個項目的權限就很大,相當於給集群開了一個隱患口子,要知道k8s集群中有可能是該公司的整個業務。原因二集群內部訪問不需要那么復雜的鑒權,反而更省事點,只需要寫個小應用部署到k8s集群中即可。應用已經在集群內部了,就沒有鑒權的概念了,其他三方服務只需要調用小應用的api即可操作k8s。

1. 構建goWeb小應用導入依賴:

  a. 不管是走go的代理還是其他辦法,這里默認能搭建goWeb項目,並且能夠使用go mod tidy拉取包。

  b. 按照官方文檔導入依賴這里我用的是0.17.0版本,此處有坑,不僅僅這個版本有這個坑,其他版本很有可能也有,完全正常的導入但是會存在jar包之間版本不一致問題,這個問題會導致go build無法構建,是官方自身的兼容問題,報錯信息為:

  # k8s.io/client-go/rest
  ../../../../goworkspace/pkg/mod/k8s.io/client-go@v11.0.0+incompatible/rest/request.go:598:31: not enough arguments in call to watch.NewStreamWatcher
  have (*versioned.Decoder)
  want (watch.Decoder, watch.Reporter)

  c. 可以嘗試手動替換k8s.io/apimachinery@v0.17.0為k8s.io/apimachinery@release-1.14來解決。在終端執行# go mod download -json k8s.io/apimachinery@release-1.14最終gomod的關於k8s的所有依賴文件如下所示:

 1 require (    
 2   k8s.io/api v0.17.0 // indirect
 3   k8s.io/apimachinery v0.17.0
 4   k8s.io/client-go v11.0.0+incompatible
 5   k8s.io/utils v0.0.0-20191114184206-e782cd3c129f // indirect
 6   sigs.k8s.io/yaml v1.1.0 // indirect
 7  8 
 9 replace (
10     k8s.io/api => k8s.io/api v0.0.0-20191004102349-159aefb8556b
11     k8s.io/apiextensions-apiserver => k8s.io/apiextensions-apiserver v0.0.0-20191004105649-b14e3c49469a
12     k8s.io/apimachinery => k8s.io/apimachinery v0.0.0-20191004074956-c5d2f014d689
13     sigs.k8s.io/controller-runtime => sigs.k8s.io/controller-runtime v0.3.0
14 )

這里參考博客為:https://segmentfault.com/a/1190000021077653?utm_source=tag-newest

最終go build就沒問題了。

2. 配置集群內部訪問的客戶端

  a. 內部訪問k8s客戶端使用defaultClient即可,但是這里第二個坑,client-go里面默認的客戶端尋找的是~/.kube下的config文件,並且需要集群的ip和port,也就是說需要人為的去配置環境變量以便滿足ip和port的寫入需要,需要提前把config放到~/.kube下。恰巧客戶的環境也沒配置環境變量,也沒把config拷到響應的目錄下,只能找其他辦法。由於之前寫過一個java的客戶端調用,里面的defaultClient是可以訪問到的。所以看下java中的尋找路徑,發現了一個上下文路徑的東西。最終改造client-go客戶端信息如下:

 1 package utils
 2 
 3 import (
 4     "k8s.io/client-go/kubernetes"
 5     "k8s.io/client-go/tools/clientcmd"
 6     "log"
 7     "os"
 8     "path/filepath"
 9 )
10 
11 // 獲取集群內部k8s客戶端
12 func K8sClient() *kubernetes.Clientset {
13     // 使用當前上下文環境
14     kubeconfig := filepath.Join(
15         os.Getenv("KUBECONFIG"),
16     )
17     config, err := clientcmd.BuildConfigFromFlags("", kubeconfig)
18     if err != nil {
19         log.Fatal(err)
20     }
21     // 根據指定的 config 創建一個新的 clientSet
22     clientSet, err := kubernetes.NewForConfig(config)
23     if err != nil {
24         panic(err.Error())
25     }
26     return clientSet
27 }

其中os.Getenv就是拿k8s的默認配置文件,只要該應用部署在k8s集群環境中,這個客戶端就可以正確返回和使用。

3. pod列表,deployment列表,deployment擴縮容等實現

 1     // 拿客戶端    
 2     clientSet := utils.K8sClient()
 3     //獲取PODS列表,不傳namespace默認查全部
 4     pods, err := clientSet.CoreV1().Pods(nameSpace).List(metav1.ListOptions{})
 5     if err != nil {
 6         log.Println(err.Error())
 7     }
 8     // deployment列表獲取
 9     deploymentsClient := clientSet.AppsV1().Deployments(nameSpace)
10     deployments, err := deploymentsClient.List(metav1.ListOptions{})
11     if err != nil {
12         panic(err)
13     }
14     // deployment詳情獲取
15     deploymentsClient := clientSet.AppsV1().Deployments(nameSpace)
16     deployment, err := deploymentsClient.Get(deploymentName, metav1.GetOptions{})
17     if err != nil {
18         panic(err)
19     }
20     // 擴縮容,num是擴縮容至多少
21   deploymentsClient := clientSet.AppsV1().Deployments(nameSpace)
22    retryErr := retry.RetryOnConflict(retry.DefaultRetry, func() error {
23         result, getErr := deploymentsClient.Get(deploymentName, metav1.GetOptions{})
24         if getErr != nil {
25             panic(fmt.Errorf("失敗,確認之后再試一下唄~: %v", getErr))
26         }
27         result.Spec.Replicas = int32Ptr(int32(num))
28         _, updateErr := deploymentsClient.Update(result)
29         return updateErr
30     })
31     if retryErr != nil {
32         panic(fmt.Errorf("擴容出現問題,請檢查調用~: %v", retryErr))
33     }

親測可用~,點個贊讓跟多人看到,避免反復踩坑。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM