2. KEDA 核心概念:ScaledObject、Scaler、Trigger、HPA 的关系与工作原理

Kubernetes 原生 HPA(Horizontal Pod Autoscaler)仅支持 CPU/内存等资源指标,无法直接感知消息队列长度、HTTP 请求速率、数据库连接数等业务指标。KEDA(Kubernetes Event-Driven Autoscaling)通过引入 ScaledObject、Scaler、Trigger 三个核心抽象层,将外部事件源与 HPA 桥接起来,实现基于任意自定义 Metric 的弹性伸缩。

2.1 核心概念速览

概念 角色 关键职责
ScaledObject 自定义资源(CRD) 声明式定义伸缩目标、触发器、边界条件
Scaler 指标采集适配器 连接外部系统,拉取业务指标值
Trigger Scaler 的配置描述 指定 Scaler 类型、连接参数、阈值
HPA K8s 原生控制器 根据指标值计算期望副本数并调整 Deployment
一句话理解:ScaledObject 是“指挥中心”,Trigger 是“传感器配置”,Scaler 是“传感器驱动”,HPA 是“执行机构”。

2.2 四者协作关系

KEDA 并不替代 HPA,而是作为 HPA 的“指标上游”。整个伸缩链路分为四个阶段:

  1. 用户定义 ScaledObject:在 YAML 中声明目标 Deployment、Trigger 类型(如 Kafka、Prometheus、RabbitMQ)及阈值。
  2. KEDA Operator 生成 HPA:Operator 监听 ScaledObject 资源,自动创建或更新对应的 HPA 对象。
  3. Scaler 采集指标:KEDA 内置的 Scaler 根据 Trigger 配置连接外部系统,将业务指标转换为标准 Metric 值。
  4. HPA 执行伸缩:HPA 定期从 KEDA Metrics Adapter 拉取指标,计算期望副本数并调整 Deployment 的 replicas。
KEDA 核心组件协作流程 用户 / 运维 ScaledObject KEDA Operator HPA Deployment Scaler 外部系统 创建/更新 生成 HPA 调整副本数 调用 Scaler 拉取指标 暴露指标

2.3 ScaledObject 深度解析

ScaledObject 是 KEDA 的入口 CRD,包含三个核心字段组:

字段路径 作用 示例值
scaleTargetRef 指定伸缩目标(Deployment/StatefulSet) name: my-app
triggers 定义一组触发器,每个触发器对应一个 Scaler type: kafka, metadata: { topic: orders }
minReplicas / maxReplicas 副本数边界 minReplicas: 1, maxReplicas: 20
pollingInterval KEDA 轮询外部系统的间隔(秒) 30
cooldownPeriod 缩容冷却时间(秒) 300
fallback 当 Scaler 不可用时的降级策略 replicas: 3
关键设计:ScaledObject 不直接包含指标值计算逻辑,它只负责“声明”需要监听什么外部事件源,以及伸缩的边界条件。指标采集和转换完全由 Scaler 层完成。

2.4 Scaler 与 Trigger 的关系

Trigger 是 Scaler 的“实例化配置”。每个 Trigger 包含:

  • type:指定 Scaler 类型,如 prometheus、kafka、rabbitmq、postgresql 等。
  • metadata:连接参数和查询条件,如 PromQL 查询语句、Kafka 主题名、队列名称。
  • authenticationRef:可选,引用 TriggerAuthentication 或 ClusterTriggerAuthentication 资源,用于存储敏感信息。

KEDA 内置 50+ 种 Scaler,覆盖主流中间件和云服务。当 KEDA Operator 解析 ScaledObject 时,会根据 triggers[].type 动态加载对应的 Scaler 实现,并传入 metadata 完成初始化。

apiVersion: keda.sh/v1alpha1
kind: ScaledObject
metadata:
  name: kafka-scaledobject
spec:
  scaleTargetRef:
    name: order-processor
  triggers:
  - type: kafka
    metadata:
      bootstrapServers: kafka-cluster:9092
      topic: orders
      lagThreshold: "100"
      consumerGroup: order-group
    authenticationRef:
      name: kafka-auth

2.5 HPA 的生成与指标桥接

KEDA Operator 为每个 ScaledObject 自动生成一个 HPA 对象。生成的 HPA 具有以下特征:

  • 指标来源:指向 KEDA Metrics Adapter 暴露的自定义指标,格式为 pods/{metric-name}。
  • 目标值:由 Scaler 返回的指标值与 Trigger 中定义的阈值共同决定。
  • 动态更新:当 ScaledObject 的 triggers 或边界条件变更时,Operator 自动更新对应的 HPA。
ScaledObject → HPA 生成映射 ScaledObject scaleTargetRef triggers[].type triggers[].metadata minReplicas maxReplicas pollingInterval cooldownPeriod Operator 转换 HPA scaleTargetRef → 同 ScaledObject metrics[].type: Pods metrics[].pods.metric.name minReplicas maxReplicas behavior.scaleDown behavior.scaleUp 注意 HPA 的 metric 名称由 KEDA 自动生成,格式为 keda-{ScaledObject名}

2.6 工作原理解析:一次完整的伸缩循环

假设我们有一个 Kafka 消费者应用,希望根据消息堆积数自动伸缩:

  1. 轮询阶段:KEDA Operator 每隔 pollingInterval(默认 30s)调用 Kafka Scaler,查询指定 topic 的消费者滞后量(lag)。
  2. 指标暴露:Scaler 将 lag 值返回给 KEDA Metrics Adapter,Adapter 将其注册为自定义指标 kafka-lag。
  3. HPA 拉取:HPA 通过 /apis/custom.metrics.k8s.io 接口拉取 kafka-lag 的当前值。
  4. 副本计算:HPA 将当前 lag 值与 Trigger 中定义的 lagThreshold(如 100)比较,计算期望副本数。公式为 desiredReplicas = ceil(currentMetricValue / targetValue)。
  5. 执行伸缩:HPA 调用 Deployment 的 Scale 子资源,更新 replicas 字段。
  6. 冷却等待:缩容时,KEDA 会等待 cooldownPeriod(默认 300s),避免频繁抖动。
避坑提示:HPA 的 targetValue 在 KEDA 中通常固定为 1。这意味着“每个副本处理 1 个单位的指标负载”。例如,lagThreshold=100 表示每个副本最多处理 100 条堆积消息。如果当前堆积 500 条,HPA 会期望 5 个副本。

2.7 多 Trigger 与指标聚合

一个 ScaledObject 可以包含多个 Trigger,KEDA 会取所有 Trigger 返回的指标值中的 最大值 作为最终伸缩依据。这种设计确保系统对任何单一指标的异常都能快速响应。

场景 Trigger 1 Trigger 2 最终副本数
CPU 高,消息低 CPU 80% → 期望 8 副本 Kafka lag 50 → 期望 2 副本 8(取最大值)
CPU 低,消息高 CPU 30% → 期望 2 副本 Kafka lag 500 → 期望 5 副本 5(取最大值)
两者都低 CPU 10% → 期望 1 副本 Kafka lag 10 → 期望 1 副本 1(取最大值)
最佳实践:将资源指标(CPU/Memory)与业务指标(队列长度、请求速率)组合使用,既能保证基础资源充足,又能实现业务驱动的精准伸缩。