欢送拜访我的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开发的时候,心愿这些内容能给您提供一些参考;
你不孤独,欣宸原创一路相伴
- Java系列
- Spring系列
- Docker系列
- kubernetes系列
- 数据库+中间件系列
- DevOps系列
欢送关注公众号:程序员欣宸
微信搜寻「程序员欣宸」,我是欣宸,期待与您一起畅游Java世界…
https://github.com/zq2599/blog_demos
发表回复