2. KEDA 架构解析:整体架构、核心组件与交互流程

KEDA(Kubernetes Event-Driven Autoscaling)并非简单地替代 Horizontal Pod Autoscaler(HPA),而是作为事件驱动的触发器与 Kubernetes 原生弹性伸缩机制之间的桥梁。理解其分层架构和组件间交互,是生产级部署与排错的基础。

2.1 整体架构概览

KEDA 采用 控制面 + 数据面 分离的设计。控制面负责监听事件源、计算期望副本数;数据面负责将期望副本数注入 Kubernetes 的 HPA 控制器,最终由 HPA 调整 Deployment/StatefulSet 的副本数。

KEDA 整体架构图 外部事件源 Kafka / RabbitMQ / Prometheus KEDA 控制面 Operator Scaler Metrics Adapter Kubernetes 数据面 HPA Deployment Pod 副本 (0→N) 事件指标 指标值 外部指标 API 期望副本数 管理 Scaler
架构要点:KEDA 不直接管理 Pod 生命周期。它通过 Metrics Adapter 将外部事件指标转换为 Kubernetes 可识别的 external.metrics.k8s.io 或 custom.metrics.k8s.io 接口,HPA 轮询该接口后执行扩缩容决策。

2.2 核心组件详解

KEDA 由三个核心组件构成,各自承担明确的职责:

组件 角色 核心职责 运行方式
Operator 控制器 监听 ScaledObject / ScaledJob CRD,管理 Scaler 实例的生命周期 Deployment(通常 2 副本)
Scaler 指标采集器 连接外部事件源(Kafka、RabbitMQ、Prometheus 等),拉取当前指标值 Operator 内部 goroutine
Metrics Adapter API 服务器扩展 实现 external.metrics.k8s.io API,将 Scaler 获取的指标暴露给 HPA Deployment + APIService

2.2.1 Operator

Operator 是 KEDA 的“大脑”。它通过 Kubernetes 的 controller-runtime 框架监听 ScaledObject 和 ScaledJob 自定义资源。当用户创建 ScaledObject 时,Operator 会:

  • 验证 ScaledObject 的配置(触发器类型、认证引用、目标 Deployment 是否存在)。
  • 根据触发器类型实例化对应的 Scaler(如 Kafka Scaler、Prometheus Scaler)。
  • 创建或更新 HPA 资源,并将 HPA 的指标源指向 KEDA Metrics Adapter。
  • 持续协调状态,确保 HPA 的期望副本数与 Scaler 返回的指标一致。

2.2.2 Scaler

Scaler 是 KEDA 的“感官”。每个 Scaler 实现一个特定的 Scaler 接口,负责与外部系统通信。KEDA 内置 50+ 种 Scaler,覆盖主流中间件和云服务。

// Scaler 核心接口(简化)
type Scaler interface {
    // 获取当前指标值,返回 int64 和错误
    GetMetrics(ctx context.Context, metricName string, metricSelector labels.Selector) ([]external_metrics.ExternalMetricValue, error)
    // 返回 Scaler 关联的指标元数据
    GetMetricSpecForScaling(ctx context.Context) []MetricSpec
}
生产建议:自定义 Scaler 开发时,务必实现 GetMetrics 的超时控制和错误重试逻辑。若 Scaler 连续 3 次获取指标失败,KEDA 会将该 Scaler 标记为不健康,HPA 将保持当前副本数不变,避免抖动。

2.2.3 Metrics Adapter

Metrics Adapter 是 KEDA 的“翻译官”。它作为 Kubernetes API Server 的扩展,注册一个 APIService,提供 /apis/external.metrics.k8s.io/v1beta1 端点。HPA 通过该端点查询指标时,Metrics Adapter 会:

  1. 接收 HPA 的指标查询请求(包含 ScaledObject 名称和命名空间)。
  2. 根据请求找到对应的 Scaler 实例。
  3. 调用 Scaler 的 GetMetrics 方法获取实时指标值。
  4. 将指标值格式化为 Kubernetes 标准响应格式返回给 HPA。

2.3 组件间交互流程

一次完整的弹性伸缩事件,从事件源触发到 Pod 副本数变化,经历以下 6 个步骤:

组件交互时序图(一次完整伸缩周期) 用户/事件源 Operator Scaler Metrics Adapter HPA 创建 ScaledObject ① 提交 CR 实例化 Scaler ② 创建 Scaler 实例 连接事件源 ③ 拉取指标 创建 HPA ④ 设置指标源为 external.metrics.k8s.io 轮询指标 ⑤ 请求指标值 调用 GetMetrics ⑥ 获取实时指标 返回指标值
关键时序约束:步骤 ④ 中 Operator 创建的 HPA,其 spec.metrics 必须指向 external 类型,且 metric.name 与 ScaledObject 中定义的 metricName 一致。若名称不匹配,HPA 将无法找到指标,导致伸缩失效。

2.4 组件交互总结

KEDA 的组件交互遵循“声明式配置 → 事件驱动 → 标准 Kubernetes API”的闭环:

  • 声明式配置:用户通过 ScaledObject YAML 声明“当 Kafka 队列深度 > 10 时,将 my-app 扩展到 5 副本”。
  • 事件驱动:Scaler 持续监听 Kafka 的 lag 指标,不依赖 CPU 或内存。
  • 标准 API:Metrics Adapter 将 Kafka lag 转换为 external.metrics.k8s.io 标准格式,HPA 无需任何修改即可消费。

这种设计使得 KEDA 能够无缝融入现有 Kubernetes 集群,无需替换或修改 HPA 控制器,也无需在应用容器中嵌入任何代理或 Sidecar。