目录
一、背景
Kubernetes Operator 是一种用于简化和自动化 Kubernetes 应用程序管理的模式。它扩展了 Kubernetes API,允许开发者定义自定义资源,并通过控制器来管理这些资源的生命周期。
现在的部署方式再配合上运维平台的自动化工具已经能满足绝大部分的运维诉求了。但是在业务复杂时往往需要一些自定义的运维操作来满足资源生命周期过程中各个环节的需求。
Operator的有如下的能力和优势:
1、CI/CD 部署时利用自定义声明式yaml简化部署流程
2、运行时期间,可根据资源状态动态调整资源规格,类型,数量,大小
3、扩展自定义资源运维策略,是其完全按照实际业务的要求来管理自身以及依赖的资源
4、在程序异常时 可以定制恢复策略,备份数据,记录异常信息,预警等
5、更加优雅的实现程序特有的架构模式
operatorhub.io中有丰富的Operator开源项目。感兴趣的小伙伴可以进一步了解。如下是官网的部分截图可是看到。
二、概念对齐
2.1 Kubernetes 资源类型列表
Kubernetes采用 etcd 作为其主要的数据存储组件。通过 API Server 对外提供 RESTful API 接口服务,以便用户和系统进行交互。用户可以通过 HTTP 请求对资源类型进行创建、读取、更新和删除操作。这种方式非常类似于 Spring Boot + MySQL 的组合,即一个服务提供 REST 接口,另一个提供数据存储服务。
而 scheduler、controller-manager、kubelet 和 kube-proxy 等核心组件会监听 etcd 中资源类型数据的变更,从而实现 Kubernetes 资源的生命周期管理,例如 Deployments、Pod、Service 等。这些操作基本上由 Kubernetes 自动完成,无需上层应用过多关注。
### 查询当前k8s 资源类型列表
kubectl api-resources
这个截图包含所有的底层数据结构 资源类型。我们接下来所要实现的目标就是对这些Kind进行增 删 改 查。
2.2 Restful API使用
可以通过kubectl直接在linux服务器上直接交互,也可以通过sdk的方式直接访问使用。需要提前配置好认证和授权文件kube-config。 Operator可以采用多种语言编写。笔者会选用Goalng作为开发语言进行演示。
2.3 CRD是什么
在Kubernetes中,CRD(Custom Resource Definition,自定义资源定义)允许用户扩展Kubernetes API,创建新的资源类型。通过CRD可以定义和管理自定义的资源,就像Kubernetes内置资源类型(例如:Pods、Services)。
相当于你在原来的kubectl api-resources 基础之上又扩展了一个新的资源类型。但是这个新的资源类型没有控制器(controller)能识别。即便是部署了也不会有实际的效果。需要我们自己编写Operator Controller去处理CRD以及声明式yaml的请求。
2.4 Group是什么
Group 是在 Kubernetes 集群中组织和管理自定义资源的强大机制。它提供了一种对自定义资源进行命名空间划分、管理 API 版本以及促进 operator 开发和管理的方法。例如:Pod在core group,Deployments在apps group,Ingress在networking.k8s.io group等等
2.5 申明式编程是什么
在Kubernetes中,申明式编程是一种描述系统的目标状态而不是操作步骤的编程方式。在这种模型中,你定义期望的系统状态,Kubernetes负责确保系统达到并维持这种状态。通常采用yaml或者json方式来作为申明文件。Pod声明式yaml文件 示例如下:
apiVersion: apps/v1
kind: Deployment
metadata:
name: demo
spec:
replicas: 3
selector:
matchLabels:
app: demo
template:
metadata:
labels:
app: myapp
spec:
containers:
- name: demo
image: nginx:latest
ports:
- containerPort: 8080
Operator开发过程中也是用到申明式文件格式用来和operator系统,进行交互。告诉Operator如何去管理各个资源的生命周期以及一些定制化的运维操作。
三、实战入门
Operator 通过CRD监听自定义的资源类型Kind创建,更新,删除 (例如:Pod)。再根据业务逻辑判定接下来的执行流程。最终都是需要调用apiaerver服务的Restful API来完成。
3.1 基础环境准备
1) kubernetes基础环境
如果已经有k8s 开发环境配置好kube-config (~/.kube/config) 远程连接即可。笔者使用minikube在本机搭建的一个简易版k8s 供调试使用
这里2.2章节里面有如何使用minikube搭建环境的http://t.csdnimg.cn/6n0As
2) Golang基础环境
如果开发Operator采用的Java语言此处就安装JDK即可,笔者采用的是Golang语言。
直接下载安装即可:
https://go.dev/dl/go1.23.0.darwin-arm64.pkg
vim ~/.bash_profile
export GOPATH=$HOME/go
export PATH=$PATH:/usr/local/go/bin:$GOPATH/binsource ~/.bash_profile
All releases - The Go Programming Languagehttps://go.dev/dl/
3) 开发工具准备
选用vscode或者Goland工具 都可以,需要读者搭建好开发的环境。
3.2 Operator 脚手架代码生成
不同语言的脚手架项目 可以生成脚手架代码帮助快速开发。
- Charmed Operator Framework
- Java Operator SDK
- Kopf (Kubernetes Operator Pythonic Framework)
- kube-rs (Rust)
- kubebuilder
- KubeOps (.NET operator SDK)
- Metacontroller,可与 Webhook 结合使用,以实现自己的功能。
- Operator Framework
- shell-operator
笔者选用的是kubebuilder框架进行调试,如果Java语言可以使用Java Operator SDK这个开源框架。
### 在本地电脑安装上kubebuilder和kustomize
brew install kubebuilder
brew install kustomize
## 生成脚手架代码
kubebuilder init --domain ta.cn
## 生成 api group 代码
kubebuilder create api --group demo --version v1 --kind Hello
### 生成CRD yaml文件
make manifests
3.3 Operator 部分代码介绍
代码生成过后是这样的目录结构
梳理一下资源清单
operator自身部署yaml清单
CustomResourceDefinition
namespace
ServiceAccount
RBAC
deployment
申明式 自定义yaml配置文件
注意:
如果在修改代码过后需要重新生成脚手架代码。特别是Types中的***Spec 结构体变化后需要重新生成CRDyaml。
3.4 逻辑代码编写 & 调试
通过代码调试之前必须要部署 CRD CustomResourceDefinition
#### 部署CRD
kubectl apply -f config/crd/bases/demo.demo.cn_hellos.yaml
### 查看crd是否已经存在
kubectl get crd
kubectl get apiservice
到此hello 已经运行出来了。可以根据yaml文件里面的信息在逻辑代码区 执行自定义的运维操作。业务代码区域可以实现Kubernetes资源对象的增 删 改 查进而可以管理和控制集群中的资源。比如 Pod,Deployments,Service等,限于篇幅本文不再展开。
3.5 制作双架构镜像 & helm包
1) 制作镜像
### 安装buildx插件
docker buildx install
### 安装buildx构建器
docker buildx create --use
### 开始制作arm64 amd64 镜像
docker buildx build \
--platform linux/amd64,linux/arm64 \
-t registry.cn-shanghai.aliyuncs.com/xy-yun/operator-demo:v1.0.0 . \
--push
笔者使用的是阿里云的私有仓库来测试的
2) 制作helm包
### 可以将离散的yaml导出到一个文件
kustomize build config/default > hello-deploy.yaml
部分yaml截图
需要手动给改造成一个helm,也可以直接使用yaml部署测试。
3.6 测试验证
helm部署 查看operator-demo是否正常的启动
helm upgrade --install operator-demo operator-demo
kubectl get po -A
部署自定义申明式yaml
kubectl apply -f config/samples/demo_v1_hello.yaml
查看operator-demo日志是否正确的处理了 yaml的请求
可以看到已经正确的输出日志。后续要扩展至需要controller的Reconcile中添加业务逻辑处理代码即可。
四、小结
本文介绍了Operator是什么 有什么作用 应用场景有哪些,也介绍了Operator完整的开发过程。包括:利用Kubebuild 开源项目生成Operator脚手架工程,IDE测试代码调试,制作镜像再部署调试等。希望能打破Kubernetes Operator技术壁垒,让更多的人能轻松上手。利用云原生的技术为企业创造更多价值。
参考文档
客户端库 | Kubernetes本页面概要介绍了基于各种编程语言使用 Kubernetes API 的客户端库。在使用 Kubernetes REST API 编写应用程序时, 你并不需要自己实现 API 调用和 “请求/响应” 类型。 你可以根据自己的编程语言需要选择使用合适的客户端库。客户端库通常为你处理诸如身份验证之类的常见任务。 如果 API 客户端在 Kubernetes 集群中运行,大多数客户端库可以发现并使用 Kubernetes 服务账号进行身份验证, 或者能够理解 kubeconfig 文件 格式来读取凭据和 API 服务器地址。官方支持的 Kubernetes 客户端库 以下客户端库由 Kubernetes SIG API Machinery 正式维护。语言 客户端库 样例程序 C github.com/kubernetes-client/c 浏览 dotnet github.com/kubernetes-client/csharp 浏览 Go github.com/kubernetes/client-go/ 浏览 Haskell github.com/kubernetes-client/haskell 浏览 Java github.com/kubernetes-client/java 浏览 JavaScript github.com/kubernetes-client/javascript 浏览 Perl github.com/kubernetes-client/perl/ 浏览 Python github.com/kubernetes-client/python/ 浏览 Ruby github.com/kubernetes-client/ruby/ 浏览 社区维护的客户端库 说明: 本部分链接到提供 Kubernetes 所需功能的第三方项目。Kubernetes 项目作者不负责这些项目。此页面遵循CNCF 网站指南,按字母顺序列出项目。要将项目添加到此列表中,请在提交更改之前阅读内容指南。 以下 Kubernetes API 客户端库是由社区,而非 Kubernetes 团队支持、维护的。https://kubernetes.io/zh-cn/docs/reference/using-api/client-libraries/Operator 模式 | KubernetesOperator 是 Kubernetes 的扩展软件, 它利用定制资源管理应用及其组件。 Operator 遵循 Kubernetes 的理念,特别是在控制器方面。初衷 Operator 模式 旨在记述(正在管理一个或一组服务的)运维人员的关键目标。 这些运维人员负责一些特定的应用和 Service,他们需要清楚地知道系统应该如何运行、如何部署以及出现问题时如何处理。在 Kubernetes 上运行工作负载的人们都喜欢通过自动化来处理重复的任务。 Operator 模式会封装你编写的(Kubernetes 本身提供功能以外的)任务自动化代码。Kubernetes 上的 Operator Kubernetes 为自动化而生。无需任何修改,你即可以从 Kubernetes 核心中获得许多内置的自动化功能。 你可以使用 Kubernetes 自动化部署和运行工作负载,甚至 可以自动化 Kubernetes 自身。Kubernetes 的 Operator 模式概念允许你在不修改 Kubernetes 自身代码的情况下, 通过为一个或多个自定义资源关联控制器来扩展集群的能力。 Operator 是 Kubernetes API 的客户端, 充当自定义资源的控制器。Operator 示例 使用 Operator 可以自动化的事情包括:按需部署应用 获取/还原应用状态的备份 处理应用代码的升级以及相关改动。例如数据库 Schema 或额外的配置设置 发布一个 Service,要求不支持 Kubernetes API 的应用也能发现它 模拟整个或部分集群中的故障以测试其稳定性 在没有内部成员选举程序的情况下,为分布式应用选择首领角色 想要更详细的了解 Operator?下面是一个示例:有一个名为 SampleDB 的自定义资源,你可以将其配置到集群中。 一个包含 Operator 控制器部分的 Deployment,用来确保 Pod 处于运行状态。 Operator 代码的容器镜像。 控制器代码,负责查询控制平面以找出已配置的 SampleDB 资源。 Operator 的核心是告诉 API 服务器,如何使现实与代码里配置的资源匹配。 如果添加新的 SampleDB,Operator 将设置 PersistentVolumeClaims 以提供持久化的数据库存储, 设置 StatefulSet 以运行 SampleDB,并设置 Job 来处理初始配置。 如果你删除它,Operator 将建立快照,然后确保 StatefulSet 和 Volume 已被删除。 Operator 也可以管理常规数据库的备份。对于每个 SampleDB 资源,Operator 会确定何时创建(可以连接到数据库并进行备份的)Pod。这些 Pod 将依赖于 ConfigMap 和/或具有数据库连接详细信息和凭据的 Secret。 由于 Operator 旨在为其管理的资源提供强大的自动化功能,因此它还需要一些额外的支持性代码。 在这个示例中,代码将检查数据库是否正运行在旧版本上, 如果是,则创建 Job 对象为你升级数据库。 部署 Operator 部署 Operator 最常见的方法是将自定义资源及其关联的控制器添加到你的集群中。 跟运行容器化应用一样,控制器通常会运行在控制平面之外。 例如,你可以在集群中将控制器作为 Deployment 运行。
https://kubernetes.io/zh-cn/docs/concepts/extend-kubernetes/operator/