Informer
是负责与Kubernetes APIServer
进行watch操作,watch的资源,可以是k8s内置资源对象,也可以是CRD。
Informer
是一个带有本地缓存以及索引机制的核心工具包,当请求为查询操作的时候,会优先从本地缓存中去查找数据,而创建、更新、删除,这类操作,则会更加事件通知写入到队列DeltaFIFO中,同时对应的事件处理过后,更新本地缓存,使本地缓存与ETCD的数据保持一致。
Informer
抽象出来的这个缓存层,将查询相关的压力接收下来,这样就不用每次调用APIServer的接口,减轻了APIServer
的数据交互压力。
从图上就能看出,Informer
是由多个组件构成的。下面先了解一下组件。
Reflector
:使用list-watch
来保证本地缓存数据的准确性、顺序性和一致性。list对应资源的全量列表数据,watch负责变化部分的数据,watch指定的k8s资源,当watch的资源发生变化时,触发变更的事件,并将资源对象的变化存放到本地队列DeltaFIFO
中。DeltaFIFO
:是一个增量队列,记录了资源变化的过程,Reflector
就相当于队列的生产者。这个组件可以拆分成两个部分来理解,FIFO就是一个队列,拥有基本的队列方法,比如ADD,UPDATE等。Delta是一个资源对象存储,保存存储对象的消费类型。Indexer
:用来存储资源对象并自带索引功能的本地存储,Reflector
从DeltaFIFO
中将消费处来的资源对象存储到Indexer
,Indexer
与ETCD中的数据完全保持一致。从而client-go可以本地读取,减少k8sAPIServer的数据交互压力。List-watch
机制是kubernetes
中的异步消息通知机制,通过它能有效的确保了消息的实时性、顺序性和可靠性。
List-Watch它分为两个部分:
list
是基于HTTP中的短链接实现。watch
则是基于HTTP长链接实现,watch
使用长链接的方式极大的减轻了k8s APIserver
的访问压力。
//watch实现
package main
import (
"context"
"fmt"
v1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/client-go/kubernetes"
"k8s.io/client-go/tools/clientcmd"
)
func main() {
//1、加载配置,生成config对象
config, err := clientcmd.BuildConfigFromFlags("", "F:\\GO\\src\\test\\config")
if err != nil {
panic(err.Error())
}
//2、实例化客户端
clientset, err := kubernetes.NewForConfig(config)
if err != nil {
panic(err.Error())
}
//3、调用监听的方法
watch, err := clientset.AppsV1().Deployments("kube-system").Watch(context.TODO(), v1.ListOptions{}) //返回一个通道
if err != nil {
panic(err.Error())
}
for {
select {
case e, _ := <-watch.ResultChan(): //监听通道,实时拿到最新消息
fmt.Println(e.Type, e.Object)
//e.Type表示事件变化的类型, Added , Delete等
//e.Object 表示变化后的数据
}
}
}
运行后输出