写点什么

“高冷”的 Kubernetes Informer 一探究竟

  • 2020-03-04
  • 本文字数:2522 字

    阅读完需:约 8 分钟

“高冷”的 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 的关键逻辑:


1.Informer 在初始化时,Reflector 会先 List API 获得所有的 Pod


2.Reflect 拿到全部 Pod 后,会将全部 Pod 放到 Store 中


3.如果有人调用 Lister 的 List/Get 方法获取 Pod, 那么 Lister 会直接从 Store 中拿数据



4.Informer 初始化完成之后,Reflector 开始 Watch Pod,监听 Pod 相关 的所有事件;如果此时 pod_1 被删除,那么 Reflector 会监听到这个事件


5.Reflector 将 pod_1 被删除 的这个事件发送到 DeltaFIFO


6.DeltaFIFO 首先会将这个事件存储在自己的数据结构中(实际上是一个 queue),然后会直接操作 Store 中的数据,删除 Store 中的 pod_1


7.DeltaFIFO 再 Pop 这个事件到 Controller 中


8.Controller 收到这个事件,会触发 Processor 的回调函数



9.LocalStore 会周期性地把所有的 Pod 信息重新放到 DeltaFIFO 中


Informer 总结

Informer 的内部原理比较复杂、不太容易上手,但 Informer 却是一个非常稳定可靠的 package,已被 Kubernetes 广泛使用。但是,目前关于 Informer 的文章不是很多,如果文章中有表述不正确的地方,希望各位读者悉心指正。


作者介绍:李昂,曾经就职于七牛,参与七牛大数据产品的开发工作,加入才云科技后,主要负责 Devops 的相关工作,才云科技云平台容器工程师。


本文转载自才云 Caicloud 公众号。


原文链接:https://mp.weixin.qq.com/s/3vlclIP-rSbWH4bplduexA


2020-03-04 20:522054

评论

发布
暂无评论
发现更多内容

ByteHouse MaterializedMySQL增强优化

字节跳动数据平台

数据库 云原生 Clickhouse 企业号 3 月 PK 榜

从0到1:学员课时预约与扣课小程序开发笔记

CC同学

H2存储内核分析一

陈飞

分布式数据库 大数据 开源 数据库内核

智能选路系统与架构

阿里云CloudImagine

云计算 智能选路

Android系统服务DropBoxManagerService详解与实践应用

vivo互联网技术

文件管理 Dropbox 文件上报

过等保堡垒机选择云堡垒机可以吗?有推荐的吗?

行云管家

等保 等级保护 行云管家 过等保

硬核!阿里P8自爆春招面试核心手册,Github上获赞65.7K

Java你猿哥

Java 面试 面经 八股文 春招‘

分享:FactorJoin,一种新的连接查询基数估计框架

Java你猿哥

数据库 ssm

2023年新疆等级保护测评机构新名单看这里!

行云管家

等保 新疆 等级测评机构

常见七大SMD器件布局基本要求,你掌握了几点?

华秋PCB

元器件 PCB PCB布局 布局 PCB设计

成长计划知识赋能 | 第九期:渐进式深入理解OpenHarmony系统

OpenHarmony开发者

OpenHarmony

RabbitMQ、RocketMQ、Kafka性能为何差距如此之大?

Java你猿哥

kafka RocketMQ RabbitMQ

Github百万收藏!一份《从零开始写分布式服务框架》称霸榜首!

程序知音

Java 分布式 编程语言 java架构 后端技术

别再说被八股文害惨了!GitHub阿里Java面试题库标星145K不无道理

Java你猿哥

Java 面试 面经 八股文 Java八股文

量化合约技术系统开发(源码搭建)合约量化技术开发(Demo)

I8O28578624

从入门到精通:C++ 学习路线指南,附详细学习计划

小万哥

c++ 程序员 后端 开发 学习路线

用OceanBase试了一下ChatGPT开源文档问答助手

OceanBase 数据库

数据库 oceanbase

实用fcpx视频剪辑:Final Cut Pro 中文版

真大的脸盆

Mac Mac 软件 FCPX软件 fcpx

焱融科技助力海尔集团上云 加速“智能制造”进程

焱融科技

文件存储 分布式存储 容器存储 分布式文件存储 #高性能

定档3月31日,博睿数据受邀参加DAMS数据智能管理峰会

博睿数据

智能运维 博睿数据 One 一体化智能可观测

迟来的Offer,至今已有672名学长靠这套Java八股文成功入职大厂

Java你猿哥

Java 面试 面经 春招 八股文

从智慧园区、智慧金融到智能制造,我们在华为云上实现了降本增效

华为云开发者联盟

云计算 华为云 华为云开发者联盟 企业号 3 月 PK 榜

PD虚拟机如何安装ARM版CentOS Linux系统镜像(苹果M1专用)

Rose

pd虚拟机 pd18虚拟机 CentOS Linux系统 Centos Stream 9

ODC,是另一个 Navicat 吗?

OceanBase 数据库

数据库 oceanbase

meta魔豹联盟系统开发源码(Demo)技术成熟

I8O28578624

让GitHub低头认错的这份阿里内部绝密Java面试八股文手册有多强?

Java你猿哥

面试 ssm 面经 八股文 Java八股文

万字详解AI开发中的数据预处理(清洗)

Baihai IDP

人工智能 机器学习 数据清洗 数据预处理 企业号 3 月 PK 榜

瓴羊Quick BI、Qlik服务企业,助力企业数据智能化管理

对不起该用户已成仙‖

火山引擎DataTester:构建增长闭环,3-5人即可搭建企业增长团队

字节跳动数据平台

AB testing实战 A/B测试 企业号 3 月 PK 榜

“高冷”的 Kubernetes Informer 一探究竟_文化 & 方法_才云科技_InfoQ精选文章