• 您可能会好奇上述FromUnstructured方法究竟是如何实现转换的,咱们去看下此方法的内部实现,如下图所示,其实也没啥悬念了,通过反射可以得到podList的字段信息:

  • 至此,Unstructured的分析就结束了吗?没有,强烈推荐您进入上图红框2中的fromUnstructured方法去看细节,这里面是非常精彩的,以podList为例,这是个数据结构,而fromUnstructured只处理原始类型,对于数据结构会调用structFromUnstructured方法处理,在structFromUnstructured方法中

处理数据结构的每个字段,又会调用fromUnstructured,这是相互迭代的过程,最终,不论podList中有多少数据结构的嵌套都会被处理掉,篇幅所限就不展开相信分析了,下图是一部分关键代码:

  • 小结:Unstructured转为资源对象的套路并不神秘,无非是用反射取得资源对象的字段类型,然后按照字段名去Unstructured的map中取得原始数据,再用反射设置到资源对象的字段中即可;

  • 做完了准备工作,接下来该回到本篇文章的主题了:dynamicClient客户端

[](()关于dynamicClient

  • deployment、pod这些资源,其数据结构是明确的固定的,可以精确对应到Clientset中的数据结构和方法,但是对于CRD(用户自定义资源),Clientset客户端就无能为力了,此时需要有一种数据结构来承载资源对象的数据,也要有对应的方法来处理这些数据;

  • 此刻,前面提到的Unstructured可以登场了,没错,把Clientset不支持的资源对象交给Unstructured来承载,接下来看看dynamicClient和Unstructured的关系:

  • 先看数据结构定义,和clientset没啥区别,只有个restClient字段:

type dynamicClient struct {

client *rest.RESTClient

}

  • 这个数据结构只有一个关联方法Resource,入参为GVR,返回的是另一个数据结构dynamicResourceClient:

func (c *dynamicClient) Resource(resource schema.GroupVersionResource) NamespaceableResourceInterface {

return &dynamicResourceClient{client: c, resource: resource}

}

  • 通过上述代码可知,dynamicClient的关键是数据结构dynamicResourceClient及其关联方法,来看看这个dynamicResourceClient,如下图,果然,dynamicClient所有和资源相关的操作都是dynamicResourceClient在做(代理模式?),选了create方法细看,序列化和反序列化都交给unstructured的UnstructuredJSONScheme,与kubernetes的交互交给Restclient:

  • 小结:
  1. 与Clientset不同,dynamicClient为各种类型的资源都提供统一的操作API,资源需要包装为Unstructured数据结构;

  2. 内部使用了Restclient与kubernetes交互;

  • 对dynamicClient的介绍分析就这些吧,可以开始实战了;

[](()需求确认

  • 本次编码实战的需求很简单:查询指定namespace下的所有pod,然后在控制台打印出来,要求用dynamicClient实现;

  • 您可能会问:pod是kubernetes的内置资源,更适合Clientset来操作,而dynamicClient更适合处理CRD不是么?—您说得没错,这里用pod是因为折腾CRD太麻烦了,定义好了还要在kubernetes上发布,于是干脆用pod来代替CRD,反正dynamicClient都能处理,咱们通过实战掌握dynamicClient的用法就行了,以后遇到各种资源都能处理之;

[](()源码下载

  • 本篇实战中的源码可在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文件夹下,如下图红框所示:

![在这里插入图片描述](https://img-blog.csdnimg.cn/20210210175040851.png?x-oss-process=image/waterma 《一线大厂Java面试题解析+后端开发学习笔记+最新架构讲解视频+实战项目源码讲义》开源 rk,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L2JvbGluZ19jYXZhbHJ5,size_16,color_FFFFFF,t_70)

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

[](()编码

  • 新建文件夹dynamicclientdemo,在里面执行以下命令,新建module:

go mod init dynamicclientdemo

  • 添加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,内容如下,稍后会说一下要注意的重点:

package main

import (

“context”

“flag”

“fmt”

apiv1 “k8s.io/api/core/v1”

metav1 “k8s.io/apimachinery/pkg/apis/meta/v1”

“k8s.io/apimachinery/pkg/runtime”

“k8s.io/apimachinery/pkg/runtime/schema”

“k8s.io/client-go/dynamic”

“k8s.io/client-go/tools/clientcmd”

“k8s.io/client-go/util/homedir”

“path/filepath”

)

func main() {

var kubeconfig *string

// home是家目录,如果能取得家目录的值,就可以用来做默认值

if home:=homedir.Ho Java开源项目【ali1024.coding.net/public/P7/Java/git】 meDir(); 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())

}

dynamicClient, err := dynamic.NewForConfig(config)

if err != nil {

panic(err.Error())

}

// dynamicClient的唯一关联方法所需的入参

gvr := schema.GroupVersionResource{Version: “v1”, Resource: “pods”}

// 使用dynamicClient的查询列表方法,查询指定namespace下的所有pod,

// 注意此方法返回的数据结构类型是UnstructuredList

unstructObj, err := dynamicClient.

Resource(gvr).

Namespace(“kube-system”).

List(context.TODO(), metav1.ListOptions{Limit: 100})

if err != nil {

panic(err.Error())

}

// 实例化一个PodList数据结构,用于接收从unstructObj转换后的结果

最后

总而言之,面试官问来问去,问的那些Redis知识点也就这么多吧,复习的不够到位,知识点掌握不够熟练,所以面试才会卡壳。将这些Redis面试知识解析以及我整理的一些学习笔记分享出来给大家参考学习

还有更多学习笔记面试资料也分享如下:

imit: 100})

if err != nil {

panic(err.Error())

}

// 实例化一个PodList数据结构,用于接收从unstructObj转换后的结果

最后

总而言之,面试官问来问去,问的那些Redis知识点也就这么多吧,复习的不够到位,知识点掌握不够熟练,所以面试才会卡壳。将这些Redis面试知识解析以及我整理的一些学习笔记分享出来给大家参考学习

还有更多学习笔记面试资料也分享如下:

[外链图片转存中…(img-MT0yHddp-1650010772514)]

client-go实战之四:dynamicClient相关推荐

  1. [原创][从mambo到joomla的迁移实战之四]插件、组件的迁移

    摘要: 本文记录了网站由mambo迁移到joomla的过程中插件.组件的迁移 作者:陈海青(josonchen)  (http://www.chq.name)  (http://www.hhrz.or ...

  2. Java Socket实战之四 传输压缩对象

    2019独角兽企业重金招聘Python工程师标准>>> 本文地址:http://blog.csdn.net/kongxx/article/details/7259834 Java S ...

  3. java与es8实战之四:SpringBoot应用中操作es8(无安全检查)

    欢迎访问我的GitHub 这里分类和汇总了欣宸的全部原创(含配套源码):https://github.com/zq2599/blog_demos 本篇概览 本篇是<java与es8实战>系 ...

  4. quarkus实战之四:远程热部署

    欢迎访问我的GitHub 这里分类和汇总了欣宸的全部原创(含配套源码):https://github.com/zq2599/blog_demos 本篇概览 本文是<quarkus实战>系列 ...

  5. Kurento实战之四:应用开发指南

    欢迎访问我的GitHub 这里分类和汇总了欣宸的全部原创(含配套源码):https://github.com/zq2599/blog_demos 本篇概览 本文是<Kurento实战>的第 ...

  6. java版gRPC实战之四:客户端流

    欢迎访问我的GitHub 这里分类和汇总了欣宸的全部原创(含配套源码):https://github.com/zq2599/blog_demos <java版gRPC实战>全系列链接 用p ...

  7. WebSocket实战之四WSS配置

    一.前言 上一篇文章WebSocket实战之三遇上PAC  ,碰到的问题只能上安全的WebSocket(WSS)才能解决,配置证书还是挺麻烦的,主要是每年都需要重新更新证书,我配置过的证书最长有效期也 ...

  8. python 降维 聚类_python数据挖掘实战之四:聚类

    计划写一下本学期选修的<机器学习与商业数据挖掘>课程的一系列实战笔记,本篇是第四节课的内容--聚类. 聚类 聚类分析(cluster analysis)是常见的数据挖掘手段,其主要假设是数 ...

  9. JavaCV的摄像头实战之四:抓图

    欢迎访问我的GitHub 这里分类和汇总了欣宸的全部原创(含配套源码):https://github.com/zq2599/blog_demos 本篇概览 本文是<JavaCV的摄像头实战> ...

最新文章

  1. 仅靠合成数据就能实现真实人脸分析!微软这项新研究告别人工标注
  2. 3. Port scanners (端口扫描器 4个)
  3. 我们处理了10亿个Java记录的错误-这是导致97%的错误的原因
  4. html按钮返回上一步操作,用js实现返回上一步操作
  5. 架构设计分布式数据结构与算法面试题
  6. 如何使用idea生成javaDoc文档
  7. Session赋值(备注)
  8. C++中的struct与class继承方式
  9. 装hadoop引发的一系列事件
  10. mysql explode函数_hive中,lateral view 与 explode函数
  11. Google 开源最新 NLP 模型,能处理整本《罪与罚》
  12. 创建Spring项目没有Spring Config文件怎么办
  13. 市场项目交接文档初稿
  14. HCIP 3-4月考试战报
  15. 万兆交换机用什么网线_现在国内没有万兆宽带,那为什么有万兆网线呢?
  16. 系统设计之路:如何设计一个URL短链服务
  17. 稍加改进的Switch/Case扩展方法
  18. 为何延时函数不起作用?
  19. 表格查询(去除重复数据)
  20. Matlab GUI程序封装成exe文件并在不安装Matlab的电脑上运行

热门文章

  1. 人工智能以及图形图像处理领域CCFA类期刊汇总与个人评价
  2. 手游运营需网络文化经营许可证?1000万资本金门槛
  3. php获取android版本,php-获取Android应用的类别-在服务器端
  4. 死囚试毒酒问题(改编)
  5. 微信小游戏 资源服务器,Cocos Creator 微信小游戏 远程资源设置
  6. 搭建hyperledger cello
  7. 帮推|基于深度学习的图像融合方法综述
  8. npm ERR! code EJSONPARSE
  9. 上承文化、下启智慧:智慧城市建设的遂宁样本
  10. KMP算法DNA的病毒检测