k8s-Informer概要解析(2)

Client-go 主要用在 k8s 控制器中

什么是 k8s Informer

Informer 负责与 kubernetes APIServer 进行 Watch 操作,Watch 的资源,可以是 kubernetes 内置资源对象,也可以 CRD。

Informer 是一个带有本地缓存以及索引机制的核心工具包,当请求为查询操作的时候,会优先从本地缓存内存去查询数据,而 创建、更新、删除这类操作,则会根据事件通知写入队列 DeltaFIFO 中,同时对应的事件处理过后,更新本地缓存,使得本地缓存与 ETCD 的数据保持一致性。

Informer 内部主要组件

  • Reflector:使用 List-Watch 来保证本地缓存数据的准确性和顺序一致性。List 从 k8s APIServer 中获取该资源的所有实例,得到最新的 ResourceVersion,然后使用 Watch 方法监听该方法resourceVersion之后的所有变化,如果发现对象的实例有如:Added、Updated、Deleted 动作,Reflector 收到"事件通知",并利用反射机制将监听的结果实例化成具体的对象,然后将资源对象的变化事件存到本地队列 DeltaFIFO 中。
  • DeltaFIFO:是一个增量的队列,记录了资源变化过程,Reflector 就相当于队列的生产者。这个组件可以拆分为两个部分来理解。FIFO 就是一个队列,拥有队列基本操作方法如ADD、UPDATE、DELETE、LIST、POP及CLOSE等,而Delta是一个资源对象存储,保存存储对象的消息类型如 Added、Updated及Deleted 等。
  • LocalStore(Indexer):Informer 不断从 DeltaFIFO 中读取增量。如果遇到事件类型是 Added操作,那么 Informer 会把这个增量对象保持到本地缓存里头,并且还为它创建索引;如果遇到类型为 Deleted 操作,那么 Informer 会在本地缓存删除该对象。此外,LocalStore 不仅用来存储资源对象,而且还自带索引功能的本地存储,LocalStore(Indexer) 与 Etcd 中的数据是完全一致的,当要查询 (Get 或 List)k8s 对象时,可直接请求 LocalStore,这样就减少 Kubernetes APIServer 的资源交互压力。
  • Workqueue:DeltaFIFO 在同步完 LocalStore 后,会 Pop 这个事件到 Controller 中, Controller 会调用事先注册的 ResourceEventHandler 回调函数(如 OnAdd、OnUpdate、 OnDelete)进行处理, 回调函数处理得到的 obj-key放入 Workqueue 中,供 Worker 中的业务逻辑处理。

List-Watch

List-Watch 机制是 k8s 中的异步消息通知机制,通过它能有效的确保了消息的实时性、顺序性及可靠性。

List-Watch 分为两个部门:

  • List 负责调用资源对应的 k8s APIServer 的 RESTful API 获取全局数据列表,并且同步到(本地缓存中)DeltaFIFO。

  • Watch 负责监听资源的变化,并调用相应事件处理函数进行处理,同时维护更新本地缓存,使得本地队列与 Etcd 总数据保持一致。

List 是基于 HTTP 中的短链接实现,Watch 则是基于 HTTP 长链接实现的,Watch 使用长链接方式是为了减轻 k8s APIServer 的访问压力。

Reflector

Reflector 是client-go 中用来监听指定资源的组件,当资源发生变化的时候如ADDED、UPDATE及DELETE操作时,会以事件的形式存入本地队列,然后有对应的方法处理。

在 Reflector 中,核心的部分分别是 List-Watch,其他功能基本都是围绕它来搞的。

在实例化 Reflector 的过程中,其中有ListerWatcher的接口对象,这个结构体对象有两个方法,分别是List和Watch这两个方法实现List-Watch功能。

Reflector 核心逻辑:

  • List:调用List方法获取资源全部列表数据,转换为资源对象列表,然后保存到本地缓存中,

  • 定时同步:定时器定时触发同步机制,定时更新缓存数据,在Reflector结构体对象中,是可以配置定时同步的周期时间的。

  • Watch:监听资源的变化,并且调用对应的事件处理函数来处理

Reflector 组件对于数据更新同步,都是基于 ResourceVersion 来进行,每个资源对象都会有 ResourceVersion 这个属性,当数据发生变化时候 ResourceVersion 也会将以递增的形式更新,这样就确保事件的更新顺序了。

DeltaFIFO

DeltaFIFO 是一个增量的本地队列,记录资源对象的变化过程。它生产者是 Reflector 组件,将监听到的对象,同步到 DeltaFIFO中。

  • FIFO 是一个先进先出的本地队列,负责接收 Reflector 传递过来的事件,并将其按照顺序存储,然后等待事件的处理,若同时出现多个相同的事件,则会被处理一次。FIFO 是队列那么它也会拥有队列相关操作的方法,可以通过 Queue 这个接口对象来实现队列需求的方法的,同时还根据需要扩展一些其他的方法如Pop,AddIfNotPresent等。

  • Delta 是一个资源对象的存储,有两个属性分别是 Type 和 Object

    • Type 表示这个事件类型,如Added表示增量,Update 表示更新等

    • Object 是一个接口类型,它表示k8s 资源对象如Pod和Service等。

总结:

Reflector 的主要作用是通过 Kubernetes Watch API 监听某种 resource 下的所有事件;DeltaFIFO 和 LocalStore 是 Informer 的两级缓存;Lister 主要是被调用 List/Get 方法;Processor 中记录了所有的回调函数实例(即 ResourceEventHandler 实例),并负责触发这些函数。

相关推荐
颜淡慕潇17 分钟前
【K8S系列】Kubernetes 资源对象的 YAML 文件示例及其详细介绍
后端·云原生·kubernetes
stormsha20 分钟前
Docker 更换 MySQL 镜像:备份、迁移与恢复数据的详细流程
linux·mysql·docker·容器
LYK_HAHA1 小时前
docker常用命令
docker·容器
apgk12 小时前
docker redis 详细教程
redis·docker·容器
IT利刃出鞘3 小时前
Docker Compose--安装本地maven
java·docker·容器
大龙Java3 小时前
docker build次数过多,导致磁盘内存不足:ERROR: no space left on device
docker·容器
碧水澜庭4 小时前
k8s中用filebeat文件如何收集不同service的日志
运维·云原生·kubernetes
勇-子4 小时前
k8s pod之间的通讯方式
云原生·容器·kubernetes
chengxuyuan666664 小时前
云原生后端详解
云原生
勇-子4 小时前
k8s 部署方式kustomization和helm的区别
云原生·容器·kubernetes