5. informer源码分析-概要分析

k8s client-go k8s informers 实现了持续获取集群的所有资源对象监听集群的资源对象变化功能,并在本地维护了全量资源对象的内存缓存,以减少对 apiserver、对 etcd 的请求压力。Informers 在启动的时候会首先在客户端调用 List 接口来获取全量的对象集合,然后通过 Watch 接口来获取增量的对象,然后更新本地缓存

1. k8s informer 概述

我们都知道可以使用 k8s 的 Clientset 来获取所有的原生资源对象,那么怎么能持续的获取集群的所有资源对象,或监听集群的资源对象数据的变化呢?这里不需要轮询去不断执行 List 操作,而是调用 Watch 接口,即可监听资源对象的变化,当资源对象发生变化,客户端即可通过 Watch 接口收到资源对象的变化。

Watch 接口虽然可以直接使用,但一般情况下很少直接使用,因为往往由于集群中的资源较多,我们需要自己在客户端去维护一套缓存,而这个维护成本比较大。

也是因为如此,client-go 提供了自己的实现机制,Informers 应运而生。informers 实现了持续获取集群的所有资源对象、监听集群的资源对象变化功能,并在本地维护了全量资源对象的内存缓存,以减少对 apiserver、对 etcd 的请求压力。Informers 在启动的时候会首先在客户端调用 List 接口来获取全量的对象集合,然后通过 Watch 接口来获取增量的对象,然后更新本地缓存

此外 informers 也有很强的健壮性,当长期运行的 watch 连接中断时,informers 会尝试拉起一个新的 watch 请求来恢复连接,在不丢失任何事件的情况下恢复事件流。另外,informers 还可以配置一个重新同步的周期参数,每间隔该周期,informers 就会重新 List 全量数据

在 informers 的使用上,通常每个 GroupVersionResource(GVR)只实例化一个 informers,但有时候我们在一个应用中往往会在多个地方对同一种资源对象都有 informer 的需求,所以就有了共享 informer,即 SharedInformerFactory。所以可以通过使用 SharedInformerFactory 来实例化 informers,这样本地内存缓存就只有一份,通知机制也只有一套,大大提高了效率,减少了资源浪费。

1.1 k8s informer 架构

在这里插入图片描述

1.2 k8s informer 包含部件

k8s client-go informer 主要包括以下部件:

  • Reflector:Reflector 从 kube-apiserver 中 list&watch 资源对象,然后调用 DeltaFIFO 的 Add/Update/Delete/Replace 方法将资源对象及其变化包装成 Delta 并将其丢到 DeltaFIFO 中;
  • DeltaFIFO:DeltaFIFO 中存储着一个 map 和一个 queue,即map[object key]Deltas 以及 object key 的 queue,Deltas 为 Delta 的切片类型,Delta 装有对象及对象的变化类型(Added/Updated/Deleted/Sync) ,Reflector 负责 DeltaFIFO 的输入,Controller 负责处理 DeltaFIFO 的输出;
  • Controller:Controller 从 DeltaFIFO 的 queue 中 pop 一个 object key 出来,并获取其关联的 Deltas 出来进行处理,遍历 Deltas,根据对象的变化更新 Indexer 中的本地内存缓存,并通知 Processor,相关对象有变化事件发生;
  • Processor:Processor 根据对象的变化事件类型,调用相应的 ResourceEventHandler 来处理对象的变化;
  • Indexer:Indexer 中有 informer 维护的指定资源对象的相对于 etcd 数据的一份本地内存缓存,可通过该缓存获取资源对象,以减少对 apiserver、对 etcd 的请求压力;
  • ResourceEventHandler:用户根据自身处理逻辑需要,注册自定义的的 ResourceEventHandler,当对象发生变化时,将触发调用对应类型的 ResourceEventHandler 来做处理。

根据 informer 架构,对 k8s informer 的分析将分为以下几部分进行,本篇为概要分析:
(1)informer概要分析;
(2)informer之初始化与启动分析;
(3)informer之Reflector分析;
(4)informer之DeltaFIFO分析;
(5)informer之Controller&Processor分析;
(6)informer之Indexer分析;


2. informer 使用示例代码

