client-go 源碼分析

1_CdjOgfolLt_GNJYBzI-1QQ.jpeg

client-go 簡介

client-go是一個(gè)調(diào)用kubernetes集群資源對象API的客戶端,即通過client-go實(shí)現(xiàn)對kubernetes集群中資源對象(包括deployment慷妙、service僻焚、ingress、replicaSet膝擂、pod虑啤、namespace、node等)的增刪改查等操作架馋。大部分對kubernetes進(jìn)行前置API封裝的二次開發(fā)都通過client-go這個(gè)第三方包來實(shí)現(xiàn)狞山。

?client-go官方文檔:https://github.com/kubernetes/client-go

client-go 源碼目錄結(jié)構(gòu)

  • The kubernetes package contains the clientset to access Kubernetes API.
  • The discovery package is used to discover APIs supported by a Kubernetes API server.
  • The dynamic package contains a dynamic client that can perform generic operations on arbitrary Kubernetes API objects.
  • The transport package is used to set up auth and start a connection.
  • The tools/cache package is useful for writing controllers.

示例代碼

#demo.go
package main

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

    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("", kubeconfig)
    if err != nil {
        panic(err.Error())
    }
    // creates the clientset
    clientset, err := kubernetes.NewForConfig(config)
    if err != nil {
        panic(err.Error())
    }
    pods, err := clientset.CoreV1().Pods("").List(metav1.ListOptions{})
    if err != nil {
        panic(err.Error())
    }
    fmt.Printf("There are %d pods in the cluster\n", len(pods.Items))
}

client-go庫版本

go get  k8s.io/client-go v0.0.0-20191114101535-6c5935290e33

kubeconfig

獲取kubernetes配置文件kubeconfig的絕對路徑。一般路徑為$HOME/.kube/config叉寂。該文件主要用來配置本地連接的kubernetes集群萍启。config配置文件支持集群內(nèi)和集群外訪問方式。(只要在網(wǎng)絡(luò)策略訪問范圍內(nèi))

config文件形式如下所示:

apiVersion: v1
clusters:
- cluster:
    certificate-authority-data: { .Certificate-authority-data}
    server: https://ip:6443
name: kubernetes
contexts:
- context:
    cluster: kubernetes
    user: kubernetes-admin
name: kubernetes-admin@kubernetes
current-context: kubernetes-admin@kubernetes
kind: Config
preferences: {}
users:
- name: kubernetes-admin
user:
    client-certificate-data: { .Client-certificate-data}
    client-key-data: { .Client-key-data}

rest.config 對象

config, err := clientcmd.BuildConfigFromFlags("", kubeconfig)

通過參數(shù)(master的url或者kubeconfig路徑)用BuildConfigFromFlags方法來獲取rest.Config對象屏鳍,一般是通過參數(shù)kubeconfig的路徑勘纯。

Clientset對象創(chuàng)建

clientset, err := kubernetes.NewForConfig(config)

