关于云计算:clientgo实战之五DiscoveryClient

欢送拜访我的GitHub

https://github.com/zq2599/blog_demos

内容:所有原创文章分类汇总及配套源码,波及Java、Docker、Kubernetes、DevOPS等;

对于DiscoveryClient

  • 本文是《client-go实战》系列的第五篇,配角是最初一种客户端:DiscoveryClient,咱们之前学习的Clientset和dynamicClient都是面向资源对象的(例如创立deployment实例、查看pod实例),而DiscoveryClient则不同,它聚焦的是资源,例如查看以后kubernetes有哪些Group、Version、Resource,上面是DiscoveryClient数据结构的字段和关联办法,再次看到了相熟的restClient字段,还有一众办法皆是与Group、Version、Resource无关:

  • 从上图可见,DiscoveryClient数据结构有两个字段:restClient和LegacyPrefix,这个<font color=”blue”>LegacyPrefix</font>是啥呢?去看看新建DiscoveryClient实例的办法,如下图红框,原来是个固定字符串<font color=”red”>/api</font>,看起来像是url中的一部分:

  • 挑一个DiscoveryClient的关联办法看看,如下图红框,果然,LegacyPrefix就是url中的一部分:

  • 相比其余几个客户端,DiscoveryClient要更简略一些,罗唆间接实战吧!

需要确认

  • 本次实战的需要很简略:从kubernetes查问所有的Group、Version、Resource信息,在控制台打印进去;

源码下载

  • 本篇实战中的源码可在GitHub下载到,地址和链接信息如下表所示(https://github.com/zq2599/blo…:
名称 链接 备注
我的项目主页 https://github.com/zq2599/blo… 该我的项目在GitHub上的主页
git仓库地址(https) https://github.com/zq2599/blo… 该我的项目源码的仓库地址,https协定
git仓库地址(ssh) mailto:git@github.com:zq2599/blog_demos.git 该我的项目源码的仓库地址,ssh协定
  • 这个git我的项目中有多个文件夹,client-go相干的利用在<font color=”blue”>client-go-tutorials</font>文件夹下,如下图红框所示:

  • client-go-tutorials文件夹下有多个子文件夹,本篇对应的源码在<font color=”blue”>discoveryclientdemo</font>目录下,如下图红框所示:

编码

  • 新建文件夹discoveryclientdemo,在外面执行以下命令,新建module:
go mod init discoveryclientdemo
  • 增加k8s.io/api和k8s.io/client-go这两个依赖,留神版本要匹配kubernetes环境:
go get k8s.io/api@v0.20.0
go get k8s.io/client-go@v0.20.0
  • 新建main.go,内容如下,外部已有具体正文,要重点关注的是ServerGroupsAndResources办法的第二个返回值,它的数据结构中有切片,切片的每个元素外面又有切片,这才是每个资源的信息:
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)
        }
    }
}
  • 执行<font color=”blue”>go run main.go</font>,截取局部执行后果如下,所有资源都被打印进去了:
...
*****************************************************************
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
  • 以上就是DiscoveryClient的根本用法,您是否感觉这样的实战太easy了,那咱们就来个延长浏览,看看DiscoveryClient的周边场景;

kubectl中如何应用DiscoveryClient

  • <font color=”blue”>kubectl api-versions</font>命令,大家应该不生疏吧,能够返回以后kubernetes环境的所有Group+Version的组合,如下:
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
...
  • 通过查看kubectl源码可见,上述命令的背地就是应用了DiscoveryClient来实现的,如下图红框所示:

  • 还有一处没有明确:上图红框2中的o.discoveryClient到底是不是DiscoveryClient呢?尽管名字很像,但还是瞅一眼才释怀,后果这一瞅有了新发现,如下所示,discoveryClient的数据结构是<font color=”blue”>CachedDiscoveryInterface</font>:
type APIVersionsOptions struct {
    discoveryClient discovery.CachedDiscoveryInterface

    genericclioptions.IOStreams
}
  • 从名称CachedDiscoveryInterface来看,kubectl对GVR数据是做了本地缓存的,想想也是,GVR不常常变动,没必要每次都去API Server拉取,对于缓存的细节请参考:staging/src/k8s.io/client-go/discovery/cached/disk/cached_discovery.go ,这里就不开展了;
  • 至此,client-go的四种客户端工具实战以及相干源码的浅层次剖析就全副实现了,在您做client-go开发的时候,心愿这些内容能给您提供一些参考;

你不孤独,欣宸原创一路相伴

  1. Java系列
  2. Spring系列
  3. Docker系列
  4. kubernetes系列
  5. 数据库+中间件系列
  6. DevOps系列

欢送关注公众号:程序员欣宸

微信搜寻「程序员欣宸」,我是欣宸,期待与您一起畅游Java世界…
https://github.com/zq2599/blog_demos

评论

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

这个站点使用 Akismet 来减少垃圾评论。了解你的评论数据如何被处理