kubernetes源碼剖析之client-go(一)

kubernetes源碼剖析之client-go(一)


  剛入k8s和go的坑,碰巧看到社區的源碼研習活動,趕忙加入開始學習閱讀clinet-go(client-go源碼地址
  Kubernetes中使用client-go做爲Go語言的官方編程式交互客戶端庫,提供對api server服務的交互訪問。對於k8s的二次開發,熟練掌握client-go是十分必要的。 node


client-go源碼結構

cubix@DESKTOP-H2868FG MINGW64 /d/coding/go/src/k8s.io/client-go (14)
$ tree -L 1
.
|-- CHANGELOG.md
|-- CONTRIBUTING.md
|-- Godeps
|-- INSTALL.md
|-- LICENSE
|-- OWNERS
|-- README.md
|-- SECURITY_CONTACTS
|-- code-of-conduct.md
|-- discovery  # 提供DiscoveryClient發現客戶端
|-- dynamic # 提供DynamicClient動態客戶端
|-- examples
|-- go.mod
|-- go.sum
|-- informers # 每種kubernetes資源的Informer實現
|-- kubernetes # 提供ClientSet客戶端
|-- kubernetes_test
|-- listers # 爲每個kubernetes資源提供Lister功能,該功能對Get和List請求提供只讀的緩存數據
|-- metadata
|-- pkg
|-- plugin # 提供OpenStack、GCP和Azure等雲服務商受權插件
|-- rest # 提供RESTClient客戶端,對Kuberntes API Server執行RESTful操做
|-- restmapper
|-- scale # 提供ScaleClient客戶端,用於擴容或縮容Deployment、ReplicaSet、Replication Controller等資源對象
|-- testing
|-- third_party
|-- tools # 提供經常使用工具,例如Sharedinformer、Reflector、DealtFIFO及Indexers。提供Client查詢和緩存機制,以減小向kube-apiserver發起的請求數等
|-- transport # 提供安全的TCP鏈接,支持Http Stream,某些操做須要在客戶端和容器之間傳輸二進制流,例如exec、attach等操做。該功能由內部的spdy包提供支持
`-- util # 提供經常使用方法,例如WorkQueue工做隊列、Certificate證書管理

19 directories, 10 files

Client客戶端對象

  client-go支持4中client客戶端對象與api server交互的訪問方式, Client對象經過kubeconfig配置信息鏈接到指定的Kubernetes API Servernginx

  • RESTClient
  • ClientSet
  • DynamicClient
  • DiscoveryClient

RESTClient

  RESTClient是最基礎的客戶端,對HTTP Request進行了封裝,實現了RESTful風格的API,其餘的三個client都是基於RESTClient實現的。
使用RESTClient加載kubconfig配置,並讀取default空間下的podsgit

package main

import (
    "fmt"

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

func main() {
    // 加載kubeconfig文件,生成config對象
    config, err := clientcmd.BuildConfigFromFlags("", "D:\\coding\\config")

    if err != nil {
        panic(err)
    }
    // 配置API路徑和請求的資源組/資源版本信息
    config.APIPath = "api"
    config.GroupVersion = &corev1.SchemeGroupVersion
    config.NegotiatedSerializer = scheme.Codecs

    // 經過rest.RESTClientFor()生成RESTClient對象
    restClient, err := rest.RESTClientFor(config)
    if err != nil {
        panic(err)
    }

    // 經過RESTClient構建請求參數,查詢default空間下全部pod資源
    result := &corev1.PodList{}
    err = restClient.Get().
        Namespace("default").
        Resource("pods").
        VersionedParams(&metav1.ListOptions{Limit: 500}, scheme.ParameterCodec).
        Do().
        Into(result)

    if err != nil {
        panic(err)
    }

    for _, d := range result.Items {
        fmt.Printf("NAMESPACE:%v \t NAME: %v \t STATUS: %v\n", d.Namespace, d.Name, d.Status.Phase)
    }
}

// 測試
go run .\restClient-example.go
NAMESPACE:default        NAME: nginx-deployment-6b474476c4-lpld7         STATUS: Running
NAMESPACE:default        NAME: nginx-deployment-6b474476c4-t6xl4         STATUS: Running

ClientSet

  ClientSet在RESTClient的基礎上封裝了對Resource和Version的管理方法,每個Resource和Version都以函數的方式暴露給開發者。ClientSet只可以處理Kubernetes內置資源,不能直接訪問CRD自定義資源。ClientSet是經過client-gen代碼生成器自動生成的。github

package main

import (
    "fmt"

    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"
)

func main() {
    // 加載kubeconfig文件,生成config對象
    config, err := clientcmd.BuildConfigFromFlags("", "D:\\coding\\config")
    if err != nil {
        panic(err)
    }

    // kubernetes.NewForConfig經過config實例化ClientSet對象
    clientset, err := kubernetes.NewForConfig(config)
    if err != nil {
        panic(err)
    }

    //請求core核心資源組v1資源版本下的Pods資源對象
    podClient := clientset.CoreV1().Pods(apiv1.NamespaceDefault)
    // 設置選項
    list, err := podClient.List(metav1.ListOptions{Limit: 500})
    if err != nil {
        panic(err)
    }

    for _, d := range list.Items {
        fmt.Printf("NAMESPACE: %v \t NAME:%v \t STATUS: %+v\n", d.Namespace, d.Name, d.Status.Phase)
    }
}

// 測試
go run .\clientSet-example.go

NAMESPACE: default       NAME:nginx-deployment-6b474476c4-lpld7          STATUS: Running
NAMESPACE: default       NAME:nginx-deployment-6b474476c4-t6xl4          STATUS: Running

DynamicClient

  DynamicClient和ClientSet最大的區別在於,DynamicClient可以訪問Kubernetes中的全部資源對象,包含Kubernetes內置資源和CRD自定義資源。web

package main

import (
    "fmt"

    apiv1 "k8s.io/api/core/v1"
    corev1 "k8s.io/api/core/v1"
    metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"

    "k8s.io/apimachinery/pkg/runtime"
    "k8s.io/apimachinery/pkg/runtime/schema"
    "k8s.io/client-go/dynamic"
    "k8s.io/client-go/tools/clientcmd"
)

func main() {
    // 加載kubeconfig文件,生成config對象
    config, err := clientcmd.BuildConfigFromFlags("", "D:\\coding\\config")
    if err != nil {
        panic(err)
    }

    // dynamic.NewForConfig函數經過config實例化dynamicClient對象
    dynamicClient, err := dynamic.NewForConfig(config)
    if err != nil {
        panic(err)
    }

    // 經過schema.GroupVersionResource設置請求的資源版本和資源組,設置命名空間和請求參數,獲得unstructured.UnstructuredList指針類型的PodList
    gvr := schema.GroupVersionResource{Version: "v1", Resource: "pods"}
    unstructObj, err := dynamicClient.Resource(gvr).Namespace(apiv1.NamespaceDefault).List(metav1.ListOptions{Limit: 500})
    if err != nil {
        panic(err)
    }

    // 經過runtime.DefaultUnstructuredConverter函數將unstructured.UnstructuredList轉爲PodList類型
    podList := &corev1.PodList{}
    err = runtime.DefaultUnstructuredConverter.FromUnstructured(unstructObj.UnstructuredContent(), podList)
    if err != nil {
        panic(err)
    }

    for _, d := range podList.Items {
        fmt.Printf("NAMESPACE: %v NAME:%v \t STATUS: %+v\n", d.Namespace, d.Name, d.Status.Phase)
    }
}

// 測試
go run .\dynamicClient-example.go
NAMESPACE: default NAME:nginx-deployment-6b474476c4-lpld7        STATUS: Running
NAMESPACE: default NAME:nginx-deployment-6b474476c4-t6xl4        STATUS: Running

DiscoveryClient

  用於發現kube-apiserver所支持的資源組(Group),資源版本(Versions),資源信息(Resources)編程

package main

import (
    "fmt"

    "k8s.io/apimachinery/pkg/runtime/schema"
    "k8s.io/client-go/discovery"
    "k8s.io/client-go/tools/clientcmd"
)

func main() {
    // 加載kubeconfig文件,生成config對象
    config, err := clientcmd.BuildConfigFromFlags("", "D:\\coding\\config")
    if err != nil {
        panic(err)
    }

    // discovery.NewDiscoveryClientForConfigg函數經過config實例化discoveryClient對象
    discoveryClient, err := discovery.NewDiscoveryClientForConfig(config)
    if err != nil {
        panic(err)
    }

    // discoveryClient.ServerGroupsAndResources 返回API Server所支持的資源組、資源版本、資源信息
    _, APIResourceList, err := discoveryClient.ServerGroupsAndResources()
    if err != nil {
        panic(err)
    }

    // 輸出全部資源信息
    for _, list := range APIResourceList {
        gv, err := schema.ParseGroupVersion(list.GroupVersion)
        if err != nil {
            panic(err)
        }

        for _, resource := range list.APIResources {
            fmt.Printf("NAME: %v, GROUP: %v, VERSION: %v \n", resource.Name, gv.Group, gv.Version)
        }
    }
}

// 測試
 go run .\discoveryClient-example.go
NAME: bindings, GROUP: , VERSION: v1 
NAME: componentstatuses, GROUP: , VERSION: v1 
NAME: configmaps, GROUP: , VERSION: v1
NAME: endpoints, GROUP: , VERSION: v1
NAME: events, GROUP: , VERSION: v1
NAME: limitranges, GROUP: , VERSION: v1
NAME: namespaces, GROUP: , VERSION: v1
NAME: namespaces/finalize, GROUP: , VERSION: v1
NAME: namespaces/status, GROUP: , VERSION: v1
NAME: nodes, GROUP: , VERSION: v1
NAME: nodes/proxy, GROUP: , VERSION: v1
NAME: nodes/status, GROUP: , VERSION: v1
NAME: persistentvolumeclaims, GROUP: , VERSION: v1
NAME: persistentvolumeclaims/status, GROUP: , VERSION: v1
NAME: persistentvolumes, GROUP: , VERSION: v1
NAME: persistentvolumes/status, GROUP: , VERSION: v1
NAME: pods, GROUP: , VERSION: v1
NAME: pods/attach, GROUP: , VERSION: v1
NAME: pods/binding, GROUP: , VERSION: v1
NAME: pods/eviction, GROUP: , VERSION: v1
NAME: pods/exec, GROUP: , VERSION: v1
NAME: pods/log, GROUP: , VERSION: v1
NAME: pods/portforward, GROUP: , VERSION: v1
NAME: pods/proxy, GROUP: , VERSION: v1
NAME: pods/status, GROUP: , VERSION: v1
NAME: podtemplates, GROUP: , VERSION: v1
NAME: replicationcontrollers, GROUP: , VERSION: v1
NAME: replicationcontrollers/scale, GROUP: , VERSION: v1
NAME: replicationcontrollers/status, GROUP: , VERSION: v1
NAME: resourcequotas, GROUP: , VERSION: v1
NAME: resourcequotas/status, GROUP: , VERSION: v1
NAME: secrets, GROUP: , VERSION: v1
NAME: serviceaccounts, GROUP: , VERSION: v1
NAME: services, GROUP: , VERSION: v1
NAME: services/proxy, GROUP: , VERSION: v1
NAME: services/status, GROUP: , VERSION: v1
NAME: apiservices, GROUP: apiregistration.k8s.io, VERSION: v1
NAME: apiservices/status, GROUP: apiregistration.k8s.io, VERSION: v1
NAME: apiservices, GROUP: apiregistration.k8s.io, VERSION: v1beta1 
NAME: apiservices/status, GROUP: apiregistration.k8s.io, VERSION: v1beta1
NAME: ingresses, GROUP: extensions, VERSION: v1beta1
NAME: ingresses/status, GROUP: extensions, VERSION: v1beta1
NAME: controllerrevisions, GROUP: apps, VERSION: v1
NAME: daemonsets, GROUP: apps, VERSION: v1
NAME: daemonsets/status, GROUP: apps, VERSION: v1
NAME: deployments, GROUP: apps, VERSION: v1
NAME: deployments/scale, GROUP: apps, VERSION: v1
NAME: deployments/status, GROUP: apps, VERSION: v1
NAME: replicasets, GROUP: apps, VERSION: v1
NAME: replicasets/scale, GROUP: apps, VERSION: v1
NAME: replicasets/status, GROUP: apps, VERSION: v1
NAME: statefulsets, GROUP: apps, VERSION: v1
NAME: statefulsets/scale, GROUP: apps, VERSION: v1
NAME: statefulsets/status, GROUP: apps, VERSION: v1
NAME: events, GROUP: events.k8s.io, VERSION: v1beta1
NAME: tokenreviews, GROUP: authentication.k8s.io, VERSION: v1
NAME: tokenreviews, GROUP: authentication.k8s.io, VERSION: v1beta1
NAME: localsubjectacce***eviews, GROUP: authorization.k8s.io, VERSION: v1
NAME: selfsubjectacce***eviews, GROUP: authorization.k8s.io, VERSION: v1
NAME: selfsubjectrulesreviews, GROUP: authorization.k8s.io, VERSION: v1
NAME: subjectacce***eviews, GROUP: authorization.k8s.io, VERSION: v1
NAME: localsubjectacce***eviews, GROUP: authorization.k8s.io, VERSION: v1beta1
NAME: selfsubjectacce***eviews, GROUP: authorization.k8s.io, VERSION: v1beta1
NAME: selfsubjectrulesreviews, GROUP: authorization.k8s.io, VERSION: v1beta1
NAME: subjectacce***eviews, GROUP: authorization.k8s.io, VERSION: v1beta1
NAME: horizontalpodautoscalers, GROUP: autoscaling, VERSION: v1
NAME: horizontalpodautoscalers/status, GROUP: autoscaling, VERSION: v1
NAME: horizontalpodautoscalers, GROUP: autoscaling, VERSION: v2beta1
NAME: horizontalpodautoscalers/status, GROUP: autoscaling, VERSION: v2beta1
NAME: horizontalpodautoscalers, GROUP: autoscaling, VERSION: v2beta2
NAME: horizontalpodautoscalers/status, GROUP: autoscaling, VERSION: v2beta2
NAME: jobs, GROUP: batch, VERSION: v1
NAME: jobs/status, GROUP: batch, VERSION: v1
NAME: cronjobs, GROUP: batch, VERSION: v1beta1
NAME: cronjobs/status, GROUP: batch, VERSION: v1beta1
NAME: certificatesigningrequests, GROUP: certificates.k8s.io, VERSION: v1beta1
NAME: certificatesigningrequests/approval, GROUP: certificates.k8s.io, VERSION: v1beta1
NAME: certificatesigningrequests/status, GROUP: certificates.k8s.io, VERSION: v1beta1
NAME: networkpolicies, GROUP: networking.k8s.io, VERSION: v1
NAME: ingressclasses, GROUP: networking.k8s.io, VERSION: v1beta1
NAME: ingresses, GROUP: networking.k8s.io, VERSION: v1beta1
NAME: ingresses/status, GROUP: networking.k8s.io, VERSION: v1beta1
NAME: poddisruptionbudgets, GROUP: policy, VERSION: v1beta1
NAME: poddisruptionbudgets/status, GROUP: policy, VERSION: v1beta1
NAME: podsecuritypolicies, GROUP: policy, VERSION: v1beta1
NAME: clusterrolebindings, GROUP: rbac.authorization.k8s.io, VERSION: v1
NAME: clusterroles, GROUP: rbac.authorization.k8s.io, VERSION: v1
NAME: rolebindings, GROUP: rbac.authorization.k8s.io, VERSION: v1
NAME: roles, GROUP: rbac.authorization.k8s.io, VERSION: v1
NAME: clusterrolebindings, GROUP: rbac.authorization.k8s.io, VERSION: v1beta1
NAME: clusterroles, GROUP: rbac.authorization.k8s.io, VERSION: v1beta1
NAME: rolebindings, GROUP: rbac.authorization.k8s.io, VERSION: v1beta1
NAME: roles, GROUP: rbac.authorization.k8s.io, VERSION: v1beta1
NAME: csidrivers, GROUP: storage.k8s.io, VERSION: v1
NAME: csinodes, GROUP: storage.k8s.io, VERSION: v1
NAME: storageclasses, GROUP: storage.k8s.io, VERSION: v1
NAME: volumeattachments, GROUP: storage.k8s.io, VERSION: v1
NAME: volumeattachments/status, GROUP: storage.k8s.io, VERSION: v1 
NAME: csidrivers, GROUP: storage.k8s.io, VERSION: v1beta1
NAME: csinodes, GROUP: storage.k8s.io, VERSION: v1beta1
NAME: storageclasses, GROUP: storage.k8s.io, VERSION: v1beta1
NAME: volumeattachments, GROUP: storage.k8s.io, VERSION: v1beta1
NAME: mutatingwebhookconfigurations, GROUP: admissionregistration.k8s.io, VERSION: v1
NAME: validatingwebhookconfigurations, GROUP: admissionregistration.k8s.io, VERSION: v1
NAME: mutatingwebhookconfigurations, GROUP: admissionregistration.k8s.io, VERSION: v1beta1
NAME: validatingwebhookconfigurations, GROUP: admissionregistration.k8s.io, VERSION: v1beta1
NAME: customresourcedefinitions, GROUP: apiextensions.k8s.io, VERSION: v1
NAME: customresourcedefinitions/status, GROUP: apiextensions.k8s.io, VERSION: v1
NAME: customresourcedefinitions, GROUP: apiextensions.k8s.io, VERSION: v1beta1
NAME: customresourcedefinitions/status, GROUP: apiextensions.k8s.io, VERSION: v1beta1
NAME: priorityclasses, GROUP: scheduling.k8s.io, VERSION: v1
NAME: priorityclasses, GROUP: scheduling.k8s.io, VERSION: v1beta1
NAME: leases, GROUP: coordination.k8s.io, VERSION: v1
NAME: leases, GROUP: coordination.k8s.io, VERSION: v1beta1
NAME: runtimeclasses, GROUP: node.k8s.io, VERSION: v1beta1
NAME: endpointslices, GROUP: discovery.k8s.io, VERSION: v1beta1
相關文章
相關標籤/搜索