Kubernetes client-go 源码分析 - ListWatcher
概述ListWatch 对象的创建GetterListWatchList() & Watch()
概述
源码版本信息
- Project: kubernetes
- Branch: master
- Last commit id: d25d741c
- Date: 2021-09-26
ListWatcher 是 Reflector 的一个主要能力提供者,今天我们具体看下 ListWatcher 是如何实现 List() 和 Watch() 过程的。这里我们只跟到 RESTClient 到调用层,不深入 RESTClient 本身的实现;后面有机会再单独结合 apiserver、etcd 等整体串在一起讲 k8s 里的 list-watch 机制底层原理。
ListWatch 对象的创建
ListWatcher 对应的新建实例函数如下:
- client-go/tools/cache/listwatch.go:70
1// 这里 Getter 类型的 c 对应一个 RESTClient
2func NewListWatchFromClient(c Getter, resource string, namespace string, fieldSelector fields.Selector) *ListWatch {
3 optionsModifier := func(options *metav1.ListOptions) {
4 options.FieldSelector = fieldSelector.String() // 序列化成字符串
5 }
6 // 调用下面这个 NewFilteredListWatchFromClient() 函数
7 return NewFilteredListWatchFromClient(c, resource, namespace, optionsModifier)
8}
主要逻辑在下面,list 和 watch 能力都是通过 RESTClient 提供:
1func NewFilteredListWatchFromClient(c Getter, resource string, namespace string, optionsModifier func(options *metav1.ListOptions)) *ListWatch {
2 // list 某个 namespace 下的某个 resource
3 listFunc := func(options metav1.ListOptions) (runtime.Object, error) {
4 optionsModifier(&options)
5 return c.Get(). // RESTClient.Get() -> *request.Request
6 Namespace(namespace).
7 Resource(resource).
8 VersionedParams(&options, metav1.ParameterCodec).
9 Do(context.TODO()).
10 Get()
11 }
12 // watch 某个 namespace 下的某个 resource
13 watchFunc := func(options metav1.ListOptions) (watch.Interface, error) {
14 options.Watch = true
15 optionsModifier(&options)
16 return c.Get().
17 Namespace(namespace).
18 Resource(resource).
19 VersionedParams(&options, metav1.ParameterCodec).
20 Watch(context.TODO())
21 }
22 return &ListWatch{ListFunc: listFunc, WatchFunc: watchFunc}
23}
Getter
上面有一个 Getter 接口,看下定义:
- client-go/tools/cache/listwatch.go:65
1type Getter interface {
2 Get() *restclient.Request
3}
这里需要一个能够获得 *restclient.Request 的方式
我们实际使用的时候,会用 rest.Interface 接口类型的实例,这是一个相对底层的工具,封装的是 Kubernetes REST apis 相应动作:
- client-go/rest/client.go:41
1type Interface interface {
2 GetRateLimiter() flowcontrol.RateLimiter
3 Verb(verb string) *Request
4 Post() *Request
5 Put() *Request
6 Patch(pt types.PatchType) *Request
7 Get() *Request
8 Delete() *Request
9 APIVersion() schema.GroupVersion
10}
对应实现是:
- client-go/rest/client.go:81
1type RESTClient struct {
2 base *url.URL
3 versionedAPIPath string
4 content ClientContentConfig
5 createBackoffMgr func() BackoffManager
6 rateLimiter flowcontrol.RateLimiter
7 warningHandler WarningHandler
8 Client *http.Client
9}
10
Getter 接口的 Get() 方法返回的是一个 *restclient.Request 类型,Request 的用法我们直接看 ListWatch 的 New 函数里已经看到是怎么玩的了。
至于这里的 RESTClient 和我们代码里常用的 Clientset 的关系,这里先简单举个例子介绍一下:我们在用 clientset 去 Get 一个指定名字的 DaemonSet 的时候,调用过程类似这样:
1r.AppsV1().DaemonSets("default").Get(ctx, "test-ds", getOpt)
这里的 Get 其实就是利用了 RESTClient 提供的能力,方法实现对应如下:
1func (c *daemonSets) Get(ctx context.Context, name string, options v1.GetOptions) (result *v1beta1.DaemonSet, err error) {
2 result = &v1beta1.DaemonSet{}
3 err = c.client.Get(). // 其实就是 RESTClient.Get(),返回的是 *rest.Request 对象
4 Namespace(c.ns).
5 Resource("daemonsets").
6 Name(name).
7 VersionedParams(&options, scheme.ParameterCodec).
8 Do(ctx).
9 Into(result)
10 return
11}
ListWatch
上面 NewFilteredListWatchFromClient() 函数里实现了 ListFunc 和 WatchFunc 属性的初始化,我们接着看下 ListWatch 结构体定义:
- client-go/tools/cache/listwatch.go:57
1type ListWatch struct {
2 ListFunc ListFunc
3 WatchFunc WatchFunc
4 // DisableChunking requests no chunking for this list watcher.
5 DisableChunking bool
6}
实现的接口叫做 ListWatcher
1type ListerWatcher interface {
2 Lister
3 Watcher
4}
这里的 Lister 是
1type Lister interface {
2 // List 的返回值应该是一个 list 类型对象,也就是里面有 Items 字段,里面的 ResourceVersion 可以用来 watch
3 List(options metav1.ListOptions) (runtime.Object, error)
4}
这里的 Watcher 是
1type Watcher interface {
2 // 从指定的资源版本开始 watch
3 Watch(options metav1.ListOptions) (watch.Interface, error)
4}
List() & Watch()
最后 ListWatch 对象的 List() 和 Watch() 的实现就没有太多新内容了:
- client-go/tools/cache/listwatch.go:103
1func (lw *ListWatch) List(options metav1.ListOptions) (runtime.Object, error) { // ListWatch 在 Reflector 中使用,在 Reflector 中已经有了分页逻辑,所以这里不能再添加分页相关代码 return lw.ListFunc(options)}func (lw *ListWatch) Watch(options metav1.ListOptions) (watch.Interface, error) { return lw.WatchFunc(options)}
(转载请保留本文原始链接 https://www.danielhu.cn)

Kubernetes client-go 源码分析 - ListWatcher的更多相关文章
- Kubernetes client-go Informer 源码分析
概述ControllerController 的初始化Controller 的启动processLoopHandleDeltas()SharedIndexInformersharedIndexerIn ...
- Kubernetes client-go DeltaFIFO 源码分析
概述Queue 接口DeltaFIFO元素增删改 - queueActionLocked()Pop()Replace() 概述 源码版本信息 Project: kubernetes Branch: m ...
- Kubernetes client-go workqueue 源码分析
概述Queue接口和结构体setAdd()Get()Done()DelayingQueue接口和结构体waitForNewDelayingQueuewaitingLoop()AddAfter()Rat ...
- Kubernetes client-go 源码分析 - Reflector
概述入口 - Reflector.Run()核心 - Reflector.ListAndWatch()Reflector.watchHandler()NewReflector()小结 概述 源码版本: ...
- Kubernetes Deployment 源码分析(二)
概述startDeploymentController 入口逻辑DeploymentController 对象DeploymentController 类型定义DeploymentController ...
- Eureka 源码分析之 Eureka Client
文章首发于微信公众号<程序员果果> 地址:https://mp.weixin.qq.com/s/47TUd96NMz67_PCDyvyInQ 简介 Eureka是一种基于REST(Repr ...
- SSO单点登录系列1:cas客户端源码分析cas-client-java-2.1.1.jar
落雨 cas 单点登录 希望能给以后来研究cas的兄弟留下一点思路,也算是研究了两天的成果,外国人的代码写的很晦涩,翻译下来也没有时间继续跟进,所以有错误的还请大家跟帖和我讨论,qq 39426378 ...
- client-go客户端自定义开发Kubernetes及源码分析
介绍 client-go 是一种能够与 Kubernetes 集群通信的客户端,通过它可以对 Kubernetes 集群中各资源类型进行 CRUD 操作,它有三大 client 类,分别为:Clien ...
- 【原】Spark中Client源码分析(二)
继续前一篇的内容.前一篇内容为: Spark中Client源码分析(一)http://www.cnblogs.com/yourarebest/p/5313006.html DriverClient中的 ...
随机推荐
- 【Android开发】【数据库】Realm For Android
目录 1.Realm简介 2.环境配置 3.初始化Realm 4.创建实体 5.增 6.删 7.改 8.查 9.异步操作 10.数据库数据更新监听 11.json转对象,插入数据库 12.Demo地址 ...
- java中Super指向他紧邻的父类,而不是最底层的基类
3.2 当有两次继承时,演示super指向他紧邻的父类 我们把上面的例子扩展成两次继承, 就看出:马克-to-win,Super是一个参考(或说指针)指向他紧邻的父类,而不是最底层的基类. 例1.3. ...
- [ Skill ] 为什么 Lisp 语言如此先进
https://www.cnblogs.com/yeungchie/ 网上看到一个应该是 2002 年的文章 译文转自:为什么Lisp语言如此先进?(译文) - 阮一峰的网络日志 原文地址:Reven ...
- C# 将PDF转为Excel
通常,PDF格式的文档能支持的编辑功能不如office文档多,针对PDF文档里面有表格数据的,如果想要编辑表格里面的数据,可以将该PDF文档转为Excel格式,然后编辑.本文,将以C#代码为例,介绍如 ...
- 百度离线人脸识别sdk的使用
1.1下载sdk运行 百度离线人脸识别sdk的使用 1.2配置环境 添加至项目,可以拖动复制或者以类库形式添加face-resource此文件夹 放到根目录上一层 激活文件与所有dll引用放到根目录嫌 ...
- Figma禁封中国企业,下一个会是Postman吗?国产软件势在必行!
"新冷战"蔓延到生产力工具 著名 UI 设计软件 Figma 宣布制裁大疆! 近日,网上流传一份 Figma 发送给大疆的内部邮件.其中写道: "我们了解到,大疆在美 ...
- uTools .SRT 转 .VTT 格式转换自动化小工具
不想用网上的转换工具,要有网,先上传,再下载,可能还要看广告.有些工具也不是很方便.打算配合uTools的自动化助手插件搞一个一键格式转换.
- 安卓记账本开发学习day9之依赖导入失败
根据上一篇文章导入依赖,在一些旧版本的AS上能正常完成,但是我下载最新的AS以后无法正常导入 同步的时候控制台报 Build file 'C:\CS\AndroidStudioProjects\tal ...
- 不借助 Javascript,利用 SVG 快速构建马赛克效果
之前在公众号转发了好友 Vajoy 的一篇文章 -- 巧用 CSS 把图片马赛克风格化. 核心是利用了 CSS 中一个很有意思的属性 -- image-rendering,它可以用于设置图像缩放算法. ...
- canvasToTempFilePath: fail SecurityError: The operations is insecure
我这里报这个错是因为canvas用到的图片有跨域问题.解决了跨域就对了. 值得一提的是:我用hbuilderX开发的h5.在内置浏览器调试时一切正常.到了部署上线后才报的这个错.