Welcome to my GitHub

https://github.com/zq2599/blog_demos

Content: Classification and summary of all original articles and supporting source code, involving Java, Docker, Kubernetes, DevOPS, etc.;

About DiscoveryClient

  • This article is the fifth in the "client-go combat" series. The protagonist is the last type of client: DiscoveryClient. The Clientset and dynamicClient we learned before are resource-oriented objects (such as creating deployment instances, viewing pod instances), and DiscoveryClient It is different. It focuses on resources, such as checking which Group, Version, and Resource currently have in kubernetes. Below are the fields and associated methods of the DiscoveryClient data structure. Once again, I saw the familiar restClient fields, and there are many other methods that are related to Group and Version. , Resource related:

在这里插入图片描述

  • As can be seen from the above figure, the DiscoveryClient data structure has two fields: restClient and LegacyPrefix. What is this <font color="blue">LegacyPrefix</font>? Let’s take a look at the method of creating a new DiscoveryClient instance, as shown in the red box below. It turned out to be a fixed string <font color="red">/api</font>, which looks like a part of the url:

在这里插入图片描述

  • Take a look at the associated method of DiscoveryClient, as shown in the red box in the figure below. Sure enough, LegacyPrefix is part of the url:

在这里插入图片描述

  • Compared with several other clients, DiscoveryClient is simpler, so let's fight directly!

Demand confirmation

  • The requirements for this actual combat are very simple: query all Group, Version, and Resource information from kubernetes, and print it out on the console;

Source download

namelinkRemarks
Project homepagehttps://github.com/zq2599/blog_demosThe project's homepage on GitHub
git warehouse address (https)https://github.com/zq2599/blog_demos.gitThe warehouse address of the source code of the project, https protocol
git warehouse address (ssh)git@github.com:zq2599/blog_demos.gitThe warehouse address of the source code of the project, ssh protocol
  • There are multiple folders in this git project, and client-go related applications are under the <font color="blue">client-go-tutorials</font> folder, as shown in the red box in the following figure:

在这里插入图片描述

  • There are multiple subfolders under the client-go-tutorials folder. The corresponding source code of this article is under the <font color="blue">discoveryclientdemo</font> directory, as shown in the red box below:

在这里插入图片描述

coding

  • Create a new folder discoveryclientdemo, execute the following command in it to create a new module:
go mod init discoveryclientdemo
  • Add the two dependencies of k8s.io/api and k8s.io/client-go. Note that the version must match the kubernetes environment:
go get k8s.io/api@v0.20.0
go get k8s.io/client-go@v0.20.0
  • Create a new main.go. The content is as follows. There are detailed comments inside. The second return value of the ServerGroupsAndResources method should be focused on. There are slices in its data structure, and there are slices in each element of the slice. This is each Information about resources:
package main

import (
    "flag"
    "fmt"
    "k8s.io/apimachinery/pkg/runtime/schema"
    "k8s.io/client-go/discovery"
    "k8s.io/client-go/tools/clientcmd"
    "k8s.io/client-go/util/homedir"
    "path/filepath"
)

