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