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
相关文章
相关标签/搜索