通過config對象為入?yún)ⅲ{(diào)用NewForConfig函數(shù)獲取clients對象钓瞭,clients是多個(gè)client的集合驳遵。里面包含著各個(gè)版本的client。源碼地址:k8s.io/client-go/kubernetes/clientset.go

// NewForConfig creates a new Clientset for the given config.
// If config's RateLimiter is not set and QPS and Burst are acceptable,
// NewForConfig will generate a rate-limiter in configShallowCopy.
func NewForConfig(c *rest.Config) (*Clientset, error) {
    configShallowCopy := *c
    if configShallowCopy.RateLimiter == nil && configShallowCopy.QPS > 0 {
        if configShallowCopy.Burst <= 0 {
            return nil, fmt.Errorf("Burst is required to be greater than 0 when RateLimiter is not set and QPS is set to greater than 0")
        }
        configShallowCopy.RateLimiter = flowcontrol.NewTokenBucketRateLimiter(configShallowCopy.QPS, configShallowCopy.Burst)
    }
    var cs Clientset
    var err error
    cs.admissionregistrationV1, err = admissionregistrationv1.NewForConfig(&configShallowCopy)
    if err != nil {
        return nil, err
    }
    cs.admissionregistrationV1beta1, err = admissionregistrationv1beta1.NewForConfig(&configShallowCopy)
    if err != nil {
        return nil, err
    }
    cs.appsV1, err = appsv1.NewForConfig(&configShallowCopy)
    if err != nil {
        return nil, err
    }
    cs.appsV1beta1, err = appsv1beta1.NewForConfig(&configShallowCopy)
    if err != nil {
        return nil, err
    }
    cs.appsV1beta2, err = appsv1beta2.NewForConfig(&configShallowCopy)
    if err != nil {
        return nil, err
    }
    cs.auditregistrationV1alpha1, err = auditregistrationv1alpha1.NewForConfig(&configShallowCopy)
    if err != nil {
        return nil, err
    }
    cs.authenticationV1, err = authenticationv1.NewForConfig(&configShallowCopy)
    if err != nil {
        return nil, err
    }
    cs.authenticationV1beta1, err = authenticationv1beta1.NewForConfig(&configShallowCopy)
    if err != nil {
        return nil, err
    }
    cs.authorizationV1, err = authorizationv1.NewForConfig(&configShallowCopy)
    if err != nil {
        return nil, err
    }
    cs.authorizationV1beta1, err = authorizationv1beta1.NewForConfig(&configShallowCopy)
    if err != nil {
        return nil, err
    }
    cs.autoscalingV1, err = autoscalingv1.NewForConfig(&configShallowCopy)
    if err != nil {
        return nil, err
    }
    cs.autoscalingV2beta1, err = autoscalingv2beta1.NewForConfig(&configShallowCopy)
    if err != nil {
        return nil, err
    }
    cs.autoscalingV2beta2, err = autoscalingv2beta2.NewForConfig(&configShallowCopy)
    if err != nil {
        return nil, err
    }
    cs.batchV1, err = batchv1.NewForConfig(&configShallowCopy)
    if err != nil {
        return nil, err
    }
    cs.batchV1beta1, err = batchv1beta1.NewForConfig(&configShallowCopy)
    if err != nil {
        return nil, err
    }
    cs.batchV2alpha1, err = batchv2alpha1.NewForConfig(&configShallowCopy)
    if err != nil {
        return nil, err
    }
    cs.certificatesV1beta1, err = certificatesv1beta1.NewForConfig(&configShallowCopy)
    if err != nil {
        return nil, err
    }
    cs.coordinationV1beta1, err = coordinationv1beta1.NewForConfig(&configShallowCopy)
    if err != nil {
        return nil, err
    }
    cs.coordinationV1, err = coordinationv1.NewForConfig(&configShallowCopy)
    if err != nil {
        return nil, err
    }
    //coreV1 對象創(chuàng)建
    cs.coreV1, err = corev1.NewForConfig(&configShallowCopy)
    if err != nil {
        return nil, err
    }
    cs.discoveryV1alpha1, err = discoveryv1alpha1.NewForConfig(&configShallowCopy)
    if err != nil {
        return nil, err
    }
    cs.eventsV1beta1, err = eventsv1beta1.NewForConfig(&configShallowCopy)
    if err != nil {
        return nil, err
    }
    cs.extensionsV1beta1, err = extensionsv1beta1.NewForConfig(&configShallowCopy)
    if err != nil {
        return nil, err
    }
    cs.networkingV1, err = networkingv1.NewForConfig(&configShallowCopy)
    if err != nil {
        return nil, err
    }
    cs.networkingV1beta1, err = networkingv1beta1.NewForConfig(&configShallowCopy)
    if err != nil {
        return nil, err
    }
    cs.nodeV1alpha1, err = nodev1alpha1.NewForConfig(&configShallowCopy)
    if err != nil {
        return nil, err
    }
    cs.nodeV1beta1, err = nodev1beta1.NewForConfig(&configShallowCopy)
    if err != nil {
        return nil, err
    }
    cs.policyV1beta1, err = policyv1beta1.NewForConfig(&configShallowCopy)
    if err != nil {
        return nil, err
    }
    cs.rbacV1, err = rbacv1.NewForConfig(&configShallowCopy)
    if err != nil {
        return nil, err
    }
    cs.rbacV1beta1, err = rbacv1beta1.NewForConfig(&configShallowCopy)
    if err != nil {
        return nil, err
    }
    cs.rbacV1alpha1, err = rbacv1alpha1.NewForConfig(&configShallowCopy)
    if err != nil {
        return nil, err
    }
    cs.schedulingV1alpha1, err = schedulingv1alpha1.NewForConfig(&configShallowCopy)
    if err != nil {
        return nil, err
    }
    cs.schedulingV1beta1, err = schedulingv1beta1.NewForConfig(&configShallowCopy)
    if err != nil {
        return nil, err
    }
    cs.schedulingV1, err = schedulingv1.NewForConfig(&configShallowCopy)
    if err != nil {
        return nil, err
    }
    cs.settingsV1alpha1, err = settingsv1alpha1.NewForConfig(&configShallowCopy)
    if err != nil {
        return nil, err
    }
    cs.storageV1beta1, err = storagev1beta1.NewForConfig(&configShallowCopy)
    if err != nil {
        return nil, err
    }
    cs.storageV1, err = storagev1.NewForConfig(&configShallowCopy)
    if err != nil {
        return nil, err
    }
    cs.storageV1alpha1, err = storagev1alpha1.NewForConfig(&configShallowCopy)
    if err != nil {
        return nil, err
    }

    cs.DiscoveryClient, err = discovery.NewDiscoveryClientForConfig(&configShallowCopy)
    if err != nil {
        return nil, err
    }
    return &cs, nil
}

NewForConfig函數(shù)根據(jù)傳入的rest.config對象創(chuàng)建一個(gè)Clientset對象,此對象可以操作CoreV1()方法山涡。

Clientset 結(jié)構(gòu)體

其結(jié)構(gòu)體具體參數(shù)如下所示:

// Clientset contains the clients for groups. Each group has exactly one
// version included in a Clientset.
type Clientset struct {
    *discovery.DiscoveryClient
    admissionregistrationV1      *admissionregistrationv1.AdmissionregistrationV1Client
    admissionregistrationV1beta1 *admissionregistrationv1beta1.AdmissionregistrationV1beta1Client
    appsV1                       *appsv1.AppsV1Client
    appsV1beta1                  *appsv1beta1.AppsV1beta1Client
    appsV1beta2                  *appsv1beta2.AppsV1beta2Client
    auditregistrationV1alpha1    *auditregistrationv1alpha1.AuditregistrationV1alpha1Client
    authenticationV1             *authenticationv1.AuthenticationV1Client
    authenticationV1beta1        *authenticationv1beta1.AuthenticationV1beta1Client
    authorizationV1              *authorizationv1.AuthorizationV1Client
    authorizationV1beta1         *authorizationv1beta1.AuthorizationV1beta1Client
    autoscalingV1                *autoscalingv1.AutoscalingV1Client
    autoscalingV2beta1           *autoscalingv2beta1.AutoscalingV2beta1Client
    autoscalingV2beta2           *autoscalingv2beta2.AutoscalingV2beta2Client
    batchV1                      *batchv1.BatchV1Client
    batchV1beta1                 *batchv1beta1.BatchV1beta1Client
    batchV2alpha1                *batchv2alpha1.BatchV2alpha1Client
    certificatesV1beta1          *certificatesv1beta1.CertificatesV1beta1Client
    coordinationV1beta1          *coordinationv1beta1.CoordinationV1beta1Client
    coordinationV1               *coordinationv1.CoordinationV1Client
    coreV1                       *corev1.CoreV1Client
    discoveryV1alpha1            *discoveryv1alpha1.DiscoveryV1alpha1Client
    eventsV1beta1                *eventsv1beta1.EventsV1beta1Client
    extensionsV1beta1            *extensionsv1beta1.ExtensionsV1beta1Client
    networkingV1                 *networkingv1.NetworkingV1Client
    networkingV1beta1            *networkingv1beta1.NetworkingV1beta1Client
    nodeV1alpha1                 *nodev1alpha1.NodeV1alpha1Client
    nodeV1beta1                  *nodev1beta1.NodeV1beta1Client
    policyV1beta1                *policyv1beta1.PolicyV1beta1Client
    rbacV1                       *rbacv1.RbacV1Client
    rbacV1beta1                  *rbacv1beta1.RbacV1beta1Client
    rbacV1alpha1                 *rbacv1alpha1.RbacV1alpha1Client
    schedulingV1alpha1           *schedulingv1alpha1.SchedulingV1alpha1Client
    schedulingV1beta1            *schedulingv1beta1.SchedulingV1beta1Client
    schedulingV1                 *schedulingv1.SchedulingV1Client
    settingsV1alpha1             *settingsv1alpha1.SettingsV1alpha1Client
    storageV1beta1               *storagev1beta1.StorageV1beta1Client
    storageV1                    *storagev1.StorageV1Client
    storageV1alpha1              *storagev1alpha1.StorageV1alpha1Client
}

Clientset 實(shí)現(xiàn)的接口

type Interface interface {
    Discovery() discovery.DiscoveryInterface
    AdmissionregistrationV1() admissionregistrationv1.AdmissionregistrationV1Interface
    AdmissionregistrationV1beta1() admissionregistrationv1beta1.AdmissionregistrationV1beta1Interface
    AppsV1() appsv1.AppsV1Interface
    AppsV1beta1() appsv1beta1.AppsV1beta1Interface
    AppsV1beta2() appsv1beta2.AppsV1beta2Interface
    AuditregistrationV1alpha1() auditregistrationv1alpha1.AuditregistrationV1alpha1Interface
    AuthenticationV1() authenticationv1.AuthenticationV1Interface
    AuthenticationV1beta1() authenticationv1beta1.AuthenticationV1beta1Interface
    AuthorizationV1() authorizationv1.AuthorizationV1Interface
    AuthorizationV1beta1() authorizationv1beta1.AuthorizationV1beta1Interface
    AutoscalingV1() autoscalingv1.AutoscalingV1Interface
    AutoscalingV2beta1() autoscalingv2beta1.AutoscalingV2beta1Interface
    AutoscalingV2beta2() autoscalingv2beta2.AutoscalingV2beta2Interface
    BatchV1() batchv1.BatchV1Interface
    BatchV1beta1() batchv1beta1.BatchV1beta1Interface
    BatchV2alpha1() batchv2alpha1.BatchV2alpha1Interface
    CertificatesV1beta1() certificatesv1beta1.CertificatesV1beta1Interface
    CoordinationV1beta1() coordinationv1beta1.CoordinationV1beta1Interface
    CoordinationV1() coordinationv1.CoordinationV1Interface
    CoreV1() corev1.CoreV1Interface
    DiscoveryV1alpha1() discoveryv1alpha1.DiscoveryV1alpha1Interface
    EventsV1beta1() eventsv1beta1.EventsV1beta1Interface
    ExtensionsV1beta1() extensionsv1beta1.ExtensionsV1beta1Interface
    NetworkingV1() networkingv1.NetworkingV1Interface
    NetworkingV1beta1() networkingv1beta1.NetworkingV1beta1Interface
    NodeV1alpha1() nodev1alpha1.NodeV1alpha1Interface
    NodeV1beta1() nodev1beta1.NodeV1beta1Interface
    PolicyV1beta1() policyv1beta1.PolicyV1beta1Interface
    RbacV1() rbacv1.RbacV1Interface
    RbacV1beta1() rbacv1beta1.RbacV1beta1Interface
    RbacV1alpha1() rbacv1alpha1.RbacV1alpha1Interface
    SchedulingV1alpha1() schedulingv1alpha1.SchedulingV1alpha1Interface
    SchedulingV1beta1() schedulingv1beta1.SchedulingV1beta1Interface
    SchedulingV1() schedulingv1.SchedulingV1Interface
    SettingsV1alpha1() settingsv1alpha1.SettingsV1alpha1Interface
    StorageV1beta1() storagev1beta1.StorageV1beta1Interface
    StorageV1() storagev1.StorageV1Interface
    StorageV1alpha1() storagev1alpha1.StorageV1alpha1Interface
}

Clientset結(jié)構(gòu)體實(shí)現(xiàn)了以上結(jié)構(gòu)定義的所有方法堤结。源碼地址:k8s.io/client-go/kubernetes/clientset.go

因?yàn)镃lientset可使用其中任意函數(shù)調(diào)用唆迁,如獲取Pod列表。

