国内operator学习大全
simple example
一、实践
二、理论问答
1.这张图属于 client-go 的 Informer 框架
配置和 Restclient或者 ClientSet 准备好后就可以通过客户端 CRUD k8s集群里面的资源
reflector 就是 watch和list k8s api 。就是监控资源变化和列出资源
ResourceVersion 资源版本,bookmark更新客户端保存的最近一次 ResourceVersion
reflector 与 api 交互需要通过各种client
缓存cache中的store.go, 通过crud将数据和store交互,key value形式构成的obj。
FIFO 就是queue,pop方法用来消费数据,传到下游,队列有两个下游,一个是sharedProcessor,另一个是存储的Cache,并实时更新。worker可以去Cache读取,不用去API server,减少了API server的压力
indexer/cache中的indexer的作用就是维护几个map,这样找东西好找,效率高,有的map,key是namespace,就很容器获取这个namespace下所有的资源。这就是索引的意义
这个图展示了 Kubernetes 中使用的 Informer 和 WorkQueue 之间的交互流程,是 Operator 框架的核心组件之一。以下是各个组件的作用和它们之间的工作流程:
1. Reflector
- 作用:
Reflector
从 Kubernetes API 服务器中拉取资源对象的最新状态,并将这些对象的变更(增量)存储在Delta FIFO Queue
中。 - 工作方式:通过
List and Watch
操作,Reflector
持续监听指定资源对象的变化。
2. Delta FIFO Queue
- 作用:
Delta FIFO Queue
维护了资源对象的变更(增量)队列,这些变更包括添加、更新和删除操作。 - 工作方式:当
Reflector
从 API 服务器接收到资源变更时,它会将这些变更放入Delta FIFO Queue
中。此队列确保变更按照它们发生的顺序进行处理。
3. Indexer/Cache
- 作用:
Indexer/Cache
负责将Delta FIFO Queue
中的变更应用到内存缓存中。缓存存储了当前集群中资源对象的完整状态,并允许通过索引高效地查找特定对象。 - 工作方式:它使用索引器来跟踪对象并允许快速查找,同时存储已缓存的对象。
4. Shared Processor
- 作用:
Shared Processor
负责将变更事件分发给注册的事件处理器。 - 工作方式:当
Delta FIFO Queue
中有变更时,Shared Processor
会将这些事件传递给所有注册的EventHandler
。
5. EventHandler
- 作用:
EventHandler
处理来自Shared Processor
的变更事件,并将需要处理的资源对象放入WorkQueue
中。 - 工作方式:
EventHandler
将处理事件并确定哪些对象需要进一步处理,通常是将它们的键(标识符)添加到WorkQueue
中。
6. WorkQueue
- 作用:
WorkQueue
存储需要处理的资源对象,通常按顺序处理每个对象。 - 工作方式:当
WorkQueue
中有资源对象时,它会依次将这些对象传递给Worker
进行处理。
7. Worker
- 作用:
Worker
是实际执行操作的组件,它从WorkQueue
中取出资源对象,并根据需要与 Kubernetes API 服务器交互(写操作)。 - 工作方式:
Worker
可能会执行一些复杂的业务逻辑,如创建、更新或删除 Kubernetes 资源对象,并将结果提交回 API 服务器。
8. API Server
- 作用:API 服务器是 Kubernetes 集群的核心组件,管理着集群的状态。所有资源对象的增删改查请求最终都需要通过 API 服务器来处理。
总结
整个流程涉及从 API 服务器监听对象变更,处理这些变更,并在需要时采取进一步操作。Informer 是一个高效的机制,允许 Kubernetes 控制器(如 Operator)保持对集群状态的了解,并根据资源的变化做出响应。
2. operator 中各种组件
Kubernetes Operator 由多个组件组成,每个组件都有其特定的作用,以下是一些关键组件的介绍:
1. controller-runtime
- 目的:一个简化构建控制器的库,提供了处理常见控制器任务的抽象,如管理调和循环、与 Kubernetes client-go 交互、处理主从选举等。
- 用途:用于创建、管理和运行控制器,这些控制器在 Kubernetes 集群中负责调和期望状态与实际状态。
2. controller-tools
- 目的:一组用于生成控制器和 CRD(自定义资源定义)代码和清单的工具。
- 用途:自动生成样板代码、CRD 清单和其他必要文件,减少手动编码的工作量。
3. operator-SDK
- 目的:一个帮助构建 Kubernetes Operator 的框架,提供脚手架、库和工具,简化 Operator 的创建过程。
- 用途:通过提供不同类型的 Operator(如 Go、Helm、Ansible),简化了开发、测试和打包 Kubernetes Operator 的流程。
4. webhook
- 目的:Webhook 是 HTTP 回调,用于在 Kubernetes Operator 中执行验证、变更和转换自定义资源等任务。
- 用途:用于在请求到达 Kubernetes API 服务器之前实施自定义业务逻辑、修改请求或验证资源以确保其符合特定要求。
5. code-generator
- 目的:一个工具,用于自动生成深度复制函数、客户端集、列出器、Informer 和其他用于自定义资源的辅助函数。
- 用途:帮助生成与 Kubernetes API 交互的 API 机械代码,使与 Kubernetes API 的交互更加高效。
6. kubebuilder
- 目的:一个类似于 Operator SDK 的框架,但更专注于使用自定义控制器创建 Kubernetes API。
- 用途:提供新项目的脚手架,生成样板代码,并与 controller-runtime 集成良好。
7. client-go
- 目的:Kubernetes 官方的 Go 语言客户端库,用于与 Kubernetes API 交互。
- 用途:提供一组函数和接口,用于与 Kubernetes API 服务器交互,控制器内部可以通过它来获取、创建、更新或删除资源。
8. apimachinery
- 目的:一组用于与 Kubernetes 风格的 API 交互的库,包含用于处理 JSON、YAML 和 HTTP 请求的工具。
- 用途:提供与 Kubernetes API 交互的基础构建块,几乎所有其他组件都依赖于它。
9. apiserver
- 目的:为自定义资源提供 API 服务器的组件,允许用户定义自己的 API。
- 用途:在构建复杂的 Operator 时使用,可能需要自己的 API 服务器,而不是依赖默认的 Kubernetes API 服务器。
10. metrics
- 目的:用于从 Operator 中导出自定义指标的库和工具。
- 用途:帮助将指标导出到如 Prometheus 这样的监控系统中,使 Operator 可以被有效监控。
11. envtest
- 目的:controller-runtime 提供的测试框架,用于在隔离环境中测试控制器。
- 用途:用于设置一个临时的 Kubernetes 控制平面,从而在不需要完整 Kubernetes 集群的情况下进行控制器的集成测试。
这些组件协同工作,帮助开发者高效地构建、管理和操作 Kubernetes Operator,实现 Kubernetes 集群内复杂操作的自动化。
3. client-go operator kubebuilder三者的关系
operator = CRD + Custom Controller 扩展 k8s 功能, 必须学习 Client-go, 来跟APIServer 交互
- client-go作为与Kubernetes集群交互的Go语言客户端,是实现Operator的基础工具库。
- Kubebuilder作为Operator的开发框架,依赖于
client-go
来提供与Kubernetes集群的交互能力。 - 开发者可以使用Kubebuilder快速生成Operator的代码框架,然后在生成的框架基础上使用client-go编写具体的业务逻辑,实现对自定义资源的管理。
4. webhook
让我们用一个非常简单的例子来说明Kubernetes中Webhook的作用。
假设你正在管理一个Kubernetes集群,并且你想要确保所有部署(Deployment)的副本数量(replicas)都不会超过3个。为了实现这一点,你可以使用一个Validating Webhook。
步骤1:定义Webhook
首先,你需要定义一个Validating Webhook,它会在任何Deployment资源创建或更新之前被调用。
步骤2:注册Webhook
然后,你需要在Kubernetes集群中注册这个Webhook,这样API Server就知道在处理Deployment资源之前调用它。
步骤3:实现Webhook逻辑
接下来,你需要实现Webhook的逻辑。这个逻辑会检查传入的Deployment对象的副本数量。如果副本数量大于3,Webhook将拒绝这个Deployment的创建或更新,并返回一个错误信息。
步骤4:使用Webhook
一旦Webhook被注册和实现,每当有人尝试创建或更新Deployment时,API Server就会先调用这个Webhook。如果Deployment的副本数量大于3,Webhook将阻止这个操作,并返回一个错误,比如:“副本数量不能超过3个。”
例子
假设有一个Deployment的YAML定义如下:
apiVersion: apps/v1
kind: Deployment
metadata:
name: my-deployment
spec:
replicas: 4 # 这里设置的副本数量是4
# 其他配置...
当尝试应用这个YAML时,API Server会调用Validating Webhook。Webhook检查spec.replicas
字段,发现它设置为4,超过了3的限制。因此,Webhook返回错误,Deployment不会被创建或更新。
这个例子展示了Webhook如何在Kubernetes集群中实现自定义的验证逻辑,确保资源的创建和更新符合特定的规则。
三、理论
Operator的主要目标是将工程师的逻辑转换为代码,以便实现原生Kubernetes无法完成的某些任务的自动化。
Operator由两个组件组成,自定义资源定义(CRD, Custom Resource Definition)和控制器(controller)。
控制器是特定于某种类型的资源的,但也可以对一组不同的资源执行CRUD(创建、读取、更新和删除)操作。
在Kubernetes的文档中举了一个控制器的例子: 恒温器。当我们设置温度时,告诉恒温器所需的状态,房间的实际温度就是当前的实际状态,恒温器通过打开或关闭空调,使实际状态更接近预期状态。
那管理器(manager)呢?该组件的目标是启动所有控制器,并使控制循环共存。假设项目中有两个CRD,同时有两个控制器,每个CRD对应一个控制器,管理器将启动这两个控制器并使它们共存。
完整链条
-
定义 CRD (Custom Resource Definition):
- 使用 YAML 文件定义 CRD,它描述了一种新的 Kubernetes 资源类型(如
RedisCluster
),并指定了这些资源的结构和字段。 - 通过
kubectl apply -f crd.yaml
命令将 CRD 应用到 Kubernetes 集群中。
- 使用 YAML 文件定义 CRD,它描述了一种新的 Kubernetes 资源类型(如
-
编写 Controller 逻辑:
- 使用 Go 语言编写 Controller,它负责监控和管理通过 CRD 创建的自定义资源(如
RedisCluster
)。 - Controller 监听 Kubernetes API 中与 CRD 相关的事件(如创建、更新、删除),并根据资源的状态做出相应的操作。
- 使用 Go 语言编写 Controller,它负责监控和管理通过 CRD 创建的自定义资源(如
-
打包 Operator:
- 将编写好的 Controller 代码打包成 Docker 镜像,使其能够在 Kubernetes 中运行。
- 使用
make docker-build
构建镜像,然后使用make docker-push
将镜像推送到 Docker 仓库。
-
部署 Operator 到 Kubernetes:
- 通过 Operator SDK 自动生成的 YAML 文件,使用
kubectl apply -f config/deploy/
将 Operator 部署到 Kubernetes 集群中。 - 这个部署过程会创建一个 Deployment,启动一个 Pod 运行你的 Operator 镜像。
- 通过 Operator SDK 自动生成的 YAML 文件,使用
-
创建自定义资源实例:
- 使用 YAML 文件定义一个具体的自定义资源实例(如
RedisCluster
),描述特定应用的配置。 - 通过
kubectl apply -f rediscluster.yaml
创建这个实例,Kubernetes API 会将其存储并触发 Controller 的事件监听。
- 使用 YAML 文件定义一个具体的自定义资源实例(如
-
Controller 监听和操作:
- Controller 监听到新的
RedisCluster
资源被创建的事件,读取其配置,并在 Kubernetes 集群中创建相应的资源(如 Pod、Service、StatefulSet 等)。 - 之后,Controller 持续监控
RedisCluster
资源的状态,处理扩展、缩容、备份等操作。
- Controller 监听到新的
-
状态反馈与更新:
- Controller 在 Kubernetes 集群中执行操作后,会将结果(如 Redis 集群的运行状态)更新到
RedisCluster
资源的Status
字段。 - Kubernetes API 会将这些状态信息存储并提供给用户或其他系统。
- Controller 在 Kubernetes 集群中执行操作后,会将结果(如 Redis 集群的运行状态)更新到