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 的“指标上游”。整个伸缩链路分为四个阶段:
- 用户定义 ScaledObject:在 YAML 中声明目标 Deployment、Trigger 类型(如 Kafka、Prometheus、RabbitMQ)及阈值。
- KEDA Operator 生成 HPA:Operator 监听 ScaledObject 资源,自动创建或更新对应的 HPA 对象。
- Scaler 采集指标:KEDA 内置的 Scaler 根据 Trigger 配置连接外部系统,将业务指标转换为标准 Metric 值。
- HPA 执行伸缩:HPA 定期从 KEDA Metrics Adapter 拉取指标,计算期望副本数并调整 Deployment 的 replicas。
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。
2.6 工作原理解析:一次完整的伸缩循环
假设我们有一个 Kafka 消费者应用,希望根据消息堆积数自动伸缩:
- 轮询阶段:KEDA Operator 每隔
pollingInterval(默认 30s)调用 Kafka Scaler,查询指定 topic 的消费者滞后量(lag)。 - 指标暴露:Scaler 将 lag 值返回给 KEDA Metrics Adapter,Adapter 将其注册为自定义指标
kafka-lag。 - HPA 拉取:HPA 通过
/apis/custom.metrics.k8s.io接口拉取kafka-lag的当前值。 - 副本计算:HPA 将当前 lag 值与 Trigger 中定义的
lagThreshold(如 100)比较,计算期望副本数。公式为desiredReplicas = ceil(currentMetricValue / targetValue)。 - 执行伸缩:HPA 调用 Deployment 的 Scale 子资源,更新 replicas 字段。
- 冷却等待:缩容时,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)与业务指标(队列长度、请求速率)组合使用,既能保证基础资源充足,又能实现业务驱动的精准伸缩。