# Kubernetes client-go 源码分析 - 开篇


## 为什么要分析 client-go 源码

我们在深度使用 Kubernetes 时难免会涉及 Operator 的开发，目前虽然已经有 Kubebuilder/Operator SDK、controller-runtime 等工具可以较好屏蔽底层细节，让我们专注于自身业务逻辑，但是不清楚底层原理会让我们在编码过程中心里没底。

<!--more-->

比如自定义控制器重启时我们会重新收到所有相关 Event 吗？我们调谐的子资源是 Deployment 时相关 pods 的变更会触发调谐逻辑吗？…… 很多的细节问题会不停跳出来，让你对自己的代码没有信心。所以在[《Kubernetes client-go 源码分析》](https://www.danielhu.cn/tags/kubernetes-client-go-源码分析/)系列文章中我们将详细分析 client-go 中和 Operator 开发相关的各种组件原理与源码，从而对自己开发的自定义控制器行为能够知根知底，胸有成足。

## 概览

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

![client-go](client-go.png "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) - <https://www.danielhu.cn>

