上一篇【第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打包分发自己!
维度HelmOperator
运行一次性(渲染部署)常驻(持续调谐)
智能无(静态)有(含逻辑)
适合无状态应用有状态/复杂应用
编写难度低(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监控体系搭建完全指南


更多推荐