• 1. client-go简介
    • 1.1 client-go说明
    • 1.2 示例代码
    • 1.3 运行结果
  • 2. client-go源码分析
    • 2.1 kubeconfig
    • 2.2 rest.config
    • 2.3 clientset
      • 2.3.1 NewForConfig
      • 2.3.2 clientset的结构体
      • 2.3.3 clientset.Interface
    • 2.4 CoreV1Client
      • 2.4.1 corev1.NewForConfig
      • 2.4.2 CoreV1Client结构体
      • 2.4.3 CoreV1Interface
      • 2.4.4 PodsGetter
    • 2.5 RESTClient
      • 2.5.1 rest.RESTClientFor
      • 2.5.2 NewRESTClient
      • 2.5.3 RESTClient结构体
      • 2.5.4 RESTClient.Interface
    • 2.6 总结
  • 3. client-go对k8s资源的调用
    • 3.1 deployment
    • 3.2 service
    • 3.3 ingress
    • 3.4 replicaSet
    • 3.5 pod
    • 3.6 statefulset

    本文个人博客地址:http://www.huweihuang.com/article/source-analysis/client-go-source-analysis/

    1. client-go简介

    1.1 client-go说明

    ​ client-go是一个调用kubernetes集群资源对象API的客户端,即通过client-go实现对kubernetes集群中资源对象(包括deployment、service、ingress、replicaSet、pod、namespace、node等)的增删改查等操作。大部分对kubernetes进行前置API封装的二次开发都通过client-go这个第三方包来实现。

    ​ client-go官方文档:https://github.com/kubernetes/client-go

    1.2 示例代码

    1. git clone https://github.com/huweihuang/client-go.git
    2. cd client-go
    3. #保证本地HOME目录有配置kubernetes集群的配置文件
    4. go run client-go.go

    client-go.go

    1. package main
    2. import (
    3. "flag"
    4. "fmt"
    5. "os"
    6. "path/filepath"
    7. "time"
    8. metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
    9. "k8s.io/client-go/kubernetes"
    10. "k8s.io/client-go/tools/clientcmd"
    11. )
    12. func main() {
    13. var kubeconfig *string
    14. if home := homeDir(); home != "" {
    15. kubeconfig = flag.String("kubeconfig", filepath.Join(home, ".kube", "config"), "(optional) absolute path to the kubeconfig file")
    16. } else {
    17. kubeconfig = flag.String("kubeconfig", "", "absolute path to the kubeconfig file")
    18. }
    19. flag.Parse()
    20. // uses the current context in kubeconfig
    21. config, err := clientcmd.BuildConfigFromFlags("", *kubeconfig)
    22. if err != nil {
    23. panic(err.Error())
    24. }
    25. // creates the clientset
    26. clientset, err := kubernetes.NewForConfig(config)
    27. if err != nil {
    28. panic(err.Error())
    29. }
    30. for {
    31. pods, err := clientset.CoreV1().Pods("").List(metav1.ListOptions{})
    32. if err != nil {
    33. panic(err.Error())
    34. }
    35. fmt.Printf("There are %d pods in the cluster\n", len(pods.Items))
    36. time.Sleep(10 * time.Second)
    37. }
    38. }
    39. func homeDir() string {
    40. if h := os.Getenv("HOME"); h != "" {
    41. return h
    42. }
    43. return os.Getenv("USERPROFILE") // windows
    44. }

    1.3 运行结果

    1. go run client-go.go
    2. There are 9 pods in the cluster
    3. There are 7 pods in the cluster
    4. There are 7 pods in the cluster
    5. There are 7 pods in the cluster
    6. There are 7 pods in the cluster

    2. client-go源码分析

    client-go源码:https://github.com/kubernetes/client-go

    client-go源码目录结构

    • 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.

    2.1 kubeconfig

    1. kubeconfig = flag.String("kubeconfig", filepath.Join(home, ".kube", "config"), "(optional) absolute path to the kubeconfig file")

    获取kubernetes配置文件kubeconfig的绝对路径。一般路径为$HOME/.kube/config。该文件主要用来配置本地连接的kubernetes集群。

    config内容如下:

    1. apiVersion: v1
    2. clusters:
    3. - cluster:
    4. server: http://<kube-master-ip>:8080
    5. name: k8s
    6. contexts:
    7. - context:
    8. cluster: k8s
    9. namespace: default
    10. user: ""
    11. name: default
    12. current-context: default
    13. kind: Config
    14. preferences: {}
    15. users: []

    2.2 rest.config

    通过参数(master的url或者kubeconfig路径)和BuildConfigFromFlags方法来获取rest.Config对象,一般是通过参数kubeconfig的路径。

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

    BuildConfigFromFlags函数源码

    k8s.io/client-go/tools/clientcmd/client_config.go

    1. // BuildConfigFromFlags is a helper function that builds configs from a master
    2. // url or a kubeconfig filepath. These are passed in as command line flags for cluster
    3. // components. Warnings should reflect this usage. If neither masterUrl or kubeconfigPath
    4. // are passed in we fallback to inClusterConfig. If inClusterConfig fails, we fallback
    5. // to the default config.
    6. func BuildConfigFromFlags(masterUrl, kubeconfigPath string) (*restclient.Config, error) {
    7. if kubeconfigPath == "" && masterUrl == "" {
    8. glog.Warningf("Neither --kubeconfig nor --master was specified. Using the inClusterConfig. This might not work.")
    9. kubeconfig, err := restclient.InClusterConfig()
    10. if err == nil {
    11. return kubeconfig, nil
    12. }
    13. glog.Warning("error creating inClusterConfig, falling back to default config: ", err)
    14. }
    15. return NewNonInteractiveDeferredLoadingClientConfig(
    16. &ClientConfigLoadingRules{ExplicitPath: kubeconfigPath},
    17. &ConfigOverrides{ClusterInfo: clientcmdapi.Cluster{Server: masterUrl}}).ClientConfig()
    18. }

    2.3 clientset

    通过*rest.Config参数和NewForConfig方法来获取clientset对象,clientset是多个client的集合,每个client可能包含不同版本的方法调用。

    1. clientset, err := kubernetes.NewForConfig(config)

    2.3.1 NewForConfig

    NewForConfig函数就是初始化clientset中的每个client。

    k8s.io/client-go/kubernetes/clientset.go

    1. // NewForConfig creates a new Clientset for the given config.
    2. func NewForConfig(c *rest.Config) (*Clientset, error) {
    3. configShallowCopy := *c
    4. ...
    5. var cs Clientset
    6. cs.appsV1beta1, err = appsv1beta1.NewForConfig(&configShallowCopy)
    7. ...
    8. cs.coreV1, err = corev1.NewForConfig(&configShallowCopy)
    9. ...
    10. }

    2.3.2 clientset的结构体

    k8s.io/client-go/kubernetes/clientset.go

    1. // Clientset contains the clients for groups. Each group has exactly one
    2. // version included in a Clientset.
    3. type Clientset struct {
    4. *discovery.DiscoveryClient
    5. admissionregistrationV1alpha1 *admissionregistrationv1alpha1.AdmissionregistrationV1alpha1Client
    6. appsV1beta1 *appsv1beta1.AppsV1beta1Client
    7. appsV1beta2 *appsv1beta2.AppsV1beta2Client
    8. authenticationV1 *authenticationv1.AuthenticationV1Client
    9. authenticationV1beta1 *authenticationv1beta1.AuthenticationV1beta1Client
    10. authorizationV1 *authorizationv1.AuthorizationV1Client
    11. authorizationV1beta1 *authorizationv1beta1.AuthorizationV1beta1Client
    12. autoscalingV1 *autoscalingv1.AutoscalingV1Client
    13. autoscalingV2beta1 *autoscalingv2beta1.AutoscalingV2beta1Client
    14. batchV1 *batchv1.BatchV1Client
    15. batchV1beta1 *batchv1beta1.BatchV1beta1Client
    16. batchV2alpha1 *batchv2alpha1.BatchV2alpha1Client
    17. certificatesV1beta1 *certificatesv1beta1.CertificatesV1beta1Client
    18. coreV1 *corev1.CoreV1Client
    19. extensionsV1beta1 *extensionsv1beta1.ExtensionsV1beta1Client
    20. networkingV1 *networkingv1.NetworkingV1Client
    21. policyV1beta1 *policyv1beta1.PolicyV1beta1Client
    22. rbacV1 *rbacv1.RbacV1Client
    23. rbacV1beta1 *rbacv1beta1.RbacV1beta1Client
    24. rbacV1alpha1 *rbacv1alpha1.RbacV1alpha1Client
    25. schedulingV1alpha1 *schedulingv1alpha1.SchedulingV1alpha1Client
    26. settingsV1alpha1 *settingsv1alpha1.SettingsV1alpha1Client
    27. storageV1beta1 *storagev1beta1.StorageV1beta1Client
    28. storageV1 *storagev1.StorageV1Client
    29. }

    2.3.3 clientset.Interface

    clientset实现了以下的Interface,因此可以通过调用以下方法获得具体的client。例如:

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

    clientset的方法集接口

    k8s.io/client-go/kubernetes/clientset.go

    1. type Interface interface {
    2. Discovery() discovery.DiscoveryInterface
    3. AdmissionregistrationV1alpha1() admissionregistrationv1alpha1.AdmissionregistrationV1alpha1Interface
    4. // Deprecated: please explicitly pick a version if possible.
    5. Admissionregistration() admissionregistrationv1alpha1.AdmissionregistrationV1alpha1Interface
    6. AppsV1beta1() appsv1beta1.AppsV1beta1Interface
    7. AppsV1beta2() appsv1beta2.AppsV1beta2Interface
    8. // Deprecated: please explicitly pick a version if possible.
    9. Apps() appsv1beta2.AppsV1beta2Interface
    10. AuthenticationV1() authenticationv1.AuthenticationV1Interface
    11. // Deprecated: please explicitly pick a version if possible.
    12. Authentication() authenticationv1.AuthenticationV1Interface
    13. AuthenticationV1beta1() authenticationv1beta1.AuthenticationV1beta1Interface
    14. AuthorizationV1() authorizationv1.AuthorizationV1Interface
    15. // Deprecated: please explicitly pick a version if possible.
    16. Authorization() authorizationv1.AuthorizationV1Interface
    17. AuthorizationV1beta1() authorizationv1beta1.AuthorizationV1beta1Interface
    18. AutoscalingV1() autoscalingv1.AutoscalingV1Interface
    19. // Deprecated: please explicitly pick a version if possible.
    20. Autoscaling() autoscalingv1.AutoscalingV1Interface
    21. AutoscalingV2beta1() autoscalingv2beta1.AutoscalingV2beta1Interface
    22. BatchV1() batchv1.BatchV1Interface
    23. // Deprecated: please explicitly pick a version if possible.
    24. Batch() batchv1.BatchV1Interface
    25. BatchV1beta1() batchv1beta1.BatchV1beta1Interface
    26. BatchV2alpha1() batchv2alpha1.BatchV2alpha1Interface
    27. CertificatesV1beta1() certificatesv1beta1.CertificatesV1beta1Interface
    28. // Deprecated: please explicitly pick a version if possible.
    29. Certificates() certificatesv1beta1.CertificatesV1beta1Interface
    30. CoreV1() corev1.CoreV1Interface
    31. // Deprecated: please explicitly pick a version if possible.
    32. Core() corev1.CoreV1Interface
    33. ExtensionsV1beta1() extensionsv1beta1.ExtensionsV1beta1Interface
    34. // Deprecated: please explicitly pick a version if possible.
    35. Extensions() extensionsv1beta1.ExtensionsV1beta1Interface
    36. NetworkingV1() networkingv1.NetworkingV1Interface
    37. // Deprecated: please explicitly pick a version if possible.
    38. Networking() networkingv1.NetworkingV1Interface
    39. PolicyV1beta1() policyv1beta1.PolicyV1beta1Interface
    40. // Deprecated: please explicitly pick a version if possible.
    41. Policy() policyv1beta1.PolicyV1beta1Interface
    42. RbacV1() rbacv1.RbacV1Interface
    43. // Deprecated: please explicitly pick a version if possible.
    44. Rbac() rbacv1.RbacV1Interface
    45. RbacV1beta1() rbacv1beta1.RbacV1beta1Interface
    46. RbacV1alpha1() rbacv1alpha1.RbacV1alpha1Interface
    47. SchedulingV1alpha1() schedulingv1alpha1.SchedulingV1alpha1Interface
    48. // Deprecated: please explicitly pick a version if possible.
    49. Scheduling() schedulingv1alpha1.SchedulingV1alpha1Interface
    50. SettingsV1alpha1() settingsv1alpha1.SettingsV1alpha1Interface
    51. // Deprecated: please explicitly pick a version if possible.
    52. Settings() settingsv1alpha1.SettingsV1alpha1Interface
    53. StorageV1beta1() storagev1beta1.StorageV1beta1Interface
    54. StorageV1() storagev1.StorageV1Interface
    55. // Deprecated: please explicitly pick a version if possible.
    56. Storage() storagev1.StorageV1Interface
    57. }

    2.4 CoreV1Client

    我们以clientset中的CoreV1Client为例做分析。

    通过传入的配置信息rest.Config初始化CoreV1Client对象。

    k8s.io/client-go/kubernetes/clientset.go

    1. cs.coreV1, err = corev1.NewForConfig(&configShallowCopy)

    2.4.1 corev1.NewForConfig

    k8s.io/client-go/kubernetes/typed/core/v1/core_client.go

    1. // NewForConfig creates a new CoreV1Client for the given config.
    2. func NewForConfig(c *rest.Config) (*CoreV1Client, error) {
    3. config := *c
    4. if err := setConfigDefaults(&config); err != nil {
    5. return nil, err
    6. }
    7. client, err := rest.RESTClientFor(&config)
    8. if err != nil {
    9. return nil, err
    10. }
    11. return &CoreV1Client{client}, nil
    12. }

    corev1.NewForConfig方法本质是调用了rest.RESTClientFor(&config)方法创建RESTClient对象,即CoreV1Client的本质就是一个RESTClient对象。

    2.4.2 CoreV1Client结构体

    以下是CoreV1Client结构体的定义:

    k8s.io/client-go/kubernetes/typed/core/v1/core_client.go

    1. // CoreV1Client is used to interact with features provided by the group.
    2. type CoreV1Client struct {
    3. restClient rest.Interface
    4. }

    CoreV1Client实现了CoreV1Interface的接口,即以下方法,从而对kubernetes的资源对象进行增删改查的操作。

    k8s.io/client-go/kubernetes/typed/core/v1/core_client.go

    1. //CoreV1Client的方法
    2. func (c *CoreV1Client) ComponentStatuses() ComponentStatusInterface {...}
    3. //ConfigMaps
    4. func (c *CoreV1Client) ConfigMaps(namespace string) ConfigMapInterface {...}
    5. //Endpoints
    6. func (c *CoreV1Client) Endpoints(namespace string) EndpointsInterface {...}
    7. func (c *CoreV1Client) Events(namespace string) EventInterface {...}
    8. func (c *CoreV1Client) LimitRanges(namespace string) LimitRangeInterface {...}
    9. //Namespaces
    10. func (c *CoreV1Client) Namespaces() NamespaceInterface {...}
    11. //Nodes
    12. func (c *CoreV1Client) Nodes() NodeInterface {...}
    13. func (c *CoreV1Client) PersistentVolumes() PersistentVolumeInterface {...}
    14. func (c *CoreV1Client) PersistentVolumeClaims(namespace string) PersistentVolumeClaimInterface {...}
    15. //Pods
    16. func (c *CoreV1Client) Pods(namespace string) PodInterface {...}
    17. func (c *CoreV1Client) PodTemplates(namespace string) PodTemplateInterface {...}
    18. //ReplicationControllers
    19. func (c *CoreV1Client) ReplicationControllers(namespace string) ReplicationControllerInterface {...}
    20. func (c *CoreV1Client) ResourceQuotas(namespace string) ResourceQuotaInterface {...}
    21. func (c *CoreV1Client) Secrets(namespace string) SecretInterface {...}
    22. //Services
    23. func (c *CoreV1Client) Services(namespace string) ServiceInterface {...}
    24. func (c *CoreV1Client) ServiceAccounts(namespace string) ServiceAccountInterface {...}

    2.4.3 CoreV1Interface

    k8s.io/client-go/kubernetes/typed/core/v1/core_client.go

    1. type CoreV1Interface interface {
    2. RESTClient() rest.Interface
    3. ComponentStatusesGetter
    4. ConfigMapsGetter
    5. EndpointsGetter
    6. EventsGetter
    7. LimitRangesGetter
    8. NamespacesGetter
    9. NodesGetter
    10. PersistentVolumesGetter
    11. PersistentVolumeClaimsGetter
    12. PodsGetter
    13. PodTemplatesGetter
    14. ReplicationControllersGetter
    15. ResourceQuotasGetter
    16. SecretsGetter
    17. ServicesGetter
    18. ServiceAccountsGetter
    19. }

    CoreV1Interface中包含了各种kubernetes对象的调用接口,例如PodsGetter是对kubernetes中pod对象增删改查操作的接口。ServicesGetter是对service对象的操作的接口。

    2.4.4 PodsGetter

    以下我们以PodsGetter接口为例分析CoreV1Clientpod对象的增删改查接口调用。

    示例中的代码如下:

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

    CoreV1().Pods()

    k8s.io/client-go/kubernetes/typed/core/v1/core_client.go

    1. func (c *CoreV1Client) Pods(namespace string) PodInterface {
    2. return newPods(c, namespace)
    3. }

    newPods()

    k8s.io/client-go/kubernetes/typed/core/v1/pod.go

    1. // newPods returns a Pods
    2. func newPods(c *CoreV1Client, namespace string) *pods {
    3. return &pods{
    4. client: c.RESTClient(),
    5. ns: namespace,
    6. }
    7. }

    CoreV1().Pods()的方法实际上是调用了newPods()的方法,创建了一个pods对象,pods对象继承了rest.Interface接口,即最终的实现本质是RESTClient的HTTP调用。

    k8s.io/client-go/kubernetes/typed/core/v1/pod.go

    1. // pods implements PodInterface
    2. type pods struct {
    3. client rest.Interface
    4. ns string
    5. }

    pods对象实现了PodInterface接口。PodInterface定义了pods对象的增删改查等方法。

    k8s.io/client-go/kubernetes/typed/core/v1/pod.go

    1. // PodInterface has methods to work with Pod resources.
    2. type PodInterface interface {
    3. Create(*v1.Pod) (*v1.Pod, error)
    4. Update(*v1.Pod) (*v1.Pod, error)
    5. UpdateStatus(*v1.Pod) (*v1.Pod, error)
    6. Delete(name string, options *meta_v1.DeleteOptions) error
    7. DeleteCollection(options *meta_v1.DeleteOptions, listOptions meta_v1.ListOptions) error
    8. Get(name string, options meta_v1.GetOptions) (*v1.Pod, error)
    9. List(opts meta_v1.ListOptions) (*v1.PodList, error)
    10. Watch(opts meta_v1.ListOptions) (watch.Interface, error)
    11. Patch(name string, pt types.PatchType, data []byte, subresources ...string) (result *v1.Pod, err error)
    12. PodExpansion
    13. }

    PodsGetter

    PodsGetter继承了PodInterface的接口。

    k8s.io/client-go/kubernetes/typed/core/v1/pod.go

    1. // PodsGetter has a method to return a PodInterface.
    2. // A group's client should implement this interface.
    3. type PodsGetter interface {
    4. Pods(namespace string) PodInterface
    5. }

    Pods().List()

    pods.List()方法通过RESTClient的HTTP调用来实现对kubernetes的pod资源的获取。

    k8s.io/client-go/kubernetes/typed/core/v1/pod.go

    1. // List takes label and field selectors, and returns the list of Pods that match those selectors.
    2. func (c *pods) List(opts meta_v1.ListOptions) (result *v1.PodList, err error) {
    3. result = &v1.PodList{}
    4. err = c.client.Get().
    5. Namespace(c.ns).
    6. Resource("pods").
    7. VersionedParams(&opts, scheme.ParameterCodec).
    8. Do().
    9. Into(result)
    10. return
    11. }

    以上分析了clientset.CoreV1().Pods("").List(metav1.ListOptions{})对pod资源获取的过程,最终是调用RESTClient的方法实现。

    2.5 RESTClient

    以下分析RESTClient的创建过程及作用。

    RESTClient对象的创建同样是依赖传入的config信息。

    k8s.io/client-go/kubernetes/typed/core/v1/core_client.go

    1. client, err := rest.RESTClientFor(&config)

    2.5.1 rest.RESTClientFor

    k8s.io/client-go/rest/config.go

    1. // RESTClientFor returns a RESTClient that satisfies the requested attributes on a client Config
    2. // object. Note that a RESTClient may require fields that are optional when initializing a Client.
    3. // A RESTClient created by this method is generic - it expects to operate on an API that follows
    4. // the Kubernetes conventions, but may not be the Kubernetes API.
    5. func RESTClientFor(config *Config) (*RESTClient, error) {
    6. ...
    7. qps := config.QPS
    8. ...
    9. burst := config.Burst
    10. ...
    11. baseURL, versionedAPIPath, err := defaultServerUrlFor(config)
    12. ...
    13. transport, err := TransportFor(config)
    14. ...
    15. var httpClient *http.Client
    16. if transport != http.DefaultTransport {
    17. httpClient = &http.Client{Transport: transport}
    18. if config.Timeout > 0 {
    19. httpClient.Timeout = config.Timeout
    20. }
    21. }
    22. return NewRESTClient(baseURL, versionedAPIPath, config.ContentConfig, qps, burst, config.RateLimiter, httpClient)
    23. }

    RESTClientFor函数调用了NewRESTClient的初始化函数。

    2.5.2 NewRESTClient

    k8s.io/client-go/rest/client.go

    1. // NewRESTClient creates a new RESTClient. This client performs generic REST functions
    2. // such as Get, Put, Post, and Delete on specified paths. Codec controls encoding and
    3. // decoding of responses from the server.
    4. func NewRESTClient(baseURL *url.URL, versionedAPIPath string, config ContentConfig, maxQPS float32, maxBurst int, rateLimiter flowcontrol.RateLimiter, client *http.Client) (*RESTClient, error) {
    5. base := *baseURL
    6. ...
    7. serializers, err := createSerializers(config)
    8. ...
    9. return &RESTClient{
    10. base: &base,
    11. versionedAPIPath: versionedAPIPath,
    12. contentConfig: config,
    13. serializers: *serializers,
    14. createBackoffMgr: readExpBackoffConfig,
    15. Throttle: throttle,
    16. Client: client,
    17. }, nil
    18. }

    2.5.3 RESTClient结构体

    以下介绍RESTClient的结构体定义,RESTClient结构体中包含了http.Client,即本质上RESTClient就是一个http.Client的封装实现。

    k8s.io/client-go/rest/client.go

    1. // RESTClient imposes common Kubernetes API conventions on a set of resource paths.
    2. // The baseURL is expected to point to an HTTP or HTTPS path that is the parent
    3. // of one or more resources. The server should return a decodable API resource
    4. // object, or an api.Status object which contains information about the reason for
    5. // any failure.
    6. //
    7. // Most consumers should use client.New() to get a Kubernetes API client.
    8. type RESTClient struct {
    9. // base is the root URL for all invocations of the client
    10. base *url.URL
    11. // versionedAPIPath is a path segment connecting the base URL to the resource root
    12. versionedAPIPath string
    13. // contentConfig is the information used to communicate with the server.
    14. contentConfig ContentConfig
    15. // serializers contain all serializers for underlying content type.
    16. serializers Serializers
    17. // creates BackoffManager that is passed to requests.
    18. createBackoffMgr func() BackoffManager
    19. // TODO extract this into a wrapper interface via the RESTClient interface in kubectl.
    20. Throttle flowcontrol.RateLimiter
    21. // Set specific behavior of the client. If not set http.DefaultClient will be used.
    22. Client *http.Client
    23. }

    2.5.4 RESTClient.Interface

    RESTClient实现了以下的接口方法:

    k8s.io/client-go/rest/client.go

    1. // Interface captures the set of operations for generically interacting with Kubernetes REST apis.
    2. type Interface interface {
    3. GetRateLimiter() flowcontrol.RateLimiter
    4. Verb(verb string) *Request
    5. Post() *Request
    6. Put() *Request
    7. Patch(pt types.PatchType) *Request
    8. Get() *Request
    9. Delete() *Request
    10. APIVersion() schema.GroupVersion
    11. }

    在调用HTTP方法(Post(),Put(),Get(),Delete() )时,实际上调用了Verb(verb string)函数。

    k8s.io/client-go/rest/client.go

    1. // Verb begins a request with a verb (GET, POST, PUT, DELETE).
    2. //
    3. // Example usage of RESTClient's request building interface:
    4. // c, err := NewRESTClient(...)
    5. // if err != nil { ... }
    6. // resp, err := c.Verb("GET").
    7. // Path("pods").
    8. // SelectorParam("labels", "area=staging").
    9. // Timeout(10*time.Second).
    10. // Do()
    11. // if err != nil { ... }
    12. // list, ok := resp.(*api.PodList)
    13. //
    14. func (c *RESTClient) Verb(verb string) *Request {
    15. backoff := c.createBackoffMgr()
    16. if c.Client == nil {
    17. return NewRequest(nil, verb, c.base, c.versionedAPIPath, c.contentConfig, c.serializers, backoff, c.Throttle)
    18. }
    19. return NewRequest(c.Client, verb, c.base, c.versionedAPIPath, c.contentConfig, c.serializers, backoff, c.Throttle)
    20. }

    Verb函数调用了NewRequest方法,最后调用Do()方法实现一个HTTP请求获取Result。

    2.6 总结

    client-go对kubernetes资源对象的调用,需要先获取kubernetes的配置信息,即$HOME/.kube/config

    整个调用的过程如下:

    kubeconfig→rest.config→clientset→具体的client(CoreV1Client)→具体的资源对象(pod)→RESTClient→http.Client→HTTP请求的发送及响应

    通过clientset中不同的client和client中不同资源对象的方法实现对kubernetes中资源对象的增删改查等操作,常用的client有CoreV1ClientAppsV1beta1ClientExtensionsV1beta1Client等。

    3. client-go对k8s资源的调用

    创建clientset

    1. //获取kubeconfig
    2. kubeconfig = flag.String("kubeconfig", filepath.Join(home, ".kube", "config"), "(optional) absolute path to the kubeconfig file")
    3. //创建config
    4. config, err := clientcmd.BuildConfigFromFlags("", *kubeconfig)
    5. //创建clientset
    6. clientset, err := kubernetes.NewForConfig(config)
    7. //具体的资源调用见以下例子

    3.1 deployment

    1. //声明deployment对象
    2. var deployment *v1beta1.Deployment
    3. //构造deployment对象
    4. //创建deployment
    5. deployment, err := clientset.AppsV1beta1().Deployments(<namespace>).Create(<deployment>)
    6. //更新deployment
    7. deployment, err := clientset.AppsV1beta1().Deployments(<namespace>).Update(<deployment>)
    8. //删除deployment
    9. err := clientset.AppsV1beta1().Deployments(<namespace>).Delete(<deployment.Name>, &meta_v1.DeleteOptions{})
    10. //查询deployment
    11. deployment, err := clientset.AppsV1beta1().Deployments(<namespace>).Get(<deployment.Name>, meta_v1.GetOptions{})
    12. //列出deployment
    13. deploymentList, err := clientset.AppsV1beta1().Deployments(<namespace>).List(&meta_v1.ListOptions{})
    14. //watch deployment
    15. watchInterface, err := clientset.AppsV1beta1().Deployments(<namespace>).Watch(&meta_v1.ListOptions{})

    3.2 service

    1. //声明service对象
    2. var service *v1.Service
    3. //构造service对象
    4. //创建service
    5. service, err := clientset.CoreV1().Services(<namespace>).Create(<service>)
    6. //更新service
    7. service, err := clientset.CoreV1().Services(<namespace>).Update(<service>)
    8. //删除service
    9. err := clientset.CoreV1().Services(<namespace>).Delete(<service.Name>, &meta_v1.DeleteOptions{})
    10. //查询service
    11. service, err := clientset.CoreV1().Services(<namespace>).Get(<service.Name>, meta_v1.GetOptions{})
    12. //列出service
    13. serviceList, err := clientset.CoreV1().Services(<namespace>).List(&meta_v1.ListOptions{})
    14. //watch service
    15. watchInterface, err := clientset.CoreV1().Services(<namespace>).Watch(&meta_v1.ListOptions{})

    3.3 ingress

    1. //声明ingress对象
    2. var ingress *v1beta1.Ingress
    3. //构造ingress对象
    4. //创建ingress
    5. ingress, err := clientset.ExtensionsV1beta1().Ingresses(<namespace>).Create(<ingress>)
    6. //更新ingress
    7. ingress, err := clientset.ExtensionsV1beta1().Ingresses(<namespace>).Update(<ingress>)
    8. //删除ingress
    9. err := clientset.ExtensionsV1beta1().Ingresses(<namespace>).Delete(<ingress.Name>, &meta_v1.DeleteOptions{})
    10. //查询ingress
    11. ingress, err := clientset.ExtensionsV1beta1().Ingresses(<namespace>).Get(<ingress.Name>, meta_v1.GetOptions{})
    12. //列出ingress
    13. ingressList, err := clientset.ExtensionsV1beta1().Ingresses(<namespace>).List(&meta_v1.ListOptions{})
    14. //watch ingress
    15. watchInterface, err := clientset.ExtensionsV1beta1().Ingresses(<namespace>).Watch(&meta_v1.ListOptions{})

    3.4 replicaSet

    1. //声明replicaSet对象
    2. var replicaSet *v1beta1.ReplicaSet
    3. //构造replicaSet对象
    4. //创建replicaSet
    5. replicaSet, err := clientset.ExtensionsV1beta1().ReplicaSets(<namespace>).Create(<replicaSet>)
    6. //更新replicaSet
    7. replicaSet, err := clientset.ExtensionsV1beta1().ReplicaSets(<namespace>).Update(<replicaSet>)
    8. //删除replicaSet
    9. err := clientset.ExtensionsV1beta1().ReplicaSets(<namespace>).Delete(<replicaSet.Name>, &meta_v1.DeleteOptions{})
    10. //查询replicaSet
    11. replicaSet, err := clientset.ExtensionsV1beta1().ReplicaSets(<namespace>).Get(<replicaSet.Name>, meta_v1.GetOptions{})
    12. //列出replicaSet
    13. replicaSetList, err := clientset.ExtensionsV1beta1().ReplicaSets(<namespace>).List(&meta_v1.ListOptions{})
    14. //watch replicaSet
    15. watchInterface, err := clientset.ExtensionsV1beta1().ReplicaSets(<namespace>).Watch(&meta_v1.ListOptions{})

    新版的kubernetes中一般通过deployment来创建replicaSet,再通过replicaSet来控制pod。

    3.5 pod

    1. //声明pod对象
    2. var pod *v1.Pod
    3. //创建pod
    4. pod, err := clientset.CoreV1().Pods(<namespace>).Create(<pod>)
    5. //更新pod
    6. pod, err := clientset.CoreV1().Pods(<namespace>).Update(<pod>)
    7. //删除pod
    8. err := clientset.CoreV1().Pods(<namespace>).Delete(<pod.Name>, &meta_v1.DeleteOptions{})
    9. //查询pod
    10. pod, err := clientset.CoreV1().Pods(<namespace>).Get(<pod.Name>, meta_v1.GetOptions{})
    11. //列出pod
    12. podList, err := clientset.CoreV1().Pods(<namespace>).List(&meta_v1.ListOptions{})
    13. //watch pod
    14. watchInterface, err := clientset.CoreV1().Pods(<namespace>).Watch(&meta_v1.ListOptions{})

    3.6 statefulset

    1. //声明statefulset对象
    2. var statefulset *v1.StatefulSet
    3. //创建statefulset
    4. statefulset, err := clientset.AppsV1().StatefulSets(<namespace>).Create(<statefulset>)
    5. //更新statefulset
    6. statefulset, err := clientset.AppsV1().StatefulSets(<namespace>).Update(<statefulset>)
    7. //删除statefulset
    8. err := clientset.AppsV1().StatefulSets(<namespace>).Delete(<statefulset.Name>, &meta_v1.DeleteOptions{})
    9. //查询statefulset
    10. statefulset, err := clientset.AppsV1().StatefulSets(<namespace>).Get(<statefulset.Name>, meta_v1.GetOptions{})
    11. //列出statefulset
    12. statefulsetList, err := clientset.AppsV1().StatefulSets(<namespace>).List(&meta_v1.ListOptions{})
    13. //watch statefulset
    14. watchInterface, err := clientset.AppsV1().StatefulSets(<namespace>).Watch(&meta_v1.ListOptions{})

    ​ 通过以上对kubernetes的资源对象的操作函数可以看出,每个资源对象都有增删改查等方法,基本调用逻辑类似。一般二次开发只需要创建deployment、service、ingress三个资源对象即可,pod对象由deployment包含的replicaSet来控制创建和删除。函数调用的入参一般只有NAMESPACEkubernetesObject两个参数,部分操作有Options的参数。在创建前,需要对资源对象构造数据,可以理解为编辑一个资源对象的yaml文件,然后通过kubectl create -f xxx.yaml来创建对象。

    参考文档:

    • https://github.com/kubernetes/client-go