pods, err := clientset.CoreV1().Pods("").List(metav1.ListOptions{})

CoreV1Client對象創(chuàng)建

在創(chuàng)建Clientset對象時(shí)竞穷,Clientset 中的變量coreV1也被一起初始化創(chuàng)建唐责。即創(chuàng)建了CoreV1Client對象。

    //coreV1 對象創(chuàng)建
    cs.coreV1, err = corev1.NewForConfig(&configShallowCopy)

NewForConfig

// NewForConfig creates a new CoreV1Client for the given config.
func NewForConfig(c *rest.Config) (*CoreV1Client, error) {
    config := *c
    if err := setConfigDefaults(&config); err != nil {
        return nil, err
    }
    client, err := rest.RESTClientFor(&config)
    if err != nil {
        return nil, err
    }
    return &CoreV1Client{client}, nil
}

CoreV1Interface

如下所示:

type CoreV1Interface interface {
    RESTClient() rest.Interface
    ComponentStatusesGetter
    ConfigMapsGetter
    EndpointsGetter
    EventsGetter
    LimitRangesGetter
    NamespacesGetter
    NodesGetter
    PersistentVolumesGetter
    PersistentVolumeClaimsGetter
    PodsGetter
    PodTemplatesGetter
    ReplicationControllersGetter
    ResourceQuotasGetter
    SecretsGetter
    ServicesGetter
    ServiceAccountsGetter
}

