第四部分:Operator 快速入门

📝 前言

在 Kubernetes 世界里,资源对象(如 Deployment、Service)大多是声明式管理的:我们定义想要的状态,Kubernetes 负责让实际状态逐步趋近于目标。

但当应用逻辑复杂、需要自定义生命周期管理(如备份、恢复、自动扩容)时,内置的控制器就显得力不从心。

这时就需要 Operator 模式 —— 一种通过自定义控制器(Controller)来扩展 Kubernetes 的能力,让其“懂”你的应用。

简单理解:Operator = CRD(定义资源) + Controller(实现逻辑)

PS:这一篇也是云原生之旅第四部分的收官篇了,作为本系列最长的部分也终于是要完结了,下一部分就将进入 k8s 的 CI/CD 与 GitOps 实战篇。

🔍 使用场景

Operator 的最大价值在于:

将人工操作流程自动化、原子化,并原生融入 Kubernetes 生命周期管理中。

以下是几类常见的使用场景:

  • 数据库与中间件自动运维(有状态应用管理)
  • SaaS 多租户服务生命周期管理(自动场景各种资源)
  • CI/CD 与发布系统自动化(Argo Rollouts Operator等)

📋 前提条件

  • 已安装 Go 环境
  • 已部署 kubernetes 集群

PS:可参看之前文章一键部署:第四部分:使用 sealos 部署集群

🚀 详细步骤

1️⃣ 什么是 Operator?

Operator 是一种利用 Kubernetes 原生机制扩展集群功能的模式。

其核心由两部分组成:

  • CRD(CustomResourceDefinition)

定义自定义资源类型,如 MySQLClusterRedisInstance

  • Controller(控制器)

监控这些自定义资源的状态变化,并执行相应逻辑。

工作流程大致如下:

2️⃣ kubebuilder 介绍

kubebuilder 是 Kubernetes 官方推荐的 Operator 开发框架,基于 controller-runtime 库构建。

它提供了完整的代码生成、项目结构和测试工具,使得开发者能快速创建可维护的 Operator 项目。

3️⃣ 安装 kubebuilder

这里以 Linux 环境为例,首先需要安装 Go 环境。

1
2
3
4
5
6
7
8
9
10
11
# ubuntu 安装 go
sudo apt install golang-go

# 下载 kubebuilder
wget https://github.com/kubernetes-sigs/kubebuilder/releases/download/v4.9.0/kubebuilder_linux_amd64

# 设置权限并移动到PATH目录
chmod a+x kubebuilder_linux_amd64 && mv kubebuilder_linux_amd64 /usr/local/bin/kubebuilder

# 验证
kubebuilder version

4️⃣ 实战示例:创建第一个 Operator

1
2
3
4
5
6
7
8
9
# 1. 新建项目目录
mkdir -p /root/operator-demo
cd /root/operator-demo

# 2. 初始化 go module
go mod init example.com/operator-demo

# 3. 初始化 kubebuilder 工程
kubebuilder init --domain example.com --owner "lusyoe"

5️⃣ 创建自定义资源

App 资源为例:

1
2
# 创建 api
kubebuilder create api --group apps --version v1 --kind App

系统将生成:

  • api/v1/app_types.go:定义 CRD 结构
  • internal/controller/app_controller.go:控制逻辑
  • config/samples/apps_v1_app.yaml:配置文件

PS:如果需要重新创建api,需要删除以上3个文件并编辑PROJECT,删除对应的resources部分。

编辑 api/v1/app_types.go 文件,定义一个简单的字段:

1
2
3
4
type AppSpec struct {
Image string `json:"image"`
Replicas int32 `json:"replicas"`
}

6️⃣ 编写控制逻辑

controllers/app_controller.goReconcile 方法中,实现资源调谐逻辑:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
func (r *AppReconciler) Reconcile(ctx context.Context, req ctrl.Request) (ctrl.Result, error) {
var app appsv1.App
if err := r.Get(ctx, req.NamespacedName, &app); err != nil {
return ctrl.Result{}, client.IgnoreNotFound(err)
}

// 定义 Deployment
deploy := appsv1.Deployment{
ObjectMeta: metav1.ObjectMeta{
Name: app.Name,
Namespace: app.Namespace,
},
Spec: appsv1.DeploymentSpec{
Replicas: &app.Spec.Replicas,
Template: corev1.PodTemplateSpec{
Spec: corev1.PodSpec{
Containers: []corev1.Container{{
Name: "app",
Image: app.Spec.Image,
}},
},
},
},
}

// 创建或更新 Deployment
_, err := ctrl.CreateOrUpdate(ctx, r.Client, &deploy, func() error { return nil })
return ctrl.Result{}, err
}

7️⃣ 部署与验证

生成 CRD 并部署:

1
2
make install
make run

编辑自定义资源:

1
2
3
4
5
6
7
8
# config/samples/apps_v1_app.yaml
apiVersion: apps.example.com/v1
kind: App
metadata:
name: demo-app
spec:
image: nginx:alpine
replicas: 1

部署并验证:

1
2
kubectl apply -f config/samples/apps_v1_app.yaml
kubectl get pods

你将看到自动生成的 nginx Pod,这意味着 Operator 已成功运作。

完整项目已上传至 Github:https://github.com/lusyoe/operator-demo