为什么要分析 client-go 源码

我们在深度使用 Kubernetes 时难免会涉及 Operator 的开发,目前虽然已经有 Kubebuilder/Operator SDK、controller-runtime 等工具可以较好屏蔽底层细节,让我们专注于自身业务逻辑,但是不清楚底层原理会让我们在编码过程中心里没底,比如自定义控制器重启时我们会重新收到所有相关 Event 吗?我们调谐的子资源是 Deployment 时相关 pods 的变更会触发调谐逻辑吗?…… 很多的细节问题会不停跳出来,让你对自己的代码没有信心。所以在《Kubernetes client-go 源码分析》系列文章中我们将详细分析 client-go 中和 Operator 开发相关的各种组件原理与源码,从而对自己开发的自定义控制器行为能够知根知底,胸有成足。

概览

如下图所示,我们在编写自定义控制器的过程中大致依赖于如下组件,其中浅黄色的是自定义控制器里需要编码的部分,浅蓝色的是 client-go 提供的一些“工具”。

今天我们先整体过一遍上面涉及到的相关模块,然后再逐个深入分析其实现。

  • Reflector:Reflector 向 apiserver watch 特定类型的资源,拿到变更通知后将其丢到 DeltaFIFO 队列中;
  • Informer: Informer 从 DeltaFIFO 中 pop 相应对象,然后通过 Indexer 将对象和索引丢到本地 cache 中,再触发相应的事件处理函数(Resource Event Handlers)运行;
  • Indexer: Indexer 主要提供一个对象根据一定条件的检索能力,典型的实现是通过 namespace/name 来构造 key ,通过 Thread Safe Store 来存储对象;
  • Workqueue:Workqueue 一般使用的是延时队列实现,在 Resource Event Handlers 中会完成将对象的 key 放入 workqueue 的过程,然后我们在自己的逻辑代码里从 workqueue 中消费这些 key;
  • ClientSet:Clientset 提供的是资源的 CURD 能力,和 apiserver 交互;
  • Resource Event Handlers:我们在 Resource Event Handlers 中一般是添加一些简单的过滤功能,判断哪些对象需要加到 workqueue 中进一步处理;对于需要加到 workqueue 中的对象,就提取其 key,然后入队;
  • Worker:Worker 指的是我们自己的业务代码处理过程,在这里可以直接接收到 workqueue 里的任务,可以通过 Indexer 从本地缓存检索对象,通过 Clientset 实现对象的增删改查逻辑。

(转载请保留本文原始链接 https://www.danielhu.cn