CoreV1Interface中包含了各種kubernetes對象的調(diào)用接口来庭,例如PodsGetter是對kubernetes中pod對象增刪改查操作的接口。ServicesGetter是對service對象的操作的接口穿挨。

CoreV1Client 結(jié)構(gòu)體

    type CoreV1Client struct {
        restClient rest.Interface
    }

CoreV1Client結(jié)構(gòu)體實(shí)現(xiàn)了CoreV1Interface所有的定義函數(shù)月弛。

//CoreV1Client的方法
func (c *CoreV1Client) ComponentStatuses() ComponentStatusInterface
//ConfigMaps
func (c *CoreV1Client) ConfigMaps(namespace string) ConfigMapInterface
//Endpoints
func (c *CoreV1Client) Endpoints(namespace string) EndpointsInterface
func (c *CoreV1Client) Events(namespace string) EventInterface
func (c *CoreV1Client) LimitRanges(namespace string) LimitRangeInterface
//namespace
func (c *CoreV1Client) Namespaces() NamespaceInterface 
//nodes
func (c *CoreV1Client) Nodes() NodeInterface 
//pv
func (c *CoreV1Client) PersistentVolumes() PersistentVolumeInterface 
//pvc
func (c *CoreV1Client) PersistentVolumeClaims(namespace string) PersistentVolumeClaimInterface 
//pods 
func (c *CoreV1Client) Pods(namespace string) PodInterface 
func (c *CoreV1Client) PodTemplates(namespace string) PodTemplateInterface 
//rc
func (c *CoreV1Client) ReplicationControllers(namespace string) ReplicationControllerInterface 
func (c *CoreV1Client) ResourceQuotas(namespace string) ResourceQuotaInterface 
//secret
func (c *CoreV1Client) Secrets(namespace string) SecretInterface 
//service
func (c *CoreV1Client) Services(namespace string) ServiceInterface 
func (c *CoreV1Client) ServiceAccounts(namespace string) ServiceAccountInterface 

