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 资源
|
|