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,这样本地内存缓存就只有一份,通知机制也只有一套,大大提高了效率,减少了资源浪费。

k8s informer架构

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

(1)Reflector:Reflector从kube-apiserver中list&watch资源对象,然后调用DeltaFIFO的Add/Update/Delete/Replace方法将资源对象及其变化包装成Delta并将其丢到DeltaFIFO中;

(2)DeltaFIFO:DeltaFIFO中存储着一个map和一个queue,即map[object key]Deltas以及object key的queue,Deltas为Delta的切片类型,Delta装有对象及对象的变化类型(Added/Updated/Deleted/Sync) ,Reflector负责DeltaFIFO的输入,Controller负责处理DeltaFIFO的输出;

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

(4)Processor:Processor根据对象的变化事件类型,调用相应的ResourceEventHandler来处理对象的变化;

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

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

根据informer架构,对k8s informer的分析将分为以下几部分进行,本篇为概要分析:

(1)informer概要分析;

(2)informer之初始化与启动分析;

(3)informer之Reflector分析;

(4)informer之DeltaFIFO分析;

(5)informer之Controller&Processor分析;

(6)informer之Indexer分析;

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 url
kubeconfig := "/.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通信的clientset
clientset, err := kubernetes.NewForConfig(config)
if err != nil {
klog.Fatalf("Failed to create client: %v", err)
} // 初始化shared informer factory以及pod informer
factory := informers.NewSharedInformerFactory(clientset, 30*time.Second)
podInformer := factory.Core().V1().Pods()
informer := podInformer.Informer() // 注册informer的自定义ResourceEventHandler
informer.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
} // 创建lister
podLister := podInformer.Lister()
// 从informer中的indexer本地缓存中获取对象
podList, err := podLister.List(labels.Everything())
if err != nil {
fmt.Println(err)
} }

总结

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

最后以一张k8s informer的架构图作为结尾总结,大家回忆一下k8s informer的架构组成以及各个部件的作用。

k8s client-go源码分析 informer源码分析(1)-概要分析的更多相关文章

  1. k8s client-go源码分析 informer源码分析(2)-初始化与启动分析

    k8s client-go源码分析 informer源码分析(2)-初始化与启动分析 前面一篇文章对k8s informer做了概要分析,本篇文章将对informer的初始化与启动进行分析. info ...

  2. k8s client-go源码分析 informer源码分析(3)-Reflector源码分析

    k8s client-go源码分析 informer源码分析(3)-Reflector源码分析 1.Reflector概述 Reflector从kube-apiserver中list&watc ...

  3. k8s client-go源码分析 informer源码分析(4)-DeltaFIFO源码分析

    client-go之DeltaFIFO源码分析 1.DeltaFIFO概述 先从名字上来看,DeltaFIFO,首先它是一个FIFO,也就是一个先进先出的队列,而Delta代表变化的资源对象,其包含资 ...

  4. k8s client-go源码分析 informer源码分析(5)-Controller&Processor源码分析

    client-go之Controller&Processor源码分析 1.controller与Processor概述 Controller Controller从DeltaFIFO中pop ...

  5. k8s client-go源码分析 informer源码分析(6)-Indexer源码分析

    client-go之Indexer源码分析 1.Indexer概述 Indexer中有informer维护的指定资源对象的相对于etcd数据的一份本地内存缓存,可通过该缓存获取资源对象,以减少对api ...

  6. Kubernetes client-go Informer 源码分析

    概述ControllerController 的初始化Controller 的启动processLoopHandleDeltas()SharedIndexInformersharedIndexerIn ...

  7. kube-scheduler源码分析(1)-初始化与启动分析

    kube-scheduler源码分析(1)-初始化与启动分析 kube-scheduler简介 kube-scheduler组件是kubernetes中的核心组件之一,主要负责pod资源对象的调度工作 ...

  8. OpenStack源码分析 Neutron源码分析(一)-----------Restful API篇

    原文:https://blog.csdn.net/happyanger6/article/details/54586463 首先,先分析WSGI应用的实现. 由前面的文章http://blog.csd ...

  9. [源码分析] 从源码入手看 Flink Watermark 之传播过程

    [源码分析] 从源码入手看 Flink Watermark 之传播过程 0x00 摘要 本文将通过源码分析,带领大家熟悉Flink Watermark 之传播过程,顺便也可以对Flink整体逻辑有一个 ...

随机推荐

  1. 用Markdown写Html和.md也就图一乐,真骚操作还得用来做PPT

    前言 和这篇文章一样,我就是用Markdown写的.相信各位平时也就用Markdown写写文档,做做笔记,转成XHtml.Html等,今天教大伙一招骚操作:用Markdown写PPT. 绝大多数朋友做 ...

  2. 用腾讯云Gogs搭建私有git服务器

    前言 经常有需要写不能公开代码的项目,所以只好自己搭建一个私人的git服务器 Gogs的好处在于比Gitlib轻量化了好多,而且是国人写的,官方主页也是中文的 Gogs首页 腾讯云服务器配置: Ubu ...

  3. Vscode的使用小技巧

    命令行启动code 如果你的系统是Linux系统(我使用的是Ubuntu 16.04)这样就可以直接使用 code + filename来编辑文件(就像vi + filename) 如果你的系统是Ma ...

  4. jQuery--筛选【串联函数】

    串联函数简介 A.add(B) 将A和B组合成一个对象 A.children().andSelf() 将之前的对象添加到操作集合中 A.children().children().end() 回到最近 ...

  5. request表示HttpServletRequest对象?

    request表示HttpServletRequest对象.它包含了有关浏览器请求的信息,并且提供了几个用于获取cookie, header, 和session数据的有用的方法. response表示 ...

  6. c语言代码规范

    什么叫规范?在C语言中不遵守编译器的规定,编译器在编译时就会报错,这个规定叫作规则.但是有一种规定,它是一种人为的.约定成俗的,即使不按照那种规定也不会出错,这种规定就叫作规范.虽然我们不按照规范也不 ...

  7. C++ | 虚拟地址空间

    在 x86 32位系统下,进程的虚拟地址空间为 232 (4G)大小,其中在windows系统下4G地址空间中0x00000000-0x7FFFFFFF 是用户地址空间,0x80000000-0xFF ...

  8. 【静态页面架构】CSS之链接和图像

    CSS架构 一.链接: 链接元素:通过使用a元素的href属性设置跳转到指定页面地址 <style> a{ color: blue; text-decoration: none; } a: ...

  9. 干货,看微信小程序后台用户数据如何演变和递增

    这几天发现附近小程序又多了好几家,其中有普通小程序和门店小程序,把它们做一个对比,门店小程序更多的像一张名片,只有基本的企业名称.地址.营业时间.电话和门店照片,和普通小程序相比显得逊色许多.楼下的水 ...

  10. 项目需求与分析--NABCD模型

    合作项目特点NABCD分析结果: 特点:便捷 N(Need 需求):在大学期间内,我们通常会有许多不用的课本或书籍或者其他东西,堆积起来又没有地方放,想卖出去就要建一个群,十分麻烦,开发该软件用户可直 ...