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信息,在控制台打印出来;
源码下载
- 本篇实战中的源码可在GitHub下载到,地址和链接信息如下表所示(https://github.com/zq2599/blog_demos):
| 名称 | 链接 | 备注 |
|---|---|---|
| 项目主页 | 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 :\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世界...
https://github.com/zq2599/blog_demos
client-go实战之五:DiscoveryClient的更多相关文章
- [Java聊天室server]实战之五 读写循环(服务端)
前言 学习不论什么一个稍有难度的技术,要对其有充分理性的分析,之后果断做出决定---->也就是人们常说的"多谋善断":本系列尽管涉及的是socket相关的知识,但学习之前,更 ...
- kubebuilder实战之五:operator编码
欢迎访问我的GitHub https://github.com/zq2599/blog_demos 内容:所有原创文章分类汇总及配套源码,涉及Java.Docker.Kubernetes.DevOPS ...
- Flink SQL Client综合实战
欢迎访问我的GitHub https://github.com/zq2599/blog_demos 内容:所有原创文章分类汇总及配套源码,涉及Java.Docker.Kubernetes.DevOPS ...
- Flink处理函数实战之五:CoProcessFunction(双流处理)
欢迎访问我的GitHub https://github.com/zq2599/blog_demos 内容:所有原创文章分类汇总及配套源码,涉及Java.Docker.Kubernetes.DevOPS ...
- java版gRPC实战之五:双向流
欢迎访问我的GitHub https://github.com/zq2599/blog_demos 内容:所有原创文章分类汇总及配套源码,涉及Java.Docker.Kubernetes.DevOPS ...
- Spring Cloud Gateway实战之五:内置filter
欢迎访问我的GitHub https://github.com/zq2599/blog_demos 内容:所有原创文章分类汇总及配套源码,涉及Java.Docker.Kubernetes.DevOPS ...
- Java Socket实战之五:使用加密协议传输对象
转自:http://developer.51cto.com/art/201202/317547.htm 前面几篇博文提到了Socket中一些常用的用法,但是对于一些有安全要求的应用就需要加密传输的数据 ...
- spring4.1.8扩展实战之五:改变bean的定义(BeanFactoryPostProcessor接口)
本章我们继续实战spring的扩展能力,通过自定义BeanFactoryPostProcessor接口的实现类,来对bean实例做一些控制: 原文地址:https://blog.csdn.net/bo ...
- MyBatis初级实战之五:一对一关联查询
欢迎访问我的GitHub https://github.com/zq2599/blog_demos 内容:所有原创文章分类汇总及配套源码,涉及Java.Docker.Kubernetes.DevOPS ...
随机推荐
- HttpRunner3源码阅读: 1. 目录结构分析
初衷 身处软件测试行业的各位应该都有耳闻HttpRunner 开源测试工具/框架(接口测试),作者博客 为什么出这系列? 不少测试同行都建议阅读HttpRunner,源码学习其设计思想. 社区当下Py ...
- Android 模块打包生成aar远程坐标(sdk)
Android 模块打包生成aar远程坐标 打包成AAR到本地仓库 在模块的gradle文件中加入apply plugin: 'maven' *repository(url:"file:/ ...
- 自学linux——15.云主机的购买流程及域名的购买备案解析
项目上线流程 一.服务器选配购买 项目上线的服务器必须是外网服务器 1.服务器购买情况 真实服务器(成本过高,购买内部自用) 云服务器(上线首选):阿里云,腾讯云,华为云 2.购买阿里云服务器:htt ...
- 04.委托Delegation
1. 基本了解 1.1 委托简述 官方文档 委托是一种引用类型,表示对具有特定参数列表和返回类型的方法的引用,用于将方法作为参数传递给其他方法,可将任何可访问类或结构中与委托类型匹配的任何方法分配给委 ...
- STM32启动文件详解及SystemInit函数分析(转)
;先在RAM中分配系统使用的栈,RAM的起始地址为0x2000_0000 ;然后在RAM中分配变量使用的堆 ;然后在CODE区(flash)分配中断向量表,flash的起始地址为0x0800_0000 ...
- Pikachu-RCE模块
一.概述 1.1 RCE漏洞 可以让攻击者直接向后台服务器远程注入操作系统命令或者代码,从而控制后台系统. 1.2 远程系统命令执行一般出现这种漏洞,是因为应用系统从设计上需要给用户提供指定的远程命令 ...
- 【死磕 Java 基础】— 我同事一个 select 分页语句查出来了 3000W 条数据
大家好,我是大明哥,一个专注于[死磕 Java]系列创作的男人 个人网站:https://www.cmsblogs.com/.专注于 Java 优质系列文章分享,提供一站式 Java 学习资料 某天我 ...
- STM32—TIMx输出PWM信号驱动MG996R舵机
文章目录 一.前言 二.MG996R舵机简介 三.TIM定时器简介 四.通用定时器TIMx 1.TIMx主要功能 2.TIMx框图 3.计数单元 4.时钟选择 5.输出比较PWM 五.TIM3输出双路 ...
- NOIP 模拟 $34\; \rm Rectangle$
题解 \(by\;zj\varphi\) 对于没有在同一行或同一列的情况,直接枚举右边界,左边界从大到小,用树状数组维护上下边界即可. 而对于有多个在一列或一行的情况,这些点将左右分成了几个区间,枚举 ...
- Longhorn,企业级云原生容器分布式存储 - 高可用
内容来源于官方 Longhorn 1.1.2 英文技术手册. 系列 Longhorn 是什么? Longhorn 企业级云原生容器分布式存储解决方案设计架构和概念 Longhorn 企业级云原生容器分 ...