• client-go实战之五: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,这个LegacyPrefix是啥呢?去看看新建DiscoveryClient实例的方法,如下图红框,原来是个固定字符串/api,看起来像是url中的一部分:

    在这里插入图片描述

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

    在这里插入图片描述

    • 相比其他几个客户端,DiscoveryClient要更简单一些,干脆直接实战吧!

    需求确认

    • 本次实战的需求很简单:从kubernetes查询所有的Group、Version、Resource信息,在控制台打印出来;

    源码下载

    名称 链接 备注
    项目主页 https://github.com/zq2599/blog_demos 该项目在GitHub上的主页
    git仓库地址(https) https://github.com/zq2599/blog_demos.git 该项目源码的仓库地址,https协议
    git仓库地址(ssh) git@github.com:zq2599/blog_demos.git 该项目源码的仓库地址,ssh协议
    • 这个git项目中有多个文件夹,client-go相关的应用在client-go-tutorials文件夹下,如下图红框所示:

    在这里插入图片描述

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

    在这里插入图片描述

    编码

    • 新建文件夹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 :
    
     %v
    
    
    
    ",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]
    GV struct [%#v]
    resources :
    
    ", groupVerionStr, gv)
    
    		// APIResources字段是个切片,里面是当前GroupVersion下的所有资源
    		for _, singleAPIResource := range singleAPIResourceList.APIResources {
    			fmt.Printf("%v
    ", singleAPIResource.Name)
    		}
    	}
    }
    
    • 执行go run main.go,截取部分执行结果如下,所有资源都被打印出来了:
    ...
    *****************************************************************
    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

    • kubectl api-versions命令,大家应该不陌生吧,可以返回当前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的数据结构是CachedDiscoveryInterface
    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

  • 相关阅读:
    MSDN RSS Feeds (ZT)
    不錯,今天看到日历了.
    模糊:让你的代码远离偷窥之眼
    .NET中異常發布器的開發(1)(2)(3)
    How To Query Performance Monitor Counters Using a Web Page
    可選參數的Stored Procedure範例.
    Outlook GetCurrent Folder / GetSelectedItems / GetInspectors
    微軟的MS04007补丁有严重问题啊.
    Blog,流行有理由 (zt)
    从VB.Net到VB6.0要小心,关于使用IIF和log求对数函数(串联的小知识)
  • 原文地址:https://www.cnblogs.com/bolingcavalry/p/15249712.html
Copyright © 2020-2023  润新知