func main() {

    var kubeconfig *string

    // home是家目录,如果能取得家目录的值,就可以用来做默认值
    if home:=homedir.HomeDir(); home != "" {
        // 如果输入了kubeconfig参数,该参数的值就是kubeconfig文件的绝对路径,
        // 如果没有输入kubeconfig参数,就用默认路径~/.kube/config
        kubeconfig = 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")
    }

    flag.Parse()

    // 从本机加载kubeconfig配置文件,因此第一个参数为空字符串
    config, err := clientcmd.BuildConfigFromFlags("", *kubeconfig)

    // kubeconfig加载失败就直接退出了
    if err != nil {
        panic(err.Error())
    }

    // 新建discoveryClient实例
    discoveryClient, err := discovery.NewDiscoveryClientForConfig(config)

    if err != nil {
        panic(err.Error())
    }

    // 获取所有分组和资源数据
    APIGroup, APIResourceListSlice, err := discoveryClient.ServerGroupsAndResources()

    if err != nil {
        panic(err.Error())
    }

    // 先看Group信息
    fmt.Printf("APIGroup :\n\n %v\n\n\n\n",APIGroup)

    // APIResourceListSlice是个切片,里面的每个元素代表一个GroupVersion及其资源
    for _, singleAPIResourceList := range APIResourceListSlice {

        // GroupVersion是个字符串,例如"apps/v1"
        groupVerionStr := singleAPIResourceList.GroupVersion

        // ParseGroupVersion方法将字符串转成数据结构
        gv, err := schema.ParseGroupVersion(groupVerionStr)

        if err != nil {
            panic(err.Error())
        }

        fmt.Println("*****************************************************************")
        fmt.Printf("GV string [%v]\nGV struct [%#v]\nresources :\n\n", groupVerionStr, gv)

        // APIResources字段是个切片,里面是当前GroupVersion下的所有资源
        for _, singleAPIResource := range singleAPIResourceList.APIResources {
            fmt.Printf("%v\n", singleAPIResource.Name)
        }
    }
}
  • Execute <font color="blue">go run main.go</font>, the intercepted part of the execution result is as follows, all resources are printed out:
...
*****************************************************************
GV string [discovery.k8s.io/v1beta1]
GV struct [schema.GroupVersion{Group:"discovery.k8s.io", Version:"v1beta1"}]
resources :

endpointslices
*****************************************************************
GV string [flowcontrol.apiserver.k8s.io/v1beta1]
GV struct [schema.GroupVersion{Group:"flowcontrol.apiserver.k8s.io", Version:"v1beta1"}]
resources :

flowschemas
flowschemas/status
prioritylevelconfigurations
prioritylevelconfigurations/status
  • The above is the basic usage of DiscoveryClient, do you think this kind of actual combat is too easy, then let's have an extended reading to see the surrounding scenes of DiscoveryClient;

How to use DiscoveryClient in kubectl

  • You should be familiar with the <font color="blue">kubectl api-versions</font> command. It can return all the Group+Version combinations of the current kubernetes environment, as follows:
zhaoqin@zhaoqindeMBP-2 discoveryclientdemo % kubectl api-versions
admissionregistration.k8s.io/v1
admissionregistration.k8s.io/v1beta1
apiextensions.k8s.io/v1
apiextensions.k8s.io/v1beta1
apiregistration.k8s.io/v1
apiregistration.k8s.io/v1beta1
apps/v1
authentication.k8s.io/v1
...
  • By viewing the source code of kubectl, it can be seen that the DiscoveryClient is used behind the above command, as shown in the red box in the following figure:

在这里插入图片描述

  • There is another thing that is not clear: Is the o.discoveryClient in the red box 2 of the above figure a DiscoveryClient? Although the names are similar, I can take a look at it and feel relieved. As a result, there are new discoveries. As shown below, the data structure of DiscoveryClient is <font color="blue">CachedDiscoveryInterface</font>:
type APIVersionsOptions struct {
    discoveryClient discovery.CachedDiscoveryInterface

    genericclioptions.IOStreams
}
  • Judging from the name CachedDiscoveryInterface, kubectl caches GVR data locally. Think about it, GVR doesn't change often, and there is no need to go to the API Server to pull it every time. For details on caching, please refer to staging/src/k8s. io/client-go/discovery/cached/disk/cached_discovery.go, it will not be expanded here;
  • At this point, the actual combat of the four client-go client tools and the shallow-level analysis of the related source code are all completed. When you are doing client-go development, I hope these contents can provide you with some reference;

You are not alone, Xinchen and original are with you all the way

  1. Java series
  2. Spring series
  3. Docker series
  4. kubernetes series
  5. database + middleware series
  6. DevOps series

Welcome to pay attention to the public account: programmer Xin Chen

Search "Programmer Xin Chen" on WeChat, I am Xin Chen, and I look forward to traveling the Java world with you...
https://github.com/zq2599/blog_demos

程序员欣宸
147 声望24 粉丝

热爱Java和Docker