2. KEDA 核心架构:核心组件详解与交互流程
KEDA(Kubernetes Event-Driven Autoscaling)的架构设计遵循“事件驱动、职责分离”原则。它不替代 Kubernetes 内置的 Horizontal Pod Autoscaler (HPA),而是作为事件感知层,将外部指标注入 HPA,实现基于事件密度的弹性伸缩。理解其核心组件及交互流程,是进行资源容量规划的前提。
2.1 核心组件总览
KEDA 由四个核心组件构成,它们协同工作,将外部事件源(如 Kafka、RabbitMQ、Prometheus)的指标转换为 Kubernetes 可识别的 Pod 扩缩容信号。
| 组件名称 | 角色定位 | 核心职责 | 部署形态 |
|---|---|---|---|
| ScaledObject | 自定义资源 (CRD) | 声明式定义“何时扩缩容”及“扩缩容目标” | 用户 YAML 配置 |
| Scaler | 指标采集器 | 连接外部事件源,拉取或监听事件队列深度/指标值 | KEDA Operator 内部模块 |
| Trigger | 事件源描述 | 在 ScaledObject 中定义事件源类型、连接信息及阈值 | ScaledObject 的 spec.triggers 字段 |
| Metrics Adapter | 指标暴露器 | 将 Scaler 采集的指标转换为 Kubernetes 自定义指标 API 格式 | 独立 Pod (keda-metrics-apiserver) |
2.2 组件详解
2.2.1 ScaledObject — 事件驱动的“大脑”
ScaledObject 是 KEDA 的核心自定义资源,它定义了整个自动缩放策略的“三要素”:
- Scaling Target:指定要扩缩容的工作负载(Deployment、StatefulSet、Custom Resource)。
- Triggers:定义事件源类型及连接参数(如 Kafka 主题、Prometheus 查询语句)。
- Scaling Config:设置最小/最大副本数、冷却时间、回退策略等。
一个典型的 ScaledObject YAML 示例如下:
apiVersion: keda.sh/v1alpha1
kind: ScaledObject
metadata:
name: kafka-consumer-scaler
namespace: default
spec:
scaleTargetRef:
apiVersion: apps/v1
kind: Deployment
name: kafka-consumer
minReplicaCount: 1
maxReplicaCount: 20
pollingInterval: 15
cooldownPeriod: 60
triggers:
- type: kafka
metadata:
bootstrapServers: kafka-cluster:9092
consumerGroup: my-consumer-group
topic: orders
lagThreshold: "100"
2.2.2 Scaler — 事件源的“适配器”
Scaler 是 KEDA 的插件化模块,每个 Scaler 对应一种外部事件源。KEDA 内置了 50+ 种 Scaler(Kafka、RabbitMQ、Prometheus、AWS SQS、Azure Event Hub 等),也支持自定义 Scaler。Scaler 的核心接口只有两个方法:
- GetMetrics():返回当前事件源的指标值(如 Kafka 分区滞后量)。
- IsActive():判断事件源是否处于活跃状态(是否有待处理事件)。
2.2.3 Trigger — 事件源的“描述文件”
Trigger 不是独立组件,而是 ScaledObject 中的一个字段集合。它告诉 KEDA 使用哪个 Scaler 以及如何连接事件源。每个 Trigger 包含:
- type:指定 Scaler 类型(如
kafka、prometheus)。 - metadata:连接参数(如地址、主题、查询语句)。
- authenticationRef:可选,引用 Kubernetes Secret 存储敏感信息。
2.2.4 Metrics Adapter — 指标“翻译官”
Metrics Adapter 是 KEDA 与 Kubernetes HPA 之间的桥梁。它实现了 Kubernetes 的 custom.metrics.k8s.io API 接口,将 Scaler 采集的指标转换为 HPA 可以消费的格式。当 HPA 轮询指标时,Metrics Adapter 会调用对应 ScaledObject 的 Scaler 获取最新指标值并返回。
2.3 组件交互流程
下图展示了从事件产生到 Pod 扩缩容的完整交互链路:
2.4 完整交互步骤
结合上图,一次完整的扩缩容事件循环包含以下 6 个步骤:
- 配置加载:用户创建 ScaledObject CRD,KEDA Operator 监听并解析配置,注册对应的 Scaler 和 Trigger。
- 指标采集:Scaler 根据 Trigger 定义,按
pollingInterval(默认 30 秒)周期性地从外部事件源拉取指标(如 Kafka 分区滞后量)。 - 指标暴露:Metrics Adapter 将 Scaler 返回的指标值注册到 Kubernetes 的
custom.metrics.k8s.ioAPI 中。 - HPA 轮询:Kubernetes HPA 按
--horizontal-pod-autoscaler-sync-period(默认 15 秒)轮询 Metrics Adapter,获取当前指标值。 - 扩缩容决策:HPA 根据当前指标值与目标值(由 ScaledObject 的
targetValue或targetAverageValue定义)计算期望副本数,并更新工作负载的replicas字段。 - Pod 调整:Kubernetes 控制器根据更新后的副本数,创建或删除 Pod。
minReplicaCount,引发服务过载。因此,升级前应确保 Metrics Adapter 的 Pod 分布策略(如 PDB、多副本)已正确配置。
2.5 组件间依赖关系
下表总结了各组件之间的依赖关系及故障影响:
| 依赖关系 | 依赖方 | 被依赖方 | 故障影响 |
|---|---|---|---|
| Scaler → 事件源 | Scaler | Kafka / RabbitMQ 等 | 指标采集失败,HPA 使用上次有效值或默认值 |
| Metrics Adapter → Scaler | Metrics Adapter | Scaler 模块 | 无法暴露指标,HPA 返回“未知指标”错误 |
| HPA → Metrics Adapter | HPA | keda-metrics-apiserver | HPA 无法获取外部指标,停止扩缩容 |
| ScaledObject → Operator | ScaledObject CRD | KEDA Operator | 新配置无法生效,已有配置继续运行 |
2.6 多 Scaler 协同与 Fallback 策略
KEDA 支持在单个 ScaledObject 中配置多个 Trigger,实现多事件源协同判断。当任一 Trigger 的指标超过阈值时,都会触发扩容。此外,KEDA 提供了 Fallback 策略,当 Scaler 无法连接事件源时,可以回退到预设的副本数,避免因事件源故障导致服务完全无副本。
spec:
triggers:
- type: kafka
metadata:
bootstrapServers: kafka-cluster:9092
topic: orders
lagThreshold: "100"
- type: prometheus
metadata:
serverAddress: http://prometheus:9090
query: sum(rate(orders_total[5m]))
threshold: "1000"
fallback:
failureThreshold: 3
replicas: 5
2.7 架构设计要点总结
- 松耦合:Scaler、Metrics Adapter、HPA 三者独立部署,任一组件故障不影响其他组件的基本运行。
- 插件化:Scaler 采用接口化设计,新增事件源只需实现两个方法,无需修改核心代码。
- 标准化:通过
custom.metrics.k8s.ioAPI 与 Kubernetes 生态无缝集成,无需修改 HPA 或 kube-controller-manager。 - 声明式:所有扩缩容策略通过 ScaledObject CRD 声明,支持 GitOps 工作流。