Client-go源码分析(三)Informer机制


本文为《Kubernetes 源码剖析》读书笔记,书籍简介: http://www.broadview.com.cn/book/6104

一、简介

Kubernetes 中,控制器需要对集群中的资源对象的状态进行监控,使资源对象的实际状态和通过 yaml 定义的期望状态协调达到一致。那么控制器是如何对资源对象进行监控,并根据对象的实际状态变化做出相应的处理呢?实际上就是通过 Client-go 包中的 Informer 机制实现的。
Informer 工作流程架构图
图片来源:极客时间 --《深入浅出 Kubernetes》
从上图中,我们可以大致了解到 Informer 机制的整个流程:

  • Reflector 组件通过对 apiserver 发起 HTTP 请求,List 得到集群中所有资源对象,再通过 HTTP 长连接 Watch 不断监听得到 etcd 变化的数据,封装成一个个事件(Event),再将事件对应的资源对象放入 Delta FIFO 队列中
  • Delta FIFO 队列保存了需要操作的资源对象,以及要对该资源对象进行什么操作(Add、Updated、Deleted、Sync)
  • Indexer 是一个带索引的本地缓存,它从Delta FIFO 队列取出资源对象的索引(和 etcd 的 key 保持一致)和具体数据进行保存
  • 从Delta FIFO 队列中取出的资源对象还会触发三种方法的回调:Add、Delete、Update 分别对应 etcd 中资源对象的增、删、改操作。回调方法中会将需要处理的资源对象的索引(Index)放入 WorkQueue 工作队列中
  • Control Loop 控制循环不断地从 WorkQueue 中取出要处理对象的索引,通过 Lister 从 Indexer 维护的本地缓存中获取具体的资源对象数据,进行相应的处理。

二、Reflector 底层原理分析

简单来说,Reflector 就做了两件事:List 和 Watch

// k8s.io/client-go/tools/cache/reflector.go
func (r *Reflector) ListAndWatch(stopCh <-chan struct{
   }) error {
   
	...
	if err := func() error {
   
		...
		pager := pager.New(pager.SimplePageFunc(func(opts metav1.ListOptions) (runtime.Object, error) {
   
				return r.listerWatcher.List(opts)
			}))
		...
		w, err := r.listerWatcher.Watch(options)
		...
}

List 指的是向 apiserver 发送 GET 请求获取集群中所有资源的数据,Watch 则是通过与 apiserver 建立 HTTP 长连接并通过分块编码传输(chunked)来监控资源对象的变更事件。而这些请求的发送都是通过我们前面提到的 ClientSet 客户端实现的。
分块编码传输简介

// 提供了 List 和 Watch 接口,让资源对象去实现具体的接口
type ListWatch struct {
   
	ListFunc  ListFunc
	WatchFunc WatchFunc
	// 是否禁用 watch 时的分块编码传输
	DisableChunking bool
}

type ListFunc func(options metav1.ListOptions) (runtime.Object, error)

type WatchFunc func(options metav1.ListOptions) (watch.Interface, error)

// 以 Pod 资源对象为例,底层通过 ClientSet 客户端向 apiserver 发送请求
// k8s.io/client-go/informers/core/v1/pod.go
func NewFilteredPodInformer(client kubernetes.Interface, namespace string, resyncPeriod time.Duration, indexers cache.Indexers, tweakListOptions internalinterfaces.TweakListOptionsFunc) cache.SharedIndexInformer {
   
	return cache.NewSharedIndexInformer(
		&cache.ListWatch{
   
			ListFunc: func(options metav1.ListOptions) (runtime.Object, error) {
   
				if tweakListOptions != nil {
   
					tweakListOptions(&options)
				}
				return client.CoreV1().Pods(namespace
  • 1
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值