使用大致过程如下:
(1)构建与 kube-apiserver 通信的 config 配置;
(2)初始化与 apiserver 通信的 clientset;
(3)利用 clientset 初始化 shared informer factory 以及 pod informer;
(4)注册 informer 的自定义 ResourceEventHandler;
(5)启动 shared informer factory,开始 informer 的 list & watch 操作;
(6)等待 informer 从 kube-apiserver 同步资源完成,即 informer 的 list 操作获取的对象都存入到 informer 中的 indexer 本地缓存中;
(7)创建 lister,可以从 informer 中的 indexer 本地缓存中获取对象;

func main() {// 自定义与kube-apiserver通信的config配置master := "192.168.1.10" // apiserver urlkubeconfig := "/.kube/config"config, err = clientcmd.BuildConfigFromFlags(master, kubeconfig)if err != nil {klog.Fatalf("Failed to create config: %v", err)}// 或使用k8s serviceAccount机制与kube-apiserver通信// config, err = rest.InClusterConfig()// 初始化与apiserver通信的clientsetclientset, err := kubernetes.NewForConfig(config)if err != nil {klog.Fatalf("Failed to create client: %v", err)}// 初始化shared informer factory以及pod informerfactory := informers.NewSharedInformerFactory(clientset, 30*time.Second)podInformer := factory.Core().V1().Pods()informer := podInformer.Informer()// 注册informer的自定义ResourceEventHandlerinformer.AddEventHandler(cache.ResourceEventHandlerFuncs{AddFunc:    xxx,UpdateFunc: xxx,DeleteFunc: xxx,})// 启动shared informer factory,开始informer的list & watch操作stopper := make(chan struct{})go factory.Start(stopper)// 等待informer从kube-apiserver同步资源完成,即informer的list操作获取的对象都存入到informer中的indexer本地缓存中 // 或者调用factory.WaitForCacheSync(stopper)if !cache.WaitForCacheSync(stopper, informer.HasSynced) {runtime.HandleError(fmt.Errorf("Timed out waiting for caches to sync"))return}// 创建listerpodLister := podInformer.Lister()// 从informer中的indexer本地缓存中获取对象podList, err := podLister.List(labels.Everything())if err != nil {fmt.Println(err)}}

以上只是对 K8s informer 做了简单的介绍,以及简单的写了一下如何使用 informer 的示例代码,后面将开始对 informer 的各个部件做进一步的源码分析。

从图中可以看出,k8s informer主要包括以下几个部分:

2.1.Reflector

(1)Reflector 从 kube-apiserver 中 list 资源对象列表,然后调用 DeltaFIFO 的 Replace 方法将 object 包装成 Sync/Deleted 类型的 Delta 丢进 DeltaFIFO 中;

(2)Reflector 从 kube-apiserver 中 watch 资源对象的变化,然后调用 DeltaFIFO 的 Add/Update/Delete 方法将 object 包装成 Added/Updated/Deleted 类型的 Delta 丢到 DeltaFIFO 中;

2.2.DeltaFIFO

DeltaFIFO 中存储着一个 map 和一个 queue;

(1)其中 queue 可以看成是一个先进先出队列,一个 object 进入 DeltaFIFO 中,会判断 queue 中是否已经存在该 object key,不存在则添加到队尾;

(2)map 即 map[object key]Deltas,是 object key 和 Deltas 的映射,Deltas 是 Delta 的切片类型,Delta 中存储着 DeltaType 和 object;另外,Deltas 最末尾的两个 Deleted 类型的 Delta 会被去重;

DeltaType 有4种,分别是 Added、Updated、Deleted、Sync

2.3.Controller

Controller 从 DeltaFIFO 的 queue 中 pop 一个 object key 出来,并从 DeltaFIFO 的 map 中获取其对应的 Deltas 出来进行处理,遍历 Deltas,根据 object 的变化类型更新 Indexer 本地缓存,并通知 Processor 相关对象有变化事件发生:

(1)如果 DeltaType 是 Deleted,则调用 Indexer 的 Delete 方法,将 Indexer 本地缓存中的 object 删除,并构造 deleteNotification struct,通知 Processor 做处理;

(2)如果 DeltaType 是 Added/Updated/Sync,调用 Indexer 的 Get 方法从 Indexer 本地缓存中获取该对象,存在则调用 Indexer 的 Update 方法来更新 Indexer 缓存中的该对象,随后构造 updateNotification struct,通知 Processor 做处理;如果 Indexer 中不存在该对象,则调用 Indexer 的 Add 方法将该对象存入本地缓存中,并构造 addNotification struct,通知 Processor 做处理;

2.4.Processor

Processor 根据 Controller 的通知,即根据对象的变化事件类型(addNotification、updateNotification、deleteNotification),调用相应的 ResourceEventHandler(addFunc、updateFunc、deleteFunc)来处理对象的变化。

2.5.Indexer

Indexer 中有 informer 维护的指定资源对象的相对于 etcd 数据的一份本地内存缓存,可通过该缓存获取资源对象,以减少对 apiserver、对etcd 的请求压力。

informer 所维护的缓存依赖于 threadSafeMap 结构体中的 items 属性,其本质上是一个用 map 构建的键值对,资源对象都存在 items 这个 map 中,key 为资源对象的 namespace/name 组成,value 为资源对象本身,这些构成了 informer 的本地缓存。

Indexer 除了维护了一份本地内存缓存外,还有一个很重要的功能,便是索引功能了。索引的目的就是为了快速查找,比如我们需要查找某个 node 节点上的所有 pod、查找某个命名空间下的所有 pod 等,利用到索引,可以实现快速查找。关于索引功能,则依赖于 threadSafeMap 结构体中的 indexers 与 indices 属性。

2.6.ResourceEventHandler

用户根据自身处理逻辑需要,注册自定义的的 ResourceEventHandler,当对象发生变化时,将触发调用对应类型的 ResourceEventHandler 来做处理。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/714086.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

日常科研中经常使用的命令

Linux目录树状结构 1. Windows是磁盘分区,Linux不区分盘符,所有文件都在根目录斜线下面; 2. 根目录显示不同,Linux是一个斜线,而windows是盘符,然后冒号; 3. 分割目录Linux用斜线&#xff0c…

化肥工业5G智能制造工厂数字孪生可视化平台,推进化肥行业数字化转型

化肥工业5G智能制造工厂数字孪生可视化平台,推进化肥行业数字化转型。随着科技的不断发展,数字化转型已经成为各行各业发展的必然趋势。在化肥工业领域,5G智能制造工厂数字孪生可视化平台的应用正在逐渐普及,为行业数字化转型提供…

租用云服务器租时要注意的问题有哪些?

随着云计算的不断发展,对云计算服务器的需求也越来越大。 那么,我们应该如何以正确的态度和方法来选择云服务器呢? 租用云服务器需要注意哪些问题? 1.了解您需要的云服务类型 了解您的云计算需求将使您了解您正在寻求的服务类型…

让两个电脑通信的方法(TCP连接,UDP连接,C/S架构)

目录 TCP-面向连接UDP-面向无连接C/S架构服务器和客户端的工作过程C/S架构例子 让两个电脑通信的方法是 在C/S的基础上,采用TCP和UDP的方式连接 TCP-面向连接 UDP-面向无连接 C/S架构 服务器和客户端的工作过程 C/S架构例子 服务器与客户端通信的过程类似公司与客户…

微信小程序云开发教程——墨刀原型工具入门(添加交互事件)

引言 作为一个小白,小北要怎么在短时间内快速学会微信小程序原型设计? “时间紧,任务重”,这意味着学习时必须把握微信小程序原型设计中的重点、难点,而非面面俱到。 要在短时间内理解、掌握一个工具的使用&#xf…

殿堂级Flink源码极精课程预售

一、为什么我们要读源码? 1、让个人技术快速成长: 优秀的开源框架,底层的源码设计思想也非常优秀,同时还有含有大量的设计模式和并发编程技术,优秀的解决方案,熟读源码对猿们技术提升有很大帮助 2、新技术学习能力: Java开源码框架的源码熟读后,若出现…

【Datawhale组队学习:Sora原理与技术实战】Sora技术原理

Sora能力边界探索 最大支持60秒高清视频生成,以及基于已有短视频的前后扩展,同时保持人物/场景的高度一致性如奶茶般丝滑过渡的视频融合能力同一场景的多角度/镜头的生成能力具有动态摄像机运动的视频。随着摄像机的移动和旋转,人和其 他场景…

javaScript 深浅拷贝

javaScript深浅拷贝 浅拷贝 自己创建一个新的对象,来接受你要重新复制或引用的对象值。如果对象属性是基本的数据类型,复制的就是基本类型的值给新对象,但如果属性是引用数据类型,复制的就是内存中的地址,如果其中一个…

Python 编程中的迭代器、生成器和装饰器探究【第110篇—迭代器】

Python 编程中的迭代器、生成器和装饰器探究 在Python编程中,迭代器(Iterators)、生成器(Generators)和装饰器(Decorators)是三个强大的概念,它们为代码的可读性、效率和灵活性提供…

PaddleOCR的部署教程(实操环境安装、数据集制作、实际应用案例)

文章目录 前言 PaddleOCR简介 一、PaddleOCR环境搭建 因为我之前安装过cuda和cudnn,查看cuda的版本根据你版本安装合适的paddlepaddle版本(之前没有安装过cuda的可以看我这篇文章Ubuntu20.04配置深度学习环境yolov5最简流程) 1.创建一个…

【C++从0到王者】第四十八站:最短路径

文章目录 一、最短路径二、单源最短路径 -- Dijkstra算法1.单源最短路径问题2.算法思想3.代码实现4.负权值带来的问题 三、单源最短路径 -- Bellman-Ford算法1.算法思想2.算法实现3.SPFA优化4.负权回路 四、多源最短路径 -- Floyd-Warshall算法1.算法思想2.算法实现 一、最短路…

Python调用ChatGPT API使用国内中转key 修改接口教程

大家好,我是淘小白~ 有的客户使用4.0的apikey ,直接使用官方直连的apikey消费很高,有一位客户一个月要消费2万,想使用4.0中转的apikey,使用中转的apikey 需要修改官方的openai库,下面具体说下。 1、首先确保安装的op…

Java ElasticSearch-Linux面试题

Java ElasticSearch-Linux面试题 前言1、守护线程的作用?2、链路追踪Skywalking用过吗?3、你对G1收集器了解吗?4、你们项目用的什么垃圾收集器?5、内存溢出和内存泄露的区别?6、什么是Spring Cloud Bus?7、…

安装ProxySQL,教程及安装链接(网盘自提)

一、网盘下载,本地直传 我网盘分享的是proxysql-2.5.5-1-centos8.x86_64.rpm,yum或者dnf直接安装就行 提取码:rhelhttps://pan.baidu.com/s/1nmx8-h8JEhrxQE3jsB7YQw 官方安装地址 官网下载地址https://repo.proxysql.com/ProxySQL/ 二、…

【AIGC】“光影交织的恋曲:绝美情侣在蓝天下的深情互动“

外貌特征 (Physical Appearance):给远景镜头,这对情侣拥有出众的容貌和气质。男子身材挺拔,五官立体鲜明,阳光洒在他俊朗的脸庞上,更显英气逼人;女子则拥有一头柔顺亮丽的秀发,明亮的眼睛如同星…

GPT-4论文精读【论文精读·53】

Toolformer 今天我们来聊一下 GPT 4,但其实在最开始准备这期视频的时候,我是准备讲 Toolformer 这篇论文的,它是 Meta AI 在2月初的时候放出来的一篇论文。说这个大的语言模型可以利用工具了,比如说它就可以去调用各种各样的API&a…

腾讯云优惠券领取的三个渠道,一个比一个优惠!

腾讯云代金券领取渠道有哪些?腾讯云官网可以领取、官方媒体账号可以领取代金券、完成任务可以领取代金券,大家也可以在腾讯云百科蹲守代金券,因为腾讯云代金券领取渠道比较分散,腾讯云百科txybk.com专注汇总优惠代金券领取页面&am…

Unity(第二十四部)UI

在游戏开发中,用户界面(UI)是至关重要的一部分。它负责与玩家进行交互,提供信息,并增强游戏的整体体验。Unity 提供了强大的工具和功能来创建和管理 UI。 ui的底层就是画布,创建画布的时候会同时创建一个事…

C++ STL标准程序库开发指南学习笔记

一、类模板简介: 在现今的C标准模板库中,几乎所有的东西都被设计为template形式,不支持模板,就无法使用标准程序库。模板库可以认为是针对一个或多个尚未明确的类型而编写一套函数或类型。模板是C的一个新特性。通过使用模板&…

【前端素材】推荐优质电商类后台管理系统网页Vuesax平台模板(附源码)

一、需求分析 在线后台管理系统是指供管理员或运营人员使用的Web应用程序,用于管理和监控网站、应用程序或系统的运行和数据。它通常包括一系列工具和功能,用于管理用户、内容、权限、数据等。下面是关于在线后台管理系统的详细分析: 1、功…