PodsGetter接口

type PodsGetter interface {
    Pods(namespace string) PodInterface
}

func (c *CoreV1Client) Pods(namespace string) PodInterface {
    return newPods(c, namespace)
}

PodsGetter接口中定義了Pods方法此方法返回PodInterface,這樣就可以用Clients.Corev1().Pods()方法對Pod進(jìn)行增刪改查操作了科盛。

Pod對象創(chuàng)建

func (c *CoreV1Client) Pods(namespace string) PodInterface {
    return newPods(c, namespace)
}

// newPods returns a Pods
func newPods(c *CoreV1Client, namespace string) *pods {
    return &pods{
        client: c.RESTClient(),
        ns:     namespace,
    }
}

調(diào)用Pods方法帽衙,再通過newPods函數(shù)創(chuàng)建一個(gè)Pods的對象。pods對象繼承了rest.Interface接口贞绵,即最終的實(shí)現(xiàn)本質(zhì)是RESTClient的HTTP調(diào)用厉萝。

PodInterface接口

// PodInterface has methods to work with Pod resources.
type PodInterface interface {
    Create(*v1.Pod) (*v1.Pod, error)
    Update(*v1.Pod) (*v1.Pod, error)
    UpdateStatus(*v1.Pod) (*v1.Pod, error)
    Delete(name string, options *metav1.DeleteOptions) error
    DeleteCollection(options *metav1.DeleteOptions, listOptions metav1.ListOptions) error
    Get(name string, options metav1.GetOptions) (*v1.Pod, error)
    List(opts metav1.ListOptions) (*v1.PodList, error)
    Watch(opts metav1.ListOptions) (watch.Interface, error)
    Patch(name string, pt types.PatchType, data []byte, subresources ...string) (result *v1.Pod, err error)
    GetEphemeralContainers(podName string, options metav1.GetOptions) (*v1.EphemeralContainers, error)
    UpdateEphemeralContainers(podName string, ephemeralContainers *v1.EphemeralContainers) (*v1.EphemeralContainers, error)

    PodExpansion
}

PodInterface接口定義了Pod對象操作的所有方法。

Pod結(jié)構(gòu)體

// pods implements PodInterface
type pods struct {
    client rest.Interface
    ns     string
}

Pod對象中繼承了rest.Interface榨崩,上面提到過此client便是進(jìn)行http請求調(diào)用谴垫。

Pod List方法

// List takes label and field selectors, and returns the list of Pods that match those selectors.
func (c *pods) List(opts metav1.ListOptions) (result *v1.PodList, err error) {
    var timeout time.Duration
    if opts.TimeoutSeconds != nil {
        timeout = time.Duration(*opts.TimeoutSeconds) * time.Second
    }
    result = &v1.PodList{}
    err = c.client.Get().
        Namespace(c.ns).
        Resource("pods").
        VersionedParams(&opts, scheme.ParameterCodec).
        Timeout(timeout).
        Do().
        Into(result)
    return
}

以上分析了clientset.CoreV1().Pods("").List(metav1.ListOptions{})對pod資源獲取的過程,最終是調(diào)用RESTClient的方法實(shí)現(xiàn)母蛛。

rest client 對象創(chuàng)建

