Kubernetes Informer 详解
今天给到大家介绍一下 Client-go 中的一个非常关键的工具包 Informer。 Informer 内部实现极其复杂,详细介绍的文章也很少,很多人反馈比较难用。但不得不承认它也是一个设计精良、安全可靠的组件,值得我们去一探究竟。
Informer 简介
Informer 基础功能
Informer 是 Client-go 中的一个核心工具包。在 Kubernetes 源码中,如果 Kubernetes 的某个组件,需要 List/Get Kubernetes 中的 Object,在绝大多 数情况下,会直接使用 Informer 实例中的 Lister()方法(该方法包含 了 Get 和 List 方法),而很少直接请求 Kubernetes API。Informer 最基本 的功能就是 List/Get Kubernetes 中的 Object。
如下图所示,仅需要十行左右的代码就能实现对 Pod 的 List 和 Get。
Informer 高级功能
Client-go 的首要目标是满足 Kubernetes 的自身需求。Informer 作为其中的核心工具包,面对 Kubernetes 极为复杂业务逻辑,如果仅实现 List/Get 功能,根本无法满足 Kubernetes 自身需求。因此,Informer 被设计为一个灵活而复杂的工具包,除 List/Get Object 外,Informer 还可以监听事件并触发回调函数等,以实现更加复杂的业务逻辑。
Informer 设计思路
Informer 设计中的关键点
为了让 Client-go 更快地返回 List/Get 请求的结果、减少对 Kubenetes API 的直接调用,Informer 被设计实现为一个依赖 Kubernetes List/Watch API 、可监听事件并触发回调函数的二级缓存工具包。
更快地返回 List/Get 请求,减少对 Kubenetes API 的直接调用
使用 Informer 实例的 Lister() 方法, List/Get Kubernetes 中的 Object 时,Informer 不会去请求 Kubernetes API,而是直接查找缓存在本地内存中的数据(这份数据由 Informer 自己维护)。通过这种方式,Informer 既可以更快地返回结果,又能减少对 Kubernetes API 的直接调用。
依赖 Kubernetes List/Watch API
Informer 只会调用 Kubernetes List 和 Watch 两种类型的 API。Informer 在初始化的时,先调用 Kubernetes List API 获得某种 resource 的全部 Object,缓存在内存中; 然后,调用 Watch API 去 watch 这种 resource,去维护这份缓存; 最后,Informer 就不再调用 Kubernetes 的任何 API。
用 List/Watch 去维护缓存、保持一致性是非常典型的做法,但令人费解的是,Informer 只在初始化时调用一次 List API,之后完全依赖 Watch API 去维护缓存,没有任何 resync 机制。
笔者在阅读 Informer 代码时候,对这种做法十分不解。按照多数人思路,通过 resync 机制,重新 List 一遍 resource 下的所有 Object,可以更好的保证 Informer 缓存和 Kubernetes 中数据的一致性。
咨询过 Google 内部 Kubernetes 开发人员之后,得到的回复是:
在 Informer 设计之初,确实存在一个 relist 无法去执 resync 操作, 但后来被取消了。原因是现有的这种 List/Watch 机制,完全能够保证永远不会漏掉任何事件,因此完全没有必要再添加 relist 方法去 resync informer 的缓存。这种做法也说明了 Kubernetes 完全信任 etcd。
可监听事件并触发回调函数
Informer 通过 Kubernetes Watch API 监听某种 resource 下的所有事件。而且,Informer 可以添加自定义的回调函数,这个回调函数实例(即 ResourceEventHandler 实例)只需实现 OnAdd(obj interface{}) OnUpdate(oldObj, newObj interface{}) 和 OnDelete(obj interface{}) 三个方法,这三个方法分别对应 informer 监听到创建、更新和删除这三种事件类型。
在 Controller 的设计实现中,会经常用到 informer 的这个功能。 Controller 相关文章请见此文《如何用 client-go 拓展 Kubernetes 的 API》。
二级缓存
二级缓存属于 Informer 的底层缓存机制,这两级缓存分别是 DeltaFIFO 和 LocalStore。
这两级缓存的用途各不相同。DeltaFIFO 用来存储 Watch API 返回的各种事件 ,LocalStore 只会被 Lister 的 List/Get 方法访问 。
虽然 Informer 和 Kubernetes 之间没有 resync 机制,但 Informer 内部的这两级缓存之间存在 resync 机制。
以上是 Informer 设计中的一些关键点,没有介绍一些太细节的东西,尤其对于 Informer 两级缓存还未做深入介绍。下一章节将对 Informer 详细的工作流程做一个详细介绍。
Informer 详细解析
Informer 内部主要组件
Informer 中主要包含 Controller、Reflector、DeltaFIFO、LocalStore、Lister 和 Processor 六个组件,其中 Controller 并不是 Kubernetes Controller,这两个 Controller 并没有任何联系;Reflector 的主要作用是通过 Kubernetes Watch API 监听某种 resource 下的所有事件;DeltaFIFO 和 LocalStore 是 Informer 的两级缓存;Lister 主要是被调用 List/Get 方法;Processor 中记录了所有的回调函数实例(即 ResourceEventHandler 实例),并负责触发这些函数。
Informer 关键逻辑解析
我们以 Pod 为例,详细说明一下 Informer 的关键逻辑:
- Informer 在初始化时,Reflector 会先 List API 获得所有的 Pod
- Reflect 拿到全部 Pod 后,会将全部 Pod 放到 Store 中
- 如果有人调用 Lister 的 List/Get 方法获取 Pod, 那么 Lister 会直接从 Store 中拿数据
- Informer 初始化完成之后,Reflector 开始 Watch Pod,监听 Pod 相关 的所有事件;如果此时 pod_1 被删除,那么 Reflector 会监听到这个事件
- Reflector 将 pod_1 被删除 的这个事件发送到 DeltaFIFO
- DeltaFIFO 首先会将这个事件存储在自己的数据结构中(实际上是一个 queue),然后会直接操作 Store 中的数据,删除 Store 中的 pod_1
- DeltaFIFO 再 Pop 这个事件到 Controller 中
- Controller 收到这个事件,会触发 Processor 的回调函数
LocalStore 会周期性地把所有的 Pod 信息重新放到 DeltaFIFO 中
Informer 总结
Informer 的内部原理比较复杂、不太容易上手,但 Informer 却是一个非常稳定可靠的 package,已被 Kubernetes 广泛使用。但是,目前关于 Informer 的文章不是很多,如果文章中有表述不正确的地方,希望各位读者悉心指正。
本文转自中文社区-Kubernetes Informer 详解
低调大师中文资讯倾力打造互联网数据资讯、行业资源、电子商务、移动互联网、网络营销平台。
持续更新报道IT业界、互联网、市场资讯、驱动更新,是最及时权威的产业资讯及硬件资讯报道平台。
转载内容版权归作者及来源网站所有,本站原创内容转载请注明来源。
- 上一篇
给你一个K8S的“发行版”
Kubernetes是Google开源的容器集群管理系统或者称为分布式操作系统。它构建在Docker技术之上,为容器化的应用提供资源调度、部署运行、服务发现、扩容缩容等整一套功能,本质上可看作是基于容器技术的mini-PaaS平台。Kubernetes的目标是让开发者可以像管理产品一样管理服务,同时提高资源的利用率,让开发者更关注在应用开发本身,高可用的事情交给Kubernetes。 然而,Kubernetes虽然已经开源,但安装和部署却相当复杂,需要具有专业知识和技能的专业人员和专业团队才能顺利的完成,但许多开发人员和企业并不具备这些专业知识和专业团队,而雇佣第三方专家或团队来进行这项工作,需要不少的时间和资金的投入,这显然令众多想要使用Kubernetes的用户望而却步。 不过,现在有一个好消息,在百度资深科学家王益的协调下,百分点和云知声两家公司在一起开发了开源的Kubernetes“发行版”——Sextant,可以实现几乎零操作的全自动安装和部署Kubernetes集群,堪称K8S的“发行版”,这无疑给众多想要使用Kubernetes的开发者和企业带来了福音。 Kubernet...
- 下一篇
选K8S是对的,但是用不好就是你的不对了
2013年以来Docker像一股旋风席卷IT界,Docker指的是容器技术,其字面意思是集装箱,此中类比有深意。 小小的集装箱不简单,曾有人著书《集装箱改变世界》,说他改变了世界经济,围绕其中的有一大串复杂又很有趣的现象。 集装箱是装在船上来运输的,船上的舵手把集装箱送往全世界。IT世界的Docker装在数据中心的Linux系统环境中,容器何去何从由Kubernetes这个舵手说了算。 有人说Kubernetes出身好(谷歌的基因),活儿好,但是不好管理,作为老船长的几个IT管理者又拿出了Sextant来驯服Kubernetes,Sextant是什么东西呢? 字面意思是六分仪,也是海上航行的家伙事儿。看来,技术人员的情怀不是遥远的星辰,而是可望又可及的大海。 今天我们主要介绍下——Sextant(请忽略这个名字前几个单词的意思)。这是百度、百分点、云之声的几位技术人员作出的很严肃的东西,如上所说就是为了管理Docker容器的,那么Sextant是什么呢? Sextant和Kubernetes(K8S)的关系,就好比RedHat、Suse、CentOS、Ubuntu和Linux的关系一样...
相关文章
文章评论
共有0条评论来说两句吧...
文章二维码
点击排行
-
Docker使用Oracle官方镜像安装(12C,18C,19C)
- Springboot2将连接池hikari替换为druid,体验最强大的数据库连接池
- CentOS8编译安装MySQL8.0.19
- Docker快速安装Oracle11G,搭建oracle11g学习环境
- SpringBoot2配置默认Tomcat设置,开启更多高级功能
- MySQL8.0.19开启GTID主从同步CentOS8
- CentOS7,8上快速安装Gitea,搭建Git服务器
- Jdk安装(Linux,MacOS,Windows),包含三大操作系统的最全安装
- SpringBoot2编写第一个Controller,响应你的http请求并返回结果
推荐阅读
最新文章
- Springboot2将连接池hikari替换为druid,体验最强大的数据库连接池
- CentOS8,CentOS7,CentOS6编译安装Redis5.0.7
- MySQL8.0.19开启GTID主从同步CentOS8
- Docker快速安装Oracle11G,搭建oracle11g学习环境
- SpringBoot2整合Redis,开启缓存,提高访问速度
- Windows10,CentOS7,CentOS8安装Nodejs环境
- CentOS7编译安装Cmake3.16.3,解决mysql等软件编译问题
- SpringBoot2编写第一个Controller,响应你的http请求并返回结果
- SpringBoot2更换Tomcat为Jetty,小型站点的福音
- CentOS7设置SWAP分区,小内存服务器的救世主