Kubernetes Operator 模式
Kubernetes Operator 模式

Kubernetes Operator
Operator 是 Kubernetes 的扩展软件,它利用 自定义资源(Custom Resource)管理应用及其组件。 Operator 遵循 Kubernetes 的理念,特别是在控制回路方面。其目的应该是帮助我们更轻松地解决应用程序 Pod 中的某些问题。
为什么需要 Operator
在 Kubernetes 中已经提供了很多控制器(Controller), 如: Deployments、Statefulsets、ReplicaSet、DaemonSet 等, 它们负责 管理/维护 Pods 对象的状态。
But!
如果我们需要对一些专业的服务如: Mysql、Prometheus 等. 进行更好的控制与管理, 我们可能需要更精细, 更具体的领域知识进行操作, 以正确管理我们的应用程序和组件的状态, 但是实际上我们希望服务的 开发人员/用户/管理者 可以更容易, 更透明的进行一些重复的操作与控制。 这时我们就需要使用 Kubernetes Operator. Operator 可以让 开发人员/用户/管理者 在使用这些专业的服务时, 像使用 Kubernetes 一样 只需要编写约定的内置资源就可以简单的 创建/管理 这些服务.
Custom Resource
定制资源(Custom Resource)- 是对 Kubernetes API 的扩展。定制资源- 所代表的是对特定 Kubernetes 安装的一种定制。 不过,很多 Kubernetes 核心功能现在都用定制资源来实现,这使得 Kubernetes 更加模块化。定制资源- 可以通过动态注册的方式在运行中的集群内或出现或消失,集群管理员可以独立于集群 更新定制资源。一旦某定制资源被安装,用户可以使用 kubectl 来创建和访问其中的对象,就像他们为 pods 这种内置资源所做的一样。资源(Resource)- 是 Kubernetes API 中的一个端点, 其中存储的是某个类别的 API 对象 的一个集合。 例如内置的 Pods 资源包含一组 Pod 对象。
Custom Controller
定制资源 (Custom Resource)- 本身而言,它只能用来存取结构化的数据。控制器- 负责将结构化的数据解释为用户所期望状态的记录,并持续地维护该状态。所以当
定制资源与定制控制器相结合时,定制资源就能够提供真正的声明式 API(Declarative API)。使用声明式 API, 你可以 声明 或者设定你的资源的期望状态,并尝试让 Kubernetes 对象的当前状态 同步到其期望状态。
一级资源和二级资源
正如前面所说,
Operator是CRD相关的控制器, 它观察并根据配置变化或集群状态变化来采取行动。但实际上控制器需要监测两种资源, 一级资源和二级资源。对于
ReplicaSet, 一级资源是ReplicaSet本身, 指定运行的Docker镜像以及Pod的副本数。二级资源则是Pod。 当ReplicaSet的定义发生改变(例如镜像版本或Pod数量)或者其中的Pod发生改变时(例如某个Pod被删除), 控制器则会通过推出新版本来协调集群状态, 或是对Pod数量扩缩容。对于
DaemonSet, 一级资源是DaemonSet本身, 而二级资源是Pod和Node。不同之处在于, 控制器也会监测集群Node变化, 以便在群集增大或缩小时添加或删除Pod。
如何开发 Operator

定制控制器 支持多种语言开发, 如: Golang、Python 等, 我们只需要实现 Controller 与 Kubernetes API 通信既可。
在开发 Kubernetes Operator 时需要遵循 Kubernetes 规则, 其实社区中已经有大量的开源可用的框架. 如:
Kubebuilder- https://github.com/kubernetes-sigs/kubebuilder- 该框架来自 kubernetes-SIG(特殊兴趣小组),成立于2018年7月。它有望提高速度并减少开发人员管理的复杂性。
Operator SDK- https://sdk.operatorframework.io/这是
Red Hat的产品, 不仅具有使用 Go语言 构建Operator的能力, 而且还具有Ansible和Helm Charts的 构建能力。它与
CNCF Landscape Operator Framework相关联。CNCF Landscape Operator Framework- https://landscape.cncf.io/selected=operator-framework
KUDO- https://kudo.dev/- KUDO 号称是使用 声明式方式 构建生产级别的 Kubernetes Operator 服务.
Docker / Kubernetes
在开发 Operator 之前, 我们需要一个 Kubernetes, 如果您没有 Kubernetes,我建议您使用
Kind。Kind- https://kind.sigs.k8s.io/ – 它是一种使用 Docker 容器做为Node运行 Kubernetes 本地集群的工具。
Kubernetes Operator 工作流程
- 如下是一个名为
PodBuggerTool的 Kubernetes Operator . 如下为 Operator PodBuggerTool 工作流程


不断 Watching Pods 的 事件(events).
当在事件 events 普抓到 创建/更新 的事件时, 对该事件进行处理.
将
Pod的 Labels 与我们使用PodBuggerTool插入的 Labels 进行比较(基于其CRD).如果我们意识到
Pod包含我们感兴趣的任何 Labels,既可进行一些操作.使用同样由我们的
PodBuggerTool指定的 image,在此Pod中添加一个新容器(作为临时容器)(在那里,我们可以在其定义中找到 Label 与 image 的相关性).
开发一个 Operator
- 利用
Operator SDK创建一个 Pods 相关的 Operator, 它的作用是 启动一个容器 busybox 执行 Sleep 3600s , 并管理 Pods 数量的扩容和缩容。
Operator SDK
- 安装 Operator SDK Version 1.5.0
| |
- 初始化 Operator 项目
| |
| |
- 添加
CRD和controller_manager(控制器)
| |
| |
Operator 代码结构
api/v1alpha1/podset_type.go定义了 PodSet 预期状态的结构体.
| |
修改了
type资源, 执行make generate更新资源修改后的代码生成.- 上面的
make generate目的调用controller-gen程序来更新api/v1alpha1/zz_generated.deepcopy.go文件, 以确保我们API的Go类型定义实现了runtime.Object所有 Kind 类型必须实现的接口。
- 上面的
| |
生成
CRD资源清单 , 执行make manifests- 生成的
CRD存于config/crd/bases/apps.jicki.cn_podsets.yaml
- 生成的
| |
| |
controllers控制器controllers/podset_controller.go文件中NewControllerManagedBy用于各种控制器的配置For(&appsv1alpha1.PodSet{})用于将PodSet{}类型指定为要监视的主要资源, 在对PodSet{}类型的资源进行Add/Update/Delete操作时, 循环发送 Request
podset_controller.go—
| |
生成授权的
rbac清单- 配置权限如下权限清单到
podset_controller.go文件中
- 配置权限如下权限清单到
| |
- 生成 —
| |
config/rbac/role.yaml文件
| |
运行 Operator
- 首先修改一下 Dockerfile 的镜像地址
gcr.io/distroless/static:nonroot改为alpine:3.11
| |
- build images
| |
- 创建一个 deployment.yaml
| |
- 运行 CRD 资源
| |
- 运行 rbac 资源
| |