// NewForConfig creates a new CoreV1Client for the given config.
func NewForConfig(c *rest.Config) (*CoreV1Client, error) {
    config := *c
    if err := setConfigDefaults(&config); err != nil {
        return nil, err
    }
    client, err := rest.RESTClientFor(&config)
    if err != nil {
        return nil, err
    }
    return &CoreV1Client{client}, nil
}

在CoreV1Client對象創(chuàng)建的時(shí)候也根據(jù)config對象調(diào)用est.RESTClientFor(&config)函數(shù)創(chuàng)建了rest client對象翩剪。在創(chuàng)建Pod時(shí)將CoreV1Client對象的restClient賦值給Pod的client。

rest.Interface

type Interface interface {
    GetRateLimiter() flowcontrol.RateLimiter
    Verb(verb string) *Request
    Post() *Request
    Put() *Request
    Patch(pt types.PatchType) *Request
    Get() *Request
    Delete() *Request
    APIVersion() schema.GroupVersion
}

此接口定義了http請求的方法彩郊。

RESTClient結(jié)構(gòu)體

type RESTClient struct {
    // base is the root URL for all invocations of the client
    base *url.URL
    // versionedAPIPath is a path segment connecting the base URL to the resource root
    versionedAPIPath string

    // contentConfig is the information used to communicate with the server.
    contentConfig ContentConfig

    // serializers contain all serializers for underlying content type.
    serializers Serializers

    // creates BackoffManager that is passed to requests.
    createBackoffMgr func() BackoffManager

    // TODO extract this into a wrapper interface via the RESTClient interface in kubectl.
    Throttle flowcontrol.RateLimiter

    // Set specific behavior of the client.  If not set http.DefaultClient will be used.
    Client *http.Client
}

RESTClient對象實(shí)現(xiàn)的接口函數(shù)

func (c *RESTClient) Verb(verb string) *Request {
    backoff := c.createBackoffMgr()

    if c.Client == nil {
        return NewRequest(nil, verb, c.base, c.versionedAPIPath, c.contentConfig, c.serializers, backoff, c.Throttle, 0)
    }
    return NewRequest(c.Client, verb, c.base, c.versionedAPIPath, c.contentConfig, c.serializers, backoff, c.Throttle, c.Client.Timeout)
}

// Post begins a POST request. Short for c.Verb("POST").
func (c *RESTClient) Post() *Request {
    return c.Verb("POST")
}

// Put begins a PUT request. Short for c.Verb("PUT").
func (c *RESTClient) Put() *Request {
    return c.Verb("PUT")
}

// Patch begins a PATCH request. Short for c.Verb("Patch").
func (c *RESTClient) Patch(pt types.PatchType) *Request {
    return c.Verb("PATCH").SetHeader("Content-Type", string(pt))
}

// Get begins a GET request. Short for c.Verb("GET").
func (c *RESTClient) Get() *Request {
    return c.Verb("GET")
}

// Delete begins a DELETE request. Short for c.Verb("DELETE").
func (c *RESTClient) Delete() *Request {
    return c.Verb("DELETE")
}

// APIVersion returns the APIVersion this RESTClient is expected to use.
func (c *RESTClient) APIVersion() schema.GroupVersion {
    return *c.contentConfig.GroupVersion
}

通過以上實(shí)現(xiàn)可以看出對著的接口調(diào)用都轉(zhuǎn)到了Verb方法的調(diào)用前弯。Verb方法通過傳參調(diào)用NewRequest函數(shù)最終執(zhí)行了一次http請求操作。

NewRequest

// NewRequest creates a new request helper object for accessing runtime.Objects on a server.
func NewRequest(client HTTPClient, verb string, baseURL *url.URL, versionedAPIPath string, content ContentConfig, serializers Serializers, backoff BackoffManager, throttle flowcontrol.RateLimiter, timeout time.Duration) *Request {
    if backoff == nil {
        klog.V(2).Infof("Not implementing request backoff strategy.")
        backoff = &NoBackoff{}
    }

    pathPrefix := "/"
    if baseURL != nil {
        pathPrefix = path.Join(pathPrefix, baseURL.Path)
    }
    r := &Request{
        client:      client,
        verb:        verb,
        baseURL:     baseURL,
        pathPrefix:  path.Join(pathPrefix, versionedAPIPath),
        content:     content,
        serializers: serializers,
        backoffMgr:  backoff,
        throttle:    throttle,
        timeout:     timeout,
    }
    switch {
    case len(content.AcceptContentTypes) > 0:
        r.SetHeader("Accept", content.AcceptContentTypes)
    case len(content.ContentType) > 0:
        r.SetHeader("Accept", content.ContentType+", */*")
    }
    return r
}

