Operator 模式基础回顾

在深入指标与告警集成之前,必须牢固掌握 Operator 模式的核心原理。Operator 本质上是将运维专家的领域知识编码为软件,通过 Kubernetes 原生机制自动管理复杂有状态应用。本节从概念、组件到循环机制逐层拆解。

2.1 Operator 概念与价值

Operator 是一种扩展 Kubernetes 平台的方法,它利用 自定义资源(CR) 和 自定义控制器 来封装特定应用或组件的运维逻辑。其核心价值在于将“人如何操作”转化为“机器如何自动执行”。

维度 传统运维 Operator 模式
知识载体 运维手册、Runbook、个人经验 代码(Go / Ansible / Helm)
执行方式 人工 SSH / 脚本触发 Kubernetes 控制循环自动驱动
故障恢复 被动告警 + 人工介入 主动自愈 + 状态收敛
版本升级 手动执行升级脚本 CR 字段变更触发滚动升级
扩展性 依赖外围工具链 原生 Kubernetes API 扩展
关键认知: Operator 不是简单的“部署工具”,而是将期望状态(Spec)与实际状态(Status)之间的差距,通过 Reconcile 循环持续缩小至零的闭环系统。

2.2 CRD 与 Controller 原理

Operator 由两大核心组件构成:自定义资源定义(CRD) 和 Controller。CRD 定义数据模型,Controller 实现业务逻辑。

2.2.1 自定义资源定义(CRD)

CRD 是 Kubernetes API 的扩展机制。通过声明 CRD,你可以定义新的资源类型(如 RedisCluster、Prometheus),Kubernetes 会像处理原生 Pod、Service 一样处理这些资源。

apiVersion: apiextensions.k8s.io/v1
kind: CustomResourceDefinition
metadata:
  name: redisclusters.cache.example.com
spec:
  group: cache.example.com
  names:
    kind: RedisCluster
    plural: redisclusters
    singular: rediscluster
  scope: Namespaced
  versions:
  - name: v1
    served: true
    storage: true
    schema:
      openAPIV3Schema:
        type: object
        properties:
          spec:
            type: object
            properties:
              replicas:
                type: integer
                minimum: 1
              version:
                type: string
          status:
            type: object
            properties:
              readyReplicas:
                type: integer
              phase:
                type: string
设计建议: CRD 的 spec 应只包含用户关心的业务参数(如副本数、版本),而 status 用于反映控制器观测到的实际状态(如就绪副本数、当前阶段)。避免将运维内部状态暴露给用户。

2.2.2 Controller 工作原理

Controller 是一个持续运行的循环,它通过 Informer 机制 监听 CR 和关联资源(如 Pod、Service)的变化。当事件发生时,Controller 将相关对象放入工作队列,由 Reconcile 函数处理。

  1. Watch: 使用 Informer 监听 CR 和 Owner 资源的变化(Add / Update / Delete)。
  2. Enqueue: 将变化事件转换为 ReconcileRequest(包含命名空间/名称)放入工作队列。
  3. Reconcile: 从队列取出请求,读取当前状态,对比期望状态,执行操作(创建/更新/删除子资源)。
  4. Update Status: 将最新的实际状态写回 CR 的 status 字段。
CRD 与 Controller 交互流程 用户 / kubectl API Server etcd Informer (Watch) Work Queue Controller Reconcile 循环 Pod / Service / ConfigMap 事件驱动 Add / Update Delete 事件 触发 Reconcile

2.3 Reconcile 循环机制

Reconcile 是 Operator 的核心执行单元。每次 Reconcile 请求都代表一次“将实际状态调整为期望状态”的尝试。理解其内部阶段是开发可靠 Operator 的基础。

2.3.1 标准 Reconcile 阶段

阶段 输入 输出 典型操作
1. 获取 CR ReconcileRequest (ns/name) CR 实例(或 NotFound) r.Get(ctx, req.NamespacedName, &cr)
2. 观测子资源 CR 的 Spec 字段 当前子资源列表 r.List(ctx, &pods, client.MatchingLabels(...))
3. 计算差异 期望状态 vs 实际状态 操作计划(创建/更新/删除) 比较副本数、镜像版本、端口等
4. 执行操作 操作计划 子资源变更结果 r.Create / r.Update / r.Delete
5. 更新状态 最新实际状态 CR.Status 更新 r.Status().Update(ctx, &cr)
6. 返回结果 成功 / 失败 / 重试 ReconcileResult ctrl.Result{Requeue: true}

2.3.2 重试与背压机制

Reconcile 循环内置了智能重试策略,避免因临时故障导致 API Server 过载:

  • 立即重试: 返回 Requeue: true,控制器会立即将请求重新入队。
  • 延迟重试: 返回 RequeueAfter: 5 * time.Second,指定延迟时间后重试。
  • 指数退避: 连续失败时,工作队列自动增加重试间隔(默认 5ms → 300s)。
  • 最大重试次数: 超过阈值后,请求被丢弃并记录 Error 事件。
常见陷阱: 不要在 Reconcile 函数内使用 time.Sleep 实现延迟。这会阻塞整个工作队列的消费者 goroutine,导致其他 CR 的 Reconcile 被饿死。应始终使用 RequeueAfter 机制。
Reconcile 循环内部状态机 获取 CR 观测子资源 计算差异 执行操作 更新状态 返回结果 需要 重试? 重试策略 Requeue: true → 立即 RequeueAfter → 延迟

2.4 指标与告警的切入点

理解 Reconcile 循环后,就能精准定位指标采集和告警规则的位置:

  • Reconcile 耗时: 每次 Reconcile 的执行时长,反映控制器性能瓶颈。
  • Reconcile 错误率: 返回错误结果的 Reconcile 次数,直接反映运维健康度。
  • 工作队列深度: 等待处理的 Reconcile 请求数量,预示控制器是否积压。
  • CR 状态相位: 自定义资源当前处于 Running、Failed、Pending 等状态。
  • 子资源偏差: 期望副本数与实际运行副本数的差值。
实战要点: 在 Reconcile 函数的入口和出口处埋点,使用 Prometheus Histogram 记录耗时,使用 Counter 记录错误。这些指标将成为后续告警规则的直接数据源。