日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

client-go实战之三:Clientset

發布時間:2023/12/16 编程问答 25 豆豆
生活随笔 收集整理的這篇文章主要介紹了 client-go实战之三:Clientset 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

歡迎訪問我的GitHub

這里分類和匯總了欣宸的全部原創(含配套源碼):https://github.com/zq2599/blog_demos

系列文章鏈接

  • client-go實戰之一:準備工作
  • client-go實戰之二:RESTClient
  • client-go實戰之三:Clientset
  • client-go實戰之四:dynamicClient
  • client-go實戰之五:DiscoveryClient
  • 關于Clientset

    • 本篇是《client-go實戰》系列的第三篇,前文學習了最基礎的客戶端Restclient,盡管咱們實戰的需求很簡單(獲取指定namespace下所有pod的信息),但還是寫了不少代碼,如下圖,各種設置太麻煩,例如api的path、Group、Version、返回的數據結構、編解碼工具等:

    • 如果業務代碼中,需要操作kubernetes資源的代碼都寫成上圖的樣子,相信您是難以忍受的,應該會做一些封裝以簡化代碼,不過client-go已經給出了簡化版客戶端,就省去了咱們自己動手的麻煩,也就是本文的主題:Clientset

    本篇概覽

    • 本篇目標是學習如何使用Clientset,因此毫無難度,咱們先來個源碼速讀,快速搞清楚Clientset到底是啥,然后確認需求,最后快速編碼和驗證就完事兒了;

    源碼速度

    • 之所以是速讀而非精度,是因為Clientset內容簡單容易理解,快速掌握其原理即可用于實戰;
    • Clientset源碼閱讀的切入點就是其名字中的set,這是個集合,里面有很多東西,看一下Clientset數據結構的源碼(限于篇幅只展示了一部分):
    type Clientset struct {*discovery.DiscoveryClientadmissionregistrationV1 *admissionregistrationv1.AdmissionregistrationV1ClientadmissionregistrationV1beta1 *admissionregistrationv1beta1.AdmissionregistrationV1beta1ClientinternalV1alpha1 *internalv1alpha1.InternalV1alpha1ClientappsV1 *appsv1.AppsV1ClientappsV1beta1 *appsv1beta1.AppsV1beta1ClientappsV1beta2 *appsv1beta2.AppsV1beta2ClientauthenticationV1 *authenticationv1.AuthenticationV1Client...
    • 如果您還沒有理解上述源碼的含義,再請看下圖,左邊是kubernetes的Group、Version信息,右邊依舊是Clientset數據結構的源碼,通過箭頭可見:kubernetes的Group和Version的每個組合,都對應Clientset數據結構的一個字段
    • Clientset果然名副其實,是所有Group和Version組合對象的集合,不過Group和Version組合對象到底是啥呢?以appsV1字段為例,去看看其類型appsv1.AppsV1Client,如下圖,AppsV1Client只有一字段,就是咱們熟悉的restClient,所以RESTClient是Clientset的基礎,這話沒毛病,另外注意紅框2中的Deployments方法,返回的是DeploymentInterface接口實現:
    • 順藤摸瓜去看DeploymentInterface,打開deployment.go文件后真相大白,接口定義的和實現一目了然:
    • 挑一個接口實現的代碼看看,就選新建deployment的方法吧,如下,和我們使用RESTClient編碼差不多:
    func (c *deployments) Create(ctx context.Context, deployment *v1.Deployment, opts metav1.CreateOptions) (result *v1.Deployment, err error) {result = &v1.Deployment{}err = c.client.Post().Namespace(c.ns).Resource("deployments").VersionedParams(&opts, scheme.ParameterCodec).Body(deployment).Do(ctx).Into(result)return }
    • 至此,您對Clientset應該心里有數了:其實就是把我們使用RESTClient操作資源的代碼按照Group和Version分類再封裝而已,這不像技術活,更像體力活—所以,這種體力活是誰做的呢?如下圖紅框所示,源碼中已經注明這些代碼是工具client-gen自動生成的:
    • 至此,Clientset的源碼速度就算完成了,咱們已經知道了Clientset的內幕,接下來開始嘗試使用它;

    需求確認

    • 本次編碼實戰的需求如下:
    • 寫一段代碼,檢查用戶輸入的operate參數,該參數默認是create,也可以接受clean;
    • 如果operate參數等于create,就執行以下操作:
  • 新建名為test-clientset的namespace
  • 新建一個deployment,namespace為test-clientset,鏡像用tomcat,副本數為2
  • 新建一個service,namespace為test-clientset,類型是NodePort
    • 如果operate參數等于clean,就刪除create操作中創建的service、deployment、namespace等資源:
    • 以上需求使用Clientset客戶端實現,完成后咱們用瀏覽器訪問來驗證tomcat是否正常;

    源碼下載

    • 本篇實戰中的源碼可在GitHub下載到,地址和鏈接信息如下表所示(https://github.com/zq2599/blog_demos):
    名稱鏈接備注
    項目主頁https://github.com/zq2599/blog_demos該項目在GitHub上的主頁
    git倉庫地址(https)https://github.com/zq2599/blog_demos.git該項目源碼的倉庫地址,https協議
    git倉庫地址(ssh)git@github.com:zq2599/blog_demos.git該項目源碼的倉庫地址,ssh協議
    • 這個git項目中有多個文件夾,client-go相關的應用在client-go-tutorials文件夾下,如下圖紅框所示:
    • client-go-tutorials文件夾下有多個子文件夾,本篇對應的源碼在clientsetdemo目錄下,如下圖紅框所示:

    編碼

    • 新建文件夾restclientdemo,在里面執行以下命令,新建module:
    go mod init clientsetdemo
    • 添加k8s.io/api和k8s.io/client-go這兩個依賴,注意版本要匹配kubernetes環境:
    go get k8s.io/api@v0.20.0 go get k8s.io/client-go@v0.20.0
    • 新建main.go,內容如下,已經都添加了詳細的注釋,就不贅述了:
    package mainimport ("context""flag""fmt"appsv1 "k8s.io/api/apps/v1"apiv1 "k8s.io/api/core/v1"metav1 "k8s.io/apimachinery/pkg/apis/meta/v1""k8s.io/client-go/kubernetes""k8s.io/client-go/tools/clientcmd""k8s.io/client-go/util/homedir""k8s.io/utils/pointer""path/filepath" )const (NAMESPACE = "test-clientset"DEPLOYMENT_NAME = "client-test-deployment"SERVICE_NAME = "client-test-service" )func main() {var kubeconfig *string// home是家目錄,如果能取得家目錄的值,就可以用來做默認值if home:=homedir.HomeDir(); home != "" {// 如果輸入了kubeconfig參數,該參數的值就是kubeconfig文件的絕對路徑,// 如果沒有輸入kubeconfig參數,就用默認路徑~/.kube/configkubeconfig = flag.String("kubeconfig", filepath.Join(home, ".kube", "config"), "(optional) absolute path to the kubeconfig file")} else {// 如果取不到當前用戶的家目錄,就沒辦法設置kubeconfig的默認目錄了,只能從入參中取kubeconfig = flag.String("kubeconfig", "", "absolute path to the kubeconfig file")}// 獲取用戶輸入的操作類型,默認是create,還可以輸入clean,用于清理所有資源operate := flag.String("operate", "create", "operate type : create or clean")flag.Parse()// 從本機加載kubeconfig配置文件,因此第一個參數為空字符串config, err := clientcmd.BuildConfigFromFlags("", *kubeconfig)// kubeconfig加載失敗就直接退出了if err != nil {panic(err.Error())}// 實例化clientset對象clientset, err := kubernetes.NewForConfig(config)if err!= nil {panic(err.Error())}fmt.Printf("operation is %v\n", *operate)// 如果要執行清理操作if "clean"==*operate {clean(clientset)} else {// 創建namespacecreateNamespace(clientset)// 創建deploymentcreateDeployment(clientset)// 創建servicecreateService(clientset)} }// 清理本次實戰創建的所有資源 func clean(clientset *kubernetes.Clientset) {emptyDeleteOptions := metav1.DeleteOptions{}// 刪除serviceif err := clientset.CoreV1().Services(NAMESPACE).Delete(context.TODO(), SERVICE_NAME, emptyDeleteOptions) ; err != nil {panic(err.Error())}// 刪除deploymentif err := clientset.AppsV1().Deployments(NAMESPACE).Delete(context.TODO(), DEPLOYMENT_NAME, emptyDeleteOptions) ; err != nil {panic(err.Error())}// 刪除namespaceif err := clientset.CoreV1().Namespaces().Delete(context.TODO(), NAMESPACE, emptyDeleteOptions) ; err != nil {panic(err.Error())} }// 新建namespace func createNamespace(clientset *kubernetes.Clientset) {namespaceClient := clientset.CoreV1().Namespaces()namespace := &apiv1.Namespace{ObjectMeta: metav1.ObjectMeta{Name: NAMESPACE,},}result, err := namespaceClient.Create(context.TODO(), namespace, metav1.CreateOptions{})if err!=nil {panic(err.Error())}fmt.Printf("Create namespace %s \n", result.GetName()) }// 新建service func createService(clientset *kubernetes.Clientset) {// 得到service的客戶端serviceClient := clientset.CoreV1().Services(NAMESPACE)// 實例化一個數據結構service := &apiv1.Service{ObjectMeta: metav1.ObjectMeta{Name: SERVICE_NAME,},Spec: apiv1.ServiceSpec{Ports: []apiv1.ServicePort{{Name: "http",Port: 8080,NodePort: 30080,},},Selector: map[string]string{"app" : "tomcat",},Type: apiv1.ServiceTypeNodePort,},}result, err := serviceClient.Create(context.TODO(), service, metav1.CreateOptions{})if err!=nil {panic(err.Error())}fmt.Printf("Create service %s \n", result.GetName()) }// 新建deployment func createDeployment(clientset *kubernetes.Clientset) {// 得到deployment的客戶端deploymentClient := clientset.AppsV1().Deployments(NAMESPACE)// 實例化一個數據結構deployment := &appsv1.Deployment{ObjectMeta: metav1.ObjectMeta{Name: DEPLOYMENT_NAME,},Spec: appsv1.DeploymentSpec{Replicas: pointer.Int32Ptr(2),Selector: &metav1.LabelSelector{MatchLabels: map[string]string{"app" : "tomcat",},},Template: apiv1.PodTemplateSpec{ObjectMeta:metav1.ObjectMeta{Labels: map[string]string{"app" : "tomcat",},},Spec: apiv1.PodSpec{Containers: []apiv1.Container{{Name: "tomcat",Image: "tomcat:8.0.18-jre8",ImagePullPolicy: "IfNotPresent",Ports: []apiv1.ContainerPort{{Name: "http",Protocol: apiv1.ProtocolSCTP,ContainerPort: 8080,},},},},},},},}result, err := deploymentClient.Create(context.TODO(), deployment, metav1.CreateOptions{})if err!=nil {panic(err.Error())}fmt.Printf("Create deployment %s \n", result.GetName()) }

    數據結構初始化的煩惱

    • 看過或者上述代碼后您可能在煩惱:創建資源時,數據結構的字段太多太復雜根本記不住,對應的代碼不好寫,這里分享一個我的做法,如下圖,我在開發的時候一共有兩個窗口,左側是官方的yaml示例,右側用了GoLand的分屏功能,分屏的左側是我寫代碼的窗口,右側是數據結構定義,此時內容不會搞錯,數據結構也能對應上,寫起來就舒服多了:

    驗證

    • 代碼寫完后,執行go run main.go,即可創建namespace、deployment、service等資源;
    • 查看kubernetes上資源是否成功創建:
    [root@hedy ~]# kubectl get pods -n test-clientset NAME READY STATUS RESTARTS AGE client-test-deployment-7677cc9669-kd7l7 1/1 Running 0 178m client-test-deployment-7677cc9669-kt5rv 1/1 Running 0 178m [root@hedy ~]# kubectl get service -n test-clientset NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE client-test-service NodePort 10.109.189.151 <none> 8080:30080/TCP 178m
    • 瀏覽器訪問kubernetes服務器的30080端口,可見熟悉的tomcat首頁:

    • 執行命令go run main.go -operate clean即可刪除剛才創建的所有資源;

    • 至此Clientset的學習和實戰就結束了,總得來說這是個大部分都是自動生成代碼的客戶端,邏輯簡單容易理解,多用幾次熟練后,就能隨心所欲的操控kubernetes的資源了;

    你不孤單,欣宸原創一路相伴

  • Java系列
  • Spring系列
  • Docker系列
  • kubernetes系列
  • 數據庫+中間件系列
  • DevOps系列
  • 歡迎關注公眾號:程序員欣宸

    微信搜索「程序員欣宸」,我是欣宸,期待與您一同暢游Java世界…

    總結

    以上是生活随笔為你收集整理的client-go实战之三:Clientset的全部內容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。