3. KEDA 与事件驱动扩缩容:KEDA 架构、Scaler 类型、基于 Prometheus/CPU/自定义指标的自动扩缩
在 Serverless 与云原生环境中,传统的基于 CPU/内存阈值的 Horizontal Pod Autoscaler(HPA)往往无法及时响应业务流量的突发变化。Kubernetes Event-driven Autoscaling(KEDA)应运而生,它通过事件驱动的机制,将扩缩容的决策从资源指标扩展到任意事件源,实现更精准、更实时的弹性伸缩。
3.1 KEDA 核心架构
KEDA 作为 Kubernetes 的扩展组件,充当 HPA 与事件源之间的桥梁。其核心组件包括 Operator、Metrics Adapter 和 ScaledObject 自定义资源。
3.2 Scaler 类型与选择策略
KEDA 提供了丰富的 Scaler(扩缩器)实现,覆盖了主流的事件源和基础设施。选择合适的 Scaler 是成本优化的第一步。
| Scaler 类型 | 适用场景 | 典型指标 | 延迟敏感度 |
|---|---|---|---|
| Prometheus | 自定义业务指标、微服务监控 | 请求延迟 P99、队列深度 | 中 |
| CPU / Memory | 传统工作负载、无状态服务 | CPU 使用率、内存使用量 | 低 |
| Kafka / RabbitMQ | 消息驱动架构、流处理 | 未消费消息数、消费者滞后 | 高 |
| AWS SQS / Azure Queue | 云原生队列处理、异步任务 | 队列长度、不可见消息数 | 高 |
| Cron | 定时任务、批量处理 | 时间表达式 | 无 |
| 自定义 HTTP | 遗留系统集成、特殊协议 | 自定义 JSON 响应 | 可变 |
3.3 基于 Prometheus 指标的自动扩缩
Prometheus Scaler 是 KEDA 中最强大的 Scaler 之一,它允许你使用任意 PromQL 查询结果作为扩缩容依据。
以下是一个基于 HTTP 请求延迟 P99 进行扩缩容的 ScaledObject 示例:
apiVersion: keda.sh/v1alpha1
kind: ScaledObject
metadata:
name: http-service-scaler
namespace: default
spec:
scaleTargetRef:
name: http-service # 目标 Deployment 名称
minReplicaCount: 2 # 最小副本数,保障基础容量
maxReplicaCount: 20 # 最大副本数,控制成本上限
triggers:
- type: prometheus
metadata:
serverAddress: http://prometheus.monitoring:9090
metricName: http_request_p99_latency
query: |
histogram_quantile(0.99,
sum(rate(http_request_duration_seconds_bucket[2m])) by (le)
)
threshold: "0.5" # P99 延迟超过 500ms 时触发扩容
activationThreshold: "0.1" # P99 低于 100ms 时缩容
advanced:
horizontalPodAutoscalerConfig:
behavior:
scaleDown:
stabilizationWindowSeconds: 120 # 缩容稳定窗口,防止抖动
policies:
- type: Percent
value: 50
periodSeconds: 60
step 参数默认与 KEDA 的轮询间隔一致(通常 30s)。如果查询涉及大范围时间窗口(如 10m),会导致指标更新滞后,造成过度扩容或缩容不及时。建议将查询的时间窗口控制在 2-5 分钟,并配合 stabilizationWindowSeconds 使用。
3.4 基于 CPU/Memory 指标的自动扩缩
虽然 KEDA 主打事件驱动,但它也内置了对传统 CPU/Memory 指标的支持。这在混合负载场景中非常有用——例如,白天由事件驱动扩缩,夜间由 CPU 指标兜底。
CPU/Memory Scaler 的配置方式与原生 HPA 类似,但通过 KEDA 可以统一管理:
apiVersion: keda.sh/v1alpha1
kind: ScaledObject
metadata:
name: cpu-memory-scaler
namespace: default
spec:
scaleTargetRef:
name: backend-service
minReplicaCount: 1
maxReplicaCount: 10
triggers:
- type: cpu
metadata:
type: Utilization # 使用率模式
value: "70" # 目标 CPU 使用率 70%
- type: memory
metadata:
type: AverageValue # 平均值模式
value: "512Mi" # 目标内存使用量 512MiB
advanced:
horizontalPodAutoscalerConfig:
behavior:
scaleDown:
stabilizationWindowSeconds: 300 # 缩容稳定窗口 5 分钟
| 参数 | 说明 | 推荐值 |
|---|---|---|
type |
指标类型:Utilization(使用率)或 AverageValue(平均值) | CPU 用 Utilization,Memory 用 AverageValue |
value |
目标阈值 | CPU 70-80%,Memory 根据应用实际占用 |
stabilizationWindowSeconds |
缩容稳定窗口,防止指标抖动导致频繁扩缩 | 120-300 秒 |
3.5 自定义指标扩缩容实战
当内置 Scaler 无法满足需求时,KEDA 支持通过 自定义 HTTP Scaler 或 External Scaler 接入任意指标源。
以下是一个自定义 HTTP Scaler 的示例,它从一个内部 API 获取队列深度:
apiVersion: keda.sh/v1alpha1
kind: ScaledObject
metadata:
name: custom-http-scaler
namespace: default
spec:
scaleTargetRef:
name: worker-service
minReplicaCount: 1
maxReplicaCount: 15
triggers:
- type: metrics-api
metadata:
targetValue: "100" # 目标队列深度 100
activationTargetValue: "10" # 低于 10 时缩容
url: "http://queue-api.internal/v1/queue-depth"
valueLocation: "depth" # JSON 响应中的字段路径
method: "GET"
- 确保指标 API 的响应时间 < 100ms,避免 KEDA 轮询超时
- 设置合理的
activationTargetValue,避免指标在零附近波动时频繁扩缩 - 配合
cooldownPeriod(默认 300s)防止缩容过快 - 对于高吞吐场景,将轮询间隔
pollingInterval调整为 10-15 秒
3.6 多触发器组合与成本优化策略
KEDA 允许在同一个 ScaledObject 中配置多个触发器,实现 OR(任一触发)或 AND(全部触发)逻辑。这是成本优化的关键手段。
成本优化组合示例:
- 主 + 备策略: 主触发器使用业务指标(如队列深度),备触发器使用 CPU 指标。当业务指标不可用时,CPU 指标兜底,避免服务完全无响应。
- 权重差异化: 为关键业务触发器设置更高的权重,确保其在多触发器竞争中优先响应。
- 时间窗口错峰: 白天使用事件驱动(快速响应),夜间切换为 CPU/Memory 指标(成本优先)。
maxReplicaCount 上限,避免事件源异常导致无限扩容。对于非关键业务,建议将 minReplicaCount 设为 0(需要配合 scaleToZero 特性),实现真正的按需付费。