可以看到NewRequest最終將參數(shù)組成http請求參數(shù)進(jìn)行了http請求調(diào)用秫逝。至此clientset.CoreV1().Pods("").List(metav1.ListOptions{})調(diào)用完成恕出,最終將結(jié)果返回。

總結(jié)

client-go對kubernetes資源對象的調(diào)用操作违帆,需要先獲取kubernetes的配置信息浙巫,即$HOME/.kube/config。(master節(jié)點(diǎn))

具體流程如下圖所示:

client-go-request.png

client-go對k8s資源的調(diào)用

Service

Clientset.CoreV1().Services(nameSpace).Create(serviceObj)
Clientset.CoreV1().Services(nameSpace).Update(serviceObj)
Clientset.CoreV1().Services(nameSpace).Delete(serviceName, &meta_v1.DeleteOptions{})
Clientset.CoreV1().Services(nameSpace).Get(serviceName, meta_v1.GetOptions{})
Clientset.CoreV1().Services(nameSpace).List(meta_v1.ListOptions{})
Clientset.CoreV1().Services(nameSpace).Watch(meta_v1.ListOptions{})

Deployment

Clientset.AppsV1beta1().Deployments(nameSpace).Create(deploymentObj)
Clientset.AppsV1beta1().Deployments(nameSpace).Update(deploymentObj)
Clientset.AppsV1beta1().Deployments(nameSpace).Delete(deploymentName, &meta_v1.DeleteOptions{})
Clientset.AppsV1beta1().Deployments(nameSpace).Get(deploymentName, meta_v1.GetOptions{})
Clientset.AppsV1beta1().Deployments(nameSpace).List(meta_v1.ListOptions{})
Clientset.AppsV1beta1().Deployments(nameSpace).Watch(meta_v1.ListOptions{})

ReplicaSet

Clientset.ExtensionsV1beta1().ReplicaSets(nameSpace).Create(replicasetsObj)
Clientset.ExtensionsV1beta1().ReplicaSets(nameSpace).Update(replicasetsObj)
Clientset.ExtensionsV1beta1().ReplicaSets(nameSpace).Delete(replicaSetName, &meta_v1.DeleteOptions{})
Clientset.ExtensionsV1beta1().ReplicaSets(nameSpace).Get(replicaSetName, meta_v1.GetOptions{})
Clientset.ExtensionsV1beta1().ReplicaSets(nameSpace).List(meta_v1.ListOptions{})
Clientset.ExtensionsV1beta1().ReplicaSets(nameSpace).Watch(meta_v1.ListOptions{})

Ingresse

Clientset.ExtensionsV1beta1().Ingresses(nameSpace).Create(ingressObj)
Clientset.ExtensionsV1beta1().Ingresses(nameSpace).Update(ingressObj)
Clientset.ExtensionsV1beta1().Ingresses(nameSpace).Delete(ingressName, &meta_v1.DeleteOptions{})
Clientset.ExtensionsV1beta1().Ingresses(nameSpace).Get(ingressName, meta_v1.GetOptions{})
Clientset.ExtensionsV1beta1().Ingresses(nameSpace).List(meta_v1.ListOptions{})

StatefulSet

Clientset.AppsV1beta1().StatefulSets(nameSpace).Create(statefulSetObj)
Clientset.AppsV1beta1().StatefulSets(nameSpace).Update(statefulSetObj)
Clientset.AppsV1beta1().StatefulSets(nameSpace).Delete(statefulSetName, &meta_v1.DeleteOptions{})
Clientset.AppsV1beta1().StatefulSets(nameSpace).Get(statefulSetName, meta_v1.GetOptions{})
Clientset.AppsV1beta1().StatefulSets(nameSpace).List(meta_v1.ListOptions{})

DaemonSet

Clientset.ExtensionsV1beta1().DaemonSets(nameSpace).Create(daemonSetObj)
Clientset.ExtensionsV1beta1().DaemonSets(nameSpace).Update(daemonSetObj)
Clientset.ExtensionsV1beta1().DaemonSets(nameSpace).Delete(daemonSetName, &meta_v1.DeleteOptions{})
Clientset.ExtensionsV1beta1().DaemonSets(nameSpace).Get(daemonSetName, meta_v1.GetOptions{})
Clientset.ExtensionsV1beta1().DaemonSets(nameSpace).List(meta_v1.ListOptions{})

ReplicationController

Clientset.CoreV1().ReplicationControllers(nameSpace).Create(replicationControllerObj)
Clientset.CoreV1().ReplicationControllers(nameSpace).Update(replicationControllerObj)
Clientset.CoreV1().ReplicationControllers(nameSpace).Delete(replicationControllerName, &meta_v1.DeleteOptions{})
Clientset.CoreV1().ReplicationControllers(nameSpace).Get(replicationControllerName, meta_v1.GetOptions{})
Clientset.CoreV1().ReplicationControllers(nameSpace).List(meta_v1.ListOptions{})

