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

30次阅读

共计 4872 个字符,预计需要花费 13 分钟才能阅读完成。

欢送拜访我的 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

正文完
 0