client-go实战之五:DiscoveryClient
2021/7/13 13:06:00
本文主要是介绍client-go实战之五:DiscoveryClient,对大家解决编程问题具有一定的参考价值,需要的程序猿们随着小编来一起学习吧!
欢迎访问我的GitHub
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信息,在控制台打印出来;
源码下载
- 本篇实战中的源码可在GitHub下载到,地址和链接信息如下表所示(github.com/zq2599/blog_demos):
名称 | 链接 | 备注 |
---|---|---|
项目主页 | github.com/zq2599/blog_demos | 该项目在GitHub上的主页 |
git仓库地址(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 :\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) } } }
- 执行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开发的时候,希望这些内容能给您提供一些参考;
我是欣宸,期待与您一同畅游Java世界…
这篇关于client-go实战之五:DiscoveryClient的文章就介绍到这儿,希望我们推荐的文章对大家有所帮助,也希望大家多多支持为之网!
- 2024-12-20go-zero 框架的 RPC 服务 启动start和停止 底层是怎么实现的?-icode9专业技术文章分享
- 2024-12-19Go-Zero 框架的 RPC 服务启动和停止的基本机制和过程是怎么实现的?-icode9专业技术文章分享
- 2024-12-18怎么在golang中使用gRPC测试mock数据?-icode9专业技术文章分享
- 2024-12-15掌握PageRank算法核心!你离Google优化高手只差一步!
- 2024-12-15GORM 中的标签 gorm:"index"是什么?-icode9专业技术文章分享
- 2024-12-11怎么在 Go 语言中获取 Open vSwitch (OVS) 的桥接信息(Bridge)?-icode9专业技术文章分享
- 2024-12-11怎么用Go 语言的库来与 Open vSwitch 进行交互?-icode9专业技术文章分享
- 2024-12-11怎么在 go-zero 项目中发送阿里云短信?-icode9专业技术文章分享
- 2024-12-11怎么使用阿里云 Go SDK (alibaba-cloud-sdk-go) 发送短信?-icode9专业技术文章分享
- 2024-12-10搭建个人博客网站之一、使用hugo创建个人博客网站