Secret

Clientset.CoreV1().Secrets(nameSpace).Create(secretObj)
Clientset.CoreV1().Secrets(nameSpace).Update(secretObj)
Clientset.CoreV1().Secrets(nameSpace).Delete(secretName, &meta_v1.DeleteOptions{})
Clientset.CoreV1().Secrets(nameSpace).Get(secretName, meta_v1.GetOptions{})
Clientset.CoreV1().Secrets(nameSpace).List(meta_v1.ListOptions{})

ConfigMap

Clientset.CoreV1().ConfigMaps(nameSpace).Create(configMapObj)
Clientset.CoreV1().ConfigMaps(nameSpace).Update(configMapObj)
Clientset.CoreV1().ConfigMaps(nameSpace).Delete(configMapName, &meta_v1.DeleteOptions{})
Clientset.CoreV1().ConfigMaps(nameSpace).Get(configMapName, meta_v1.GetOptions{})
Clientset.CoreV1().ConfigMaps(nameSpace).List(meta_v1.ListOptions{})

Pod

Clientset.CoreV1().Pods(nameSpace).Get(podName, meta_v1.GetOptions{})
Clientset.CoreV1().Pods(nameSpace).List(meta_v1.ListOptions{})
Clientset.CoreV1().Pods(nameSpace).Delete(podName, &meta_v1.DeleteOptions{})

Namespace

Clientset.CoreV1().Namespaces().Create(nsSpec)
Clientset.CoreV1().Namespaces().Get(nameSpace, meta_v1.GetOptions{})
Clientset.CoreV1().Namespaces().List(meta_v1.ListOptions{})
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末刷后,一起剝皮案震驚了整個(gè)濱河市狈醉,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌惠险,老刑警劉巖苗傅,帶你破解...
    沈念sama閱讀 217,406評論 6 503
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異班巩,居然都是意外死亡渣慕,警方通過查閱死者的電腦和手機(jī)嘶炭,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,732評論 3 393
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來逊桦,“玉大人眨猎,你說我怎么就攤上這事∏烤” “怎么了睡陪?”我有些...
    開封第一講書人閱讀 163,711評論 0 353
  • 文/不壞的土叔 我叫張陵,是天一觀的道長匿情。 經(jīng)常有香客問我兰迫,道長,這世上最難降的妖魔是什么炬称? 我笑而不...
    開封第一講書人閱讀 58,380評論 1 293
  • 正文 為了忘掉前任汁果,我火速辦了婚禮,結(jié)果婚禮上玲躯,老公的妹妹穿的比我還像新娘据德。我一直安慰自己,他們只是感情好跷车,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,432評論 6 392
  • 文/花漫 我一把揭開白布棘利。 她就那樣靜靜地躺著,像睡著了一般朽缴。 火紅的嫁衣襯著肌膚如雪赡译。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 51,301評論 1 301
  • 那天不铆,我揣著相機(jī)與錄音蝌焚,去河邊找鬼。 笑死誓斥,一個(gè)胖子當(dāng)著我的面吹牛只洒,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播劳坑,決...
    沈念sama閱讀 40,145評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼毕谴,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了距芬?” 一聲冷哼從身側(cè)響起涝开,我...
    開封第一講書人閱讀 39,008評論 0 276
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎框仔,沒想到半個(gè)月后舀武,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,443評論 1 314
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡离斩,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,649評論 3 334
  • 正文 我和宋清朗相戀三年银舱,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了瘪匿。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 39,795評論 1 347
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡寻馏,死狀恐怖棋弥,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情诚欠,我是刑警寧澤顽染,帶...
    沈念sama閱讀 35,501評論 5 345
  • 正文 年R本政府宣布,位于F島的核電站轰绵,受9級特大地震影響粉寞,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜藏澳,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,119評論 3 328
  • 文/蒙蒙 一仁锯、第九天 我趴在偏房一處隱蔽的房頂上張望耀找。 院中可真熱鬧翔悠,春花似錦、人聲如沸野芒。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,731評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽狞悲。三九已至撮抓,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間摇锋,已是汗流浹背丹拯。 一陣腳步聲響...
    開封第一講書人閱讀 32,865評論 1 269
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留荸恕,地道東北人乖酬。 一個(gè)月前我還...
    沈念sama閱讀 47,899評論 2 370
  • 正文 我出身青樓,卻偏偏與公主長得像融求,于是被迫代替她去往敵國和親咬像。 傳聞我的和親對象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,724評論 2 354

推薦閱讀更多精彩內(nèi)容