使用client-go連接k8s集群


說明: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的所有依賴文件如下所示:

require (
  k8s.io/api v0.17.0 // indirect
  k8s.io/apimachinery v0.17.0
  k8s.io/client-go v11.0.0+incompatible
  k8s.io/utils v0.0.0-20191114184206-e782cd3c129f // indirect
  sigs.k8s.io/yaml v1.1.0 // indirect
)

replace (
    k8s.io/api => k8s.io/api v0.0.0-20191004102349-159aefb8556b
    k8s.io/apiextensions-apiserver => k8s.io/apiextensions-apiserver v0.0.0-20191004105649-b14e3c49469a
    k8s.io/apimachinery => k8s.io/apimachinery v0.0.0-20191004074956-c5d2f014d689
    sigs.k8s.io/controller-runtime => sigs.k8s.io/controller-runtime v0.3.0
)

2.使用 client-go 在 k8s 集群外操作資源:

代碼如下:

package main

/*
參考:
https://studygolang.com/articles/31750
https://github.com/owenliang/k8s-client-go
https://yuerblog.cc/2018/12/12/k8s-client-go-setup-and-basic-usage/
https://www.cnblogs.com/darope/p/12097013.html
https://www.cnblogs.com/wuchangblog/p/14208555.html
https://www.cnblogs.com/Dev0ps/p/14919838.html
https://www.cnblogs.com/rancherlabs/p/11888065.html
*/


import (
    "flag"
    "fmt"
    "os"
    "path/filepath"

    metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
    "k8s.io/client-go/kubernetes"
    "k8s.io/client-go/rest"
    "k8s.io/client-go/tools/clientcmd"
)

// 2.定義一個函數用來在操作系統中獲取目錄路徑
func homeDir() string{
    if h:=os.Getenv("HOME");h!=""{
        return h
    }
    return os.Getenv("USERPROFILE")  //windows
}

func main(){
    // 1.聲明三個變量
    var err error
    var config *rest.Config
    // inCluster(Pod).kuberconfig(kubectl)
    var kubeconfig *string


    //3.在k8s的環境中kubectl配置文件一般存放在用戶目錄的.kube文件中
    if home:=homeDir();home!=""{
        kubeconfig=flag.String("kubeconfig",filepath.Join(home,".kube","config"),"(可選)kubeconfig 文件的絕對路徑")
        fmt.Println(home)
    }else{
        kubeconfig=flag.String("kubeconfig","","kubeconfig 文件的絕對路徑")
        fmt.Println(kubeconfig)
        fmt.Println("##################")
    }
    flag.Parse()
    // 4.創建集群配置,首先使用 inCluster 模式(需要區配置對應的RBAC 權限,默認的sa是default-->是沒有獲取deployment的List權限)
    if config,err =rest.InClusterConfig();err!=nil{
        // 使用Kubeonfig文件配置集群配置Config對象
        if config,err=clientcmd.BuildConfigFromFlags("",*kubeconfig);err!=nil{
            panic(err.Error())
        }
    }

    //5.在獲取到使用Kubeonfig文件配置的Config對象之后,創建Clientset對象,並對其進行操作
    // 已經獲得了rest.Config對象
    // 創建Clientset對象
    clientset,err:=kubernetes.NewForConfig(config)
    if err !=nil{
        panic(err.Error())
    }

    // 6.就可以使用Clientset對象獲取資源對象,進行增刪改查
    // 想要獲取default命令空間下面的Deployment的列表
    //deployment,err:=clientset.AppsV1().Deployments("default").List(metav1.ListOptions{})
    deployment,err:=clientset.AppsV1().Deployments("kubernetes-dashboard").List(metav1.ListOptions{})
    if err!=nil{
        panic(err.Error())
    }

    for idx,deploy:=range deployment.Items{
        fmt.Printf("%d-%s\n",idx,deploy.Name)
    }

}

 

參考:

https://studygolang.com/articles/31750

https://www.cnblogs.com/darope/p/12097013.html


免責聲明!

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



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