【Kubernetes从入门到精通】第74篇:Operator模式——让K8s学会“自动驾驶“,把DBA的活也干了
上一篇【第73篇】Helm——K8s的“包管理器“,从此告别复制粘贴YAML的地狱
下一篇【第75篇】Prometheus和Grafana——K8s监控体系搭建完全指南
摘要
上篇讲了Helm——它把"部署应用"标准化了。但部署只是开始,真正的麻烦在运维:MySQL主从怎么自动故障切换?Redis哨兵挂了怎么自动重建?ETCD集群怎么滚动升级不丢数据?备份怎么定时做?
这些"领域专家知识"Helm表达不了——它是静态模板,不懂应用的运行时逻辑。这就需要Operator模式:用CRD定义"我想要一个什么样的MySQL集群",用自定义控制器把DBA的运维经验写进代码,让K8s自动照料这个应用的一生。
这篇文章讲清Operator的本质、Operator Framework三件套,并用Kubebuilder演示写一个Redis Operator的思路。
一、Operator的本质
1.1 CRD + Controller
【Operator = CRD (我要啥) + Controller (你怎么实现)】
回忆第072篇的CRD:
• CRD 只定义"MysqlCluster长什么样"
• 创建了存etcd,但没人实现它
Operator补上"实现"那部分:
• 一个自定义控制器(Controller)
• 盯着MysqlCluster资源
• 把"领域专家知识"写成代码:
- 创建StatefulSet + Headless Service
- 初始化主从复制
- 监控主节点健康
- 主挂了 → 选新主 → 重配从节点
- 定时备份
- 滚动升级不停服
要点:Operator的核心思想是把人类专家的运维经验代码化。一个资深DBA知道MySQL主从怎么搭、怎么切换、怎么备份——Operator就是把这些知识写成一个永远在线的控制器。它让"部署+运维"全自动化,用户只需声明"我要一个3节点的MySQL 8.0集群",剩下的K8s自己搞定。
二、Operator Framework三件套
2.1 官方工具链
【Operator Framework (CNCF项目)】
┌──────────────────────────────────────────┐
│ 1. Operator SDK │
│ • 脚手架工具,快速生成代码骨架 │
│ • 支持 Go / Ansible / Helm 三种语言写 │
│ • 一条命令生成CRD+Controller模板 │
└──────────────────────────────────────────┘
┌──────────────────────────────────────────┐
│ 2. Operator Lifecycle Manager (OLM) │
│ • 管理Operator的安装/升级/依赖 │
│ • 像"Operator的应用商店" │
│ • 处理Operator自身的版本迭代 │
└──────────────────────────────────────────┘
┌──────────────────────────────────────────┐
│ 3. OperatorHub │
│ • 公开 registry,找现成Operator │
│ • Redis/MySQL/ETCD/Prometheus...都有 │
│ • 大部分场景不用自己写,直接用现成 │
└──────────────────────────────────────────┘
| 组件 | 作用 | 类比 |
|---|---|---|
| Operator SDK | 写Operator的工具 | 脚手架 |
| OLM | 管Operator生命周期 | 包管理器 |
| OperatorHub | 找现成Operator | 应用商店 |
三、实战:用Kubebuilder写Redis Operator
3.1 脚手架
# 1. 初始化项目
kubebuilder init --domain example.com --repo github.com/me/redis-operator
# 生成: main.go, Dockerfile, Makefile, config/ ...
# 2. 创建API (CRD + Controller骨架)
kubebuilder create api --group cache --version v1 --kind RedisCluster
# 生成: api/v1/rediscluster_types.go (CRD Go定义)
# controllers/rediscluster_controller.go (控制器骨架)
# 3. 在 types.go 里定义Spec/Status
# RedisClusterSpec:
# replicas: 3
# version: "7.0"
# storage: 10Gi
# RedisClusterStatus:
# phase: Running / Failed
# readyReplicas: 3
3.2 控制器逻辑(伪代码)
// controllers/rediscluster_controller.go
func (r *RedisClusterReconciler) Reconcile(ctx, req) {
// 1. 拿到用户声明的RedisCluster
var rc RedisCluster
r.Get(ctx, req.NamespacedName, &rc)
// 2. 确保StatefulSet存在(3个Redis节点)
if !statefulSetExists(rc) {
createStatefulSet(rc) // 用Headless Service(第022篇)
}
// 3. 确保主从复制配置
ensureReplication(rc) // 选主、配从
// 4. 监控健康
if masterDown(rc) {
electNewMaster(rc) // 自动故障切换!
reconfigureSlaves(rc)
}
// 5. 更新status
rc.Status.ReadyReplicas = countReady(rc)
r.Status().Update(ctx, &rc)
// 6. 定期requeue(持续监控)
return ctrl.Result{RequeueAfter: 30 * time.Second}, nil
}
# 部署后,用户只需一句话
kubectl apply -f - <<EOF
apiVersion: cache.example.com/v1
kind: RedisCluster
metadata:
name: my-redis
spec:
replicas: 3
version: "7.0"
storage: 10Gi
EOF
# Operator自动: 起3节点StatefulSet、配主从、监控、故障切换
要点:Kubebuilder生成的骨架已经把"Informer/WorkQueue/Reconcile"那套(第063篇)搭好了,你只需填空:在Reconcile里写"让实际状态靠拢期望状态"的逻辑。这就是标准的控制器模式——只不过管的是你自己的CRD。你写的Operator跑在集群里,永远在线、永远对账,把DBA的活自动化了。
四、Operator vs Helm
4.1 定位不同
【Helm 管"部署" vs Operator 管"运维"】
Helm:
• 静态模板 → 渲染 → apply
• 部署完就"不管了"
• 适合: 无状态/标准化应用(nginx/web)
• 不懂应用的运行时逻辑
Operator:
• 常驻控制器 → 持续监视 → 自动调谐
• 部署完"一直在管"
• 适合: 复杂有状态应用(数据库/中间件)
• 把运维专家知识代码化
配合: 很多Operator用Helm打包分发自己!
| 维度 | Helm | Operator |
|---|---|---|
| 运行 | 一次性(渲染部署) | 常驻(持续调谐) |
| 智能 | 无(静态) | 有(含逻辑) |
| 适合 | 无状态应用 | 有状态/复杂应用 |
| 编写难度 | 低(YAML) | 高(Go代码) |
五、什么时候该写Operator
【决策树】
你要部署的是?
│
├─ 标准无状态应用(web/nginx)
│ → Helm 足够(别过度设计)
│
├─ 复杂有状态应用(MySQL/Redis/ETCD)
│ ├─ 社区有现成Operator?
│ │ → 直接用(OperatorHub上找)
│ │
│ └─ 没有现成的 / 特别定制?
│ → 自己写Operator
│
└─ 只是部署+简单配置?
→ Helm(别为简单需求写Operator)
本篇小结
Operator=CRD+自定义控制器,把人类运维专家的领域知识代码化,让K8s自动照料复杂有状态应用的一生(部署、主从、故障切换、备份、升级)。Operator Framework提供SDK(脚手架)、OLM(生命周期管理)、OperatorHub(现成仓库)。
用Kubebuilder写Operator时,骨架已搭好Informer/Reconcile,你只需在Reconcile里写"对齐逻辑"。Operator管"运维"、Helm管"部署",定位互补(很多Operator还用Helm打包自己)。决策口诀:标准无状态用Helm,复杂有状态先找现成Operator,没有再自己写。下篇讲监控——Prometheus+Grafana。
上一篇【第73篇】Helm——K8s的“包管理器“,从此告别复制粘贴YAML的地狱
下一篇【第75篇】Prometheus和Grafana——K8s监控体系搭建完全指南
更多推荐
所有评论(0)