跳转到内容

KEDA 事件驱动自动缩放面试题库

30 道题
分类
Kubernetes
子分类
scheduler
题目数
30 道
已阅读 0 / 30 题
1 KEDA 是什么?它的核心架构包含哪些组件?

答案:

KEDA(Kubernetes Event-driven Autoscaler)是 CNCF 孵化项目,为 Kubernetes 提供基于外部事件驱动的工作负载自动缩放能力。与标准 HPA 仅支持 CPU/内存指标不同,KEDA 可从消息队列、数据库、监控系统等数十种外部数据源获取实时事件指标驱动缩放。

[核心组件]

组件职责说明
Operator控制循环核心管理 ScaledObject/ScaledJob/TriggerAuthentication CRD 生命周期,翻译为缩放行为
Metrics Server指标适配器通过 Kubernetes Metrics API 暴露外部事件指标,供 HPA 查询
Scalers事件源适配器对接外部系统(Kafka/RabbitMQ/Prometheus 等)拉取指标数据
CRDs声明式配置ScaledObject(长任务)、ScaledJob(批处理)、TriggerAuthentication(认证)

[架构关系]

graph LR
    A[外部事件源<br/>Kafka/RabbitMQ/Prometheus] --> B[Scalers<br/>指标采集器]
    B --> C[KEDA Metrics Server<br/>指标适配器]
    C --> D[HPA<br/>水平自动缩放器]
    D --> E[KEDA Operator<br/>控制器]
    E --> F[Deployment/StatefulSet<br/>工作负载]
    F -.->|scale-to-zero| E

[事件驱动缩放流程]

graph LR
    A["1. 外部事件到达<br/>队列消息增加/流延迟上升/请求速率变化"] --> B["2. Scaler 从事件源采集指标值"]
    B --> C["3. KEDA Metrics Server 暴露为 External Metric"]
    C --> D["4. HPA 周期查询指标值,计算期望副本数"]
    D --> E["5. HPA 调整 Deployment/StatefulSet 副本数"]
    E --> F["6. 指标归零时,KEDA 可将工作负载缩至 0"]
    F --> G["7. 事件再次到达,KEDA 触发从 0→1 的扩容"]
2 KEDA 与标准 HPA 的关系是什么?KEDA 是否取代了 HPA?

答案:

KEDA 不取代 HPA,而是与 HPA 协同工作。KEDA 将外部事件指标转换为 HPA 可消费的标准 External Metric,然后由 HPA 执行实际的副本数调整。

[协作机制]

graph LR
    A["用户创建 ScaledObject"] --> B["KEDA Operator 自动创建 HPA 资源"]
    B -.-> C["HPA 的 metric spec 指向 KEDA Metrics Server"]
    B --> D["HPA 通过 external.metrics.k8s.io API 查询指标"]
    D -.-> E["KEDA Metrics Server 根据 Scaler 返回实时值"]
    D --> F["HPA 计算期望副本数 → 调整 targetRef 的 replicas"]
维度标准 HPAKEDA
指标来源CPU/内存/Pod 自定义指标外部事件源(80+ Scalers)
最小副本数强制 ≥ 1支持缩到 0
缩放依据资源利用率事件量/队列深度/流延迟
CRDHPA 资源ScaledObject/ScaledJob
触发方式周期采集事件驱动(Pull/Push)

[KEDA 增值能力]

  • 标准 HPA 无法达到 0 副本,KEDA 接管 0→1 的扩容逻辑
  • 标准 HPA 仅支持资源指标,KEDA 新增 80+ 外部事件源
  • ScaledObject 自动创建并管理 HPA,保持两者同步
3 KEDA 如何实现 Scale-to-Zero?从 0 到 1 的扩容机制是什么?

答案:

标准 HPA 强制 minReplicas >= 1,KEDA 通过 Operator 层接管 0 副本状态的管理来实现缩到 0。当事件源无活动时,KEDA 将工作负载缩至 0;事件到达后触发扩容。

[Scale-to-Zero 实现机制]

graph LR
    A["事件消逝 → 指标归零"] --> B["HPA 将副本缩到 minReplicaCount<br/>通常为 1"]
    B --> C["KEDA Operator 检测到指标持续为零"]
    C --> D["KEDA 将 Deployment replicas 设置为 0<br/>绕过 HPA 限制"]
    D --> E["删除所有 Pod"]
    D --> F["内部标记该 ScaledObject 处于停用状态"]
    G["事件到达 → Scaler 检测到指标 > activationThreshold"] --> H["KEDA Operator 重新激活 ScaledObject"]
    H --> I["恢复 Deployment replicas 到 1"]
    H --> J["HPA 恢复接管后续缩放"]

[关键参数]

参数作用说明
minReplicaCount: 0允许缩到 0ScaledObject 中设置
activationThreshold激活阈值指标超过此值才从 0→1 扩容
cooldownPeriod冷却期指标归零后等待时长再缩到 0
idleReplicaCount空闲副本数闲置时保留的副本数(0 或 1)

[使用限制]

  • 仅 ScaledObject 支持 scale-to-zero,ScaledJob 不涉及
  • 需要 minReplicaCount: 0 显式配置
  • 从 0→1 扩容有额外延迟(需重新创建 Pod 并加载配置)
  • 某些场景需配合 activationThreshold 防止抖动
4 KEDA 有哪些 CRD 资源?各自的作用是什么?

答案:

KEDA 定义三个核心 CRD:ScaledObject、ScaledJob、TriggerAuthentication(含集群级 ClusterTriggerAuthentication)。

[CRD 概览]

CRD作用域目标说明
ScaledObject命名空间Deployment/StatefulSet/Custom Resource长任务工作负载事件驱动缩放
ScaledJob命名空间Job批处理任务的事件驱动创建
TriggerAuthentication命名空间Scaler 认证命名空间级认证配置
ClusterTriggerAuthentication集群Scaler 认证集群级认证配置,跨命名空间复用

[ScaledObject]

apiVersion: keda.sh/v1alpha1
kind: ScaledObject
metadata:
  name: kafka-consumer
spec:
  scaleTargetRef:
    name: my-deployment           # 目标工作负载
    kind: Deployment               # 支持 Deployment/StatefulSet/Custom Resource
    envSourceContainerName: app   # 环境变量来源容器
  pollingInterval: 30              # 轮询间隔(秒,默认 30)
  cooldownPeriod: 300              # 冷却期(秒,默认 300)
  minReplicaCount: 0               # 最小副本数(默认 0)
  maxReplicaCount: 30              # 最大副本数(默认 100)
  idleReplicaCount: 0              # 空闲副本数(闲置时保留)
  triggers:
  - type: kafka
    metadata:
      topic: my-topic
      bootstrapServers: kafka:9092
      consumerGroup: my-group
      lagThreshold: "10"
  advanced:                        # 高级配置
    horizontalPodAutoscalerConfig:
      behavior:
        scaleDown:
          stabilizationWindowSeconds: 60

[ScaledJob]

apiVersion: keda.sh/v1alpha1
kind: ScaledJob
metadata:
  name: sqs-consumer
spec:
  jobTargetRef:                     # Job 模板定义
    template:
      spec:
        containers:
        - name: worker
          image: my-worker:latest
          command: ["./process"]
        restartPolicy: Never
    backoffLimit: 4
  pollingInterval: 10
  maxReplicaCount: 30
  successfulJobsHistoryLimit: 3
  failedJobsHistoryLimit: 2
  scalingStrategy:
    strategy: "custom"             # default / custom / accurate / eager
    customScalingQueueLengthDeduction: 1
    customScalingRunningJobPercentage: "0.5"
  triggers:
  - type: aws-sqs-queue
    metadata:
      queueURL: https://sqs.us-east-1.amazonaws.com/...
      queueLength: "5"

[TriggerAuthentication]

apiVersion: keda.sh/v1alpha1
kind: TriggerAuthentication
metadata:
  name: kafka-auth
spec:
  secretTargetRef:
  - parameter: sasl                    # Scaler 参数名
    name: kafka-secrets                # Secret 名称
    key: sasl                          # Secret 中的键
  - parameter: tls
    name: kafka-secrets
    key: tls
apiVersion: keda.sh/v1alpha1
kind: ClusterTriggerAuthentication
metadata:
  name: global-kafka-auth
spec:
  secretTargetRef:
  - parameter: sasl
    name: keda/kafka-secrets           # cluster-scoped 需包含命名空间
    key: sasl
5 KEDA 的 Metrics Server 如何工作?HPA 如何获取外部指标?

答案:

KEDA Metrics Server 实现 Kubernetes External Metrics API,将 Scaler 采集的事件指标暴露为标准 External Metric,HPA 通过 external.metrics.k8s.io API 周期查询并驱动缩放决策。

[指标暴露流程]

graph LR
    A["ScaledObject 创建"] --> B["KEDA Operator 根据 triggers 配置注册 External Metric"]
    B -.-> C["metric name = keda-{namespace}-{scaledobject-name}-{trigger-index}"]
    B --> D["KEDA Metrics Server 实现 APIService"]
    D -.-> E["v1beta1.external.metrics.k8s.io"]
    D --> F["HPA 自动发现并查询 External Metric"]
    F -.-> G["spec: metrics: - type: External<br/>external: metric: name: keda-...<br/>target: averageValue: '10'"]
    F --> H["Metrics Server 调用对应 Scaler 的 GetMetrics 方法"]
    H -.-> I["返回当前队列深度/流延迟/请求数"]
    H --> J["HPA 计算 desired = ceil(current_value / target_value)"]
    J -.-> K["调整 Deployment replicas"]

[指标注册规则]

# ScaledObject 生成的指标命名
# default 命名空间下名为 kafka-consumer 的 ScaledObject
# 第一个 trigger(index=0)
# → 外部指标名: keda-default-kafka-consumer-0

# 多个 trigger 时,每个 trigger 生成独立指标
# scaledObject 有 3 个 triggers → 3 个 external metrics
# advanced.scalingModifiers.formula 合并多指标

[HPA 自动创建]

# KEDA Operator 自动创建(或更新)的 HPA
apiVersion: autoscaling/v2
kind: HorizontalPodAutoscaler
metadata:
  name: keda-hpa-kafka-consumer
  labels:
    scaledobject.keda.sh/name: kafka-consumer
spec:
  scaleTargetRef:
    apiVersion: apps/v1
    kind: Deployment
    name: my-deployment
  minReplicas: 0         # KEDA 允许 0
  maxReplicas: 30
  metrics:
  - type: External
    external:
      metric:
        name: keda-default-kafka-consumer-0
      target:
        type: AverageValue
        averageValue: "10"

[指标缓存]

  • Metrics Server 缓存 Scaler 返回的指标值,避免每次 HPA 查询都调用 Scaler
  • 缓存按 pollingInterval 刷新(默认 30 秒)
  • 可对特定 trigger 设置 useCachedMetrics: false 关闭缓存(cpu/memory/cron 不支持)
6 ScaledObject 的 pollingInterval、cooldownPeriod 和 idleReplicaCount 如何配合工作?

答案:

三个参数协同控制 KEDA 的缩放节奏:pollingInterval 控制指标采集频率,cooldownPeriod 控制缩容等待时长,idleReplicaCount 控制空闲时保留的副本水平。

[参数关系]

graph LR
    subgraph 扩容阶段
        A[事件到达] --> B[激活阈值检查]
        B -->|超出 activationThreshold| C[从 idle 扩容到 1]
        C --> D[HPA 按指标持续扩容]
    end
    subgraph 缩容阶段
        E[指标下降] --> F[pollingInterval 检测到归零]
        F --> G[cooldownPeriod 等待期<br/>防止抖动]
        G --> H[缩容到 idleReplicaCount]
    end
    subgraph 完全空闲
        I[idleReplicaCount=0] --> J[完全缩零<br/>无 Pod 运行]
        K[idleReplicaCount=1] --> L[保留 1 个 Pod<br/>就绪但未处理]
    end
    D --> E
    H --> I
    H --> K
参数默认值作用建议
pollingInterval30s每隔 N 秒采集一次指标事件频繁的设小(5-10s),低频的设大(60-300s)
cooldownPeriod300s指标归零后等待 N 秒再缩容避免指标抖动导致频繁扩缩,可设 60-600s
idleReplicaCount0空闲时保留的副本数对启动耗时长的应用设 1,减少冷启动延迟
minReplicaCount0最低副本数下限设 1 则禁止缩到 0
maxReplicaCount100最高副本数上限按预期峰值流量设置

[典型场景配置]

# 场景 1:毫秒级延迟敏感,但不希望空跑
apiVersion: keda.sh/v1alpha1
kind: ScaledObject
metadata:
  name: latency-sensitive
spec:
  scaleTargetRef:
    name: my-app
  pollingInterval: 5        # 5s 采集一次,快速响应
  cooldownPeriod: 60        # 60s 后就缩
  idleReplicaCount: 1       # 保留 1 个热备
# 场景 2:批处理任务,完全不希望空跑
apiVersion: keda.sh/v1alpha1
kind: ScaledObject
metadata:
  name: batch-worker
spec:
  scaleTargetRef:
    name: worker
  minReplicaCount: 0
  maxReplicaCount: 50
  pollingInterval: 30
  cooldownPeriod: 300
  idleReplicaCount: 0       # 完全缩零

[注意事项]

  • cooldownPeriod 从指标归零时开始计时,不是从上一次缩放完成
  • idleReplicaCount 必须 ≤ minReplicaCount,通常相等或更小
  • pollingInterval 太小会增加 Metrics Server 和 Scaler 负载
  • 频繁扩缩时增大 cooldownPeriod 或使用 HPA behaviorstabilizationWindow
7 ScaledObject 的 advanced.scalingModifiers 有什么用?如何组合多指标?

答案:

scalingModifiers 允许通过数学公式组合多个 trigger 的指标值,实现复合缩放策略。使用 expr 包定义公式,支持四则运算、条件判断和聚合函数。

[配置结构]

apiVersion: keda.sh/v1alpha1
kind: ScaledObject
metadata:
  name: multi-trigger
spec:
  scaleTargetRef:
    name: my-app
  triggers:
  - type: prometheus      # 指标: trig_one
    name: trig_one
    metadata:
      query: sum(rate(http_requests_total[1m]))
      threshold: "100"
  - type: rabbitmq        # 指标: trig_two
    name: trig_two
    metadata:
      queueName: my-queue
      queueLength: "10"
  advanced:
    scalingModifiers:
      formula: "(trig_one + trig_two) / 2"   # 复合公式
      target: "50"                            # 目标值
      activationTarget: "10"                  # 激活阈值
      metricType: "AverageValue"              # AverageValue / Value

[公式示例]

公式行为
trig_one + trig_two两指标求和
(trig_one + trig_two) / 2两指标平均
trig_one > trig_two ? trig_one : trig_two取较大值
count([trig_one, trig_two, trig_three], {# > 1}) > 1至少两个指标 > 1 时返回 5
trig_one < 2 ? trig_one + trig_two >= 2 ? 5 : 10 : 0嵌套条件
ceil(trig_one / 10) * 10按 10 的倍数向上取整

[多指标合并策略]

graph LR
    A["触发模式:多 ScaledObject,各有独立 HPA"]
    A -.-> B["问题:同一工作负载被多个 HPA 管理<br/>行为不可预测"]
    C["聚合模式(推荐):单 ScaledObject + scalingModifiers"]
    C -.-> D["单个 HPA,公式决定最终指标值"]
    E["独立模式:单 ScaledObject 多 trigger,无 modifiers"]
    E -.-> F["HPA 取所有指标中的最大值"]

[使用限制]

  • 公式必须返回单一数值(非布尔值),结果自动转为 float
  • trigger 索引名使用 name 字段定义的名称,非 type
  • 设置 target 后的行为:desired = ceil(formula_result / target)
  • activationThreshold 配合时,激活值与缩放值可能不同
8 ScaledObject 如何与已有的 HPA 共存?如何接管现有 HPA?

答案:

KEDA 支持接管用户已有 HPA 的管理权,通过 transfer-hpa-ownership 注解实现。接管后 KEDA 保持 HPA 同步,用户不再直接管理该 HPA。

[默认行为]

graph LR
    A["无已有 HPA"] --> B["KEDA 自动创建 HPA"]
    C["有已有 HPA"] --> D["KEDA 检测到冲突,拒绝创建 ScaledObject"]
    D -.-> E["报错:ScaledObject 与已有 HPA 管理相同 targetRef"]

[接管已有 HPA]

apiVersion: keda.sh/v1alpha1
kind: ScaledObject
metadata:
  name: take-over
  annotations:
    scaledobject.keda.sh/transfer-hpa-ownership: "true"   # 启用接管
spec:
  scaleTargetRef:
    name: my-deployment
  advanced:
    horizontalPodAutoscalerConfig:
      name: my-existing-hpa                                 # 指定已有 HPA
  triggers:
  - type: prometheus
    metadata:
      serverAddress: http://prometheus:9090
      query: sum(rate(http_requests_total[1m]))
      threshold: "100"

[接管流程]

graph LR
    A["1. 用户在 ScaledObject 添加 transfer-hpa-ownership 注解"] --> B["2. KEDA 验证 HPA 的 scaleTargetRef 与 ScaledObject 一致"]
    B --> C["3. 验证通过 → KEDA 接管 HPA 管理权"]
    C --> D["添加 label: scaledobject.keda.sh/name"]
    C --> E["更新 HPA metrics 指向 KEDA Metrics Server"]
    C --> F["保持 HPA behavior / 其他已有配置"]
    C --> G["4. 用户不可再直接编辑该 HPA"]
    G --> H["5. 删除 ScaledObject 时 → HPA 可选择保留或删除"]

[HPA behavior 保留]

  • 接管时,KEDA 保留已有 HPA 的 behavior 配置(稳定窗口、策略等)
  • 如需覆盖,在 ScaledObject 的 advanced.horizontalPodAutoscalerConfig.behavior 中声明
  • 未声明的 behavior 字段,KEDA 不会主动修改

[缩放到 0 的特殊行为]

  • 接管后的 HPA 仍不允许 minReplicas: 0(K8s 限制)
  • KEDA 通过额外逻辑在 HPA 之外将副本设置为 0
  • HPA 看到的 minReplicas 始终 ≥ 1,实际副本由 KEDA Operator 管理
9 ScaledObject 支持哪些 target 工作负载类型?Custom Resource 如何接入?

答案:

ScaledObject 支持 Deployment、StatefulSet 和实现了 /scale 子资源的 Custom Resource。对于自定义资源,需满足 Kubernetes 缩放子资源规范。

[支持的目标类型]

类型说明示例
Deployment无状态应用Web 服务、API 网关
StatefulSet有状态应用数据库、消息队列消费者
Custom Resource自定义控制器需要 CRD 实现 /scale 子资源

[Custom Resource 接入]

# Custom Resource 必须实现 /scale 子资源
# 在 CRD 定义中:
apiVersion: apiextensions.k8s.io/v1
kind: CustomResourceDefinition
spec:
  versions:
  - name: v1
    subresources:
      scale:                          # 启用缩放子资源
        specReplicasPath: .spec.replicas
        statusReplicasPath: .status.replicas
        labelSelectorPath: .status.selector
# ScaledObject 引用自定义资源
apiVersion: keda.sh/v1alpha1
kind: ScaledObject
metadata:
  name: custom-resource-scaler
spec:
  scaleTargetRef:
    name: my-cr-instance
    kind: MyCustomResource            # CRD 的 kind
    apiVersion: example.io/v1         # CRD 的 API 版本
    envSourceContainerName: app

[缩放机制]

  • KEDA Operator 通过 /scale 子资源读取和写入 replicas
  • 前提:CRD controller 需要实际处理 spec.replicasstatus.replicas 的调和逻辑
  • 典型场景:OpenSession、Flink、Spark Operator 等自定义工作负载

[限制说明]

  • 不支持 DaemonSet(节点级守护进程,不应缩放)
  • 不支持裸 Pod(无 ReplicaSet 管理)
  • Custom Resource 若无 /scale 子资源,无法被 ScaledObject 管理
10 ScaledObject 的 advanced.horizontalPodAutoscalerConfig.behavior 如何配置?稳定窗口和策略的作用是什么?

答案:

behavior 字段覆盖 HPA 的缩放行为策略,控制扩容和缩容的速度、窗口和限制。这是 KEDA 用于精细调控缩放行为的关键配置。

[behavior 结构]

apiVersion: keda.sh/v1alpha1
kind: ScaledObject
metadata:
  name: controlled-scaler
spec:
  scaleTargetRef:
    name: my-app
  advanced:
    horizontalPodAutoscalerConfig:
      behavior:
        scaleDown:                              # 缩容策略
          stabilizationWindowSeconds: 300        # 稳定窗口(5分钟)
          policies:
          - type: Percent
            value: 10                           # 每分钟最多缩 10%
            periodSeconds: 60
          selectPolicy: Min                     # Min / Max / Disabled
        scaleUp:                                # 扩容策略
          stabilizationWindowSeconds: 0          # 无稳定窗口,立即扩容
          policies:
          - type: Percent
            value: 100                          # 每分钟最多翻倍扩容
            periodSeconds: 15
          - type: Pods
            value: 4                            # 每分钟最多加 4 Pod
            periodSeconds: 15
          selectPolicy: Max                     # 取两个策略中较大的限制

[核心参数]

参数作用建议值
stabilizationWindowSeconds窗口期内取最大/最小值,防止抖动缩容 300-600,扩容 0-60
type: Percent按百分比限制缩放速率扩容 100%,缩容 10%
type: Pods按绝对值限制缩放速率扩容 4,缩容 1
selectPolicy: Max取宽松的限制扩容时常用
selectPolicy: Min取严格的限制缩容时常用
selectPolicy: Disabled禁止该方向缩放禁止缩容

[典型场景]

# 场景:扩容快、缩容慢、禁止缩到零
spec:
  advanced:
    horizontalPodAutoscalerConfig:
      behavior:
        scaleUp:
          stabilizationWindowSeconds: 0        # 无延迟,立即响应流量
          policies:
          - type: Percent
            value: 100
            periodSeconds: 15
          selectPolicy: Max
        scaleDown:
          stabilizationWindowSeconds: 600       # 10分钟稳定期
          policies:
          - type: Pods
            value: 1
            periodSeconds: 60
          selectPolicy: Min
# 场景:紧急扩容(CPU 突增)
spec:
  advanced:
    horizontalPodAutoscalerConfig:
      behavior:
        scaleDown:
          selectPolicy: Disabled               # 完全禁止缩容

[暂停缩放注解]

# 暂停缩容
metadata:
  annotations:
    autoscaling.keda.sh/paused-scale-in: "true"

# 暂停扩容
metadata:
  annotations:
    autoscaling.keda.sh/paused-scale-out: "true"

# 完全暂停
metadata:
  annotations:
    autoscaling.keda.sh/paused: "true"
11 ScaledJob 与 ScaledObject 的核心区别是什么?ScaledJob 如何处理批处理任务?

答案:

ScaledObject 用于缩放长运行的工作负载(Deployment/StatefulSet),ScaledJob 用于事件驱动的批处理任务——每个事件触发一个 Kubernetes Job 创建,Job 处理完就终止。

[核心区别]

维度ScaledObjectScaledJob
目标资源Deployment/StatefulSet/Custom ResourceJob
行为模式调整副本数创建和清理 Job
处理模型一个实例处理多个事件一个 Job 处理一个事件
工作负载持久运行(长任务)运行到完成(批处理)
清理机制正常缩容/删除 PodfailedJobsHistoryLimit/successfulJobsHistoryLimit
空闲状态缩到 0 副本(Pod 不运行)0 个 Job 创建

[ScaledJob 工作流程]

graph LR
    A["Kafka 消息到达(事件触发)"] --> B["KEDA Scaler 检测到消息数 > 阈值"]
    B --> C["KEDA Operator 根据 scalingStrategy 计算需要创建多少 Job"]
    C --> D["创建 Kubernetes Job(每消息一个任务)"]
    D -.-> E["每个 Job 处理一条消息后终止"]
    D --> F["Job 完成 → 清理<br/>保留在 successfulJobsHistoryLimit 内"]
    D --> G["Job 失败 → 重试(backoffLimit)<br/>保留在 failedJobsHistoryLimit 内"]

[Scaling Strategy]

策略行为说明
default每个事件创建一个 Job简单直接,适用于低频事件
custom考虑运行中 Job 数,用公式调整避免创建过多 Job,适用于高频事件
accuratemaxReplicaCount = 事件总数最大并发度,无限制
eager尽可能多地创建快速消费队列
spec:
  scalingStrategy:
    strategy: "custom"
    customScalingQueueLengthDeduction: 1      # 每个 Job 处理 1 个消息
    customScalingRunningJobPercentage: "0.5"   # 运行中 Job 占队列比例
12 ScaledJob 的 scalingStrategy 有哪些模式?各字段的计算逻辑是什么?

答案:

ScaledJob 的 scalingStrategy 控制如何将队列中的事件映射为需要创建的 Job 数量,不同策略适用于不同的消费模式。

[默认策略]

scalingStrategy:
  strategy: "default"

每个事件对应一个 Job。desiredJobs = pendingEvents。适用于低频、处理快的场景。

[自定义策略]

scalingStrategy:
  strategy: "custom"
  customScalingQueueLengthDeduction: 1        # 每个 Job 可消费的消息数
  customScalingRunningJobPercentage: "0.5"    # 运行中 Job 折算比例
desiredJobs = ceil(
    (pendingEvents / customScalingQueueLengthDeduction) -
    (runningJobs * customScalingRunningJobPercentage)
)

假设队列 100 条消息,运行中 Job 10 个:

  • desiredJobs = ceil(100/1 - 10×0.5) = ceil(100 - 5) = 95
  • 表示还需要创建 85 个 Job(减去已有 10 个运行中)

[精确策略]

scalingStrategy:
  strategy: "accurate"

desiredJobs = pendingEvents(与 default 相同),但 maxReplicaCount 直接等价于事件总数,无上限推导。

[急切策略]

scalingStrategy:
  strategy: "eager"

尽可能快速创建 Job 来消费队列,desiredJobs 直接等于 maxReplicaCountpendingEvents 中的较大值。

[策略选择]

策略场景优点缺点
default低频、处理快实现简单高频时创建过多
custom高频、处理慢考虑运行中 Job,避免堆积配置复杂
accurate需要全量并发消息级精确控制可能资源爆炸
eager延迟敏感最快速度消费资源浪费
13 ScaledJob 如何清理已完成的 Job?历史记录保留如何配置?

答案:

ScaledJob 通过 successfulJobsHistoryLimitfailedJobsHistoryLimit 控制已完成 Job 的清理策略,避免历史 Job 对象堆积。

[清理配置]

apiVersion: keda.sh/v1alpha1
kind: ScaledJob
metadata:
  name: sqs-worker
spec:
  jobTargetRef:
    template:
      spec:
        containers:
        - name: worker
          image: worker:latest
        restartPolicy: Never
    backoffLimit: 4
  successfulJobsHistoryLimit: 5     # 保留最近 5 个成功 Job
  failedJobsHistoryLimit: 3         # 保留最近 3 个失败 Job
  maxReplicaCount: 50
参数默认值说明
successfulJobsHistoryLimit100成功 Job 保留数,超出的被 KEDA 删除
failedJobsHistoryLimit100失败 Job 保留数,超出的被 KEDA 删除
backoffLimit6(Job 默认)Job 内部重试次数

[清理行为]

graph LR
    A["定时检查:KEDA Operator 定期检查 ScaledJob 创建的 Job"]
    A --> B["成功 Job 数 > successfulJobsHistoryLimit"]
    B -.-> C["删除最旧的成功 Job<br/>保留最新的 N 个"]
    A --> D["失败 Job 数 > failedJobsHistoryLimit"]
    D -.-> E["删除最旧的失败 Job"]
    A --> F["Job 未完成 → 不参与清理"]

[标签传播与排除]

# 默认行为:ScaledJob 的 labels 全部传播到创建的 Job
# 排除特定标签(避免传播敏感或高基数标签)
metadata:
  annotations:
    scaledjob.keda.sh/job-excluded-labels: "team,environment"
  labels:
    app: worker
    team: backend
    environment: staging
14 KEDA 的 TriggerAuthentication 支持哪些认证源?参数化映射机制是什么?

答案:

TriggerAuthentication 支持 Kubernetes Secret、环境变量、HashiCorp Vault、Azure Key Vault、AWS/GCP Secret Manager、Pod Identity 等多种认证源。通过 parameter 字段将认证值映射到 Scaler 所需的参数名。

[认证源矩阵]

源类型配置路径作用域适用场景
secretTargetRefKubernetes Secret命名空间通用,密码/密钥/连接串
env容器环境变量命名空间跟随部署环境变量
podIdentityProvider 标识命名空间云原生 Workload Identity
hashiCorpVaultVault KV Engine命名空间已有 Vault 基础设施
azureKeyVaultAzure Key Vault命名空间Azure 云原生
awsSecretManagerAWS Secrets Manager命名空间AWS 云原生
gcpSecretManagerGCP Secret Manager命名空间GCP 云原生
boundServiceAccountTokenSA Token命名空间K8s 内建认证
filePath文件路径集群(仅 CTA)从 Operator 挂载文件读取

[参数化映射机制]

graph LR
    A["每个 Scaler 定义一组需要的参数<br/>如 sasl、tls、password"] --> B["TriggerAuthentication 通过 parameter 字段将认证源的值映射到 Scaler 参数"]
    B --> C["secretTargetRef.parameter = sasl<br/>从 Secret 中取某个 key 的值<br/>传给 Scaler 的 sasl 参数"]
    C --> D["ScaledObject 的 trigger 中通过 authenticationRef 引用 TriggerAuthentication"]
# 示例:Scaler 需要 connectionString 和 queueName
# TriggerAuthentication 提供 connectionString 值
apiVersion: keda.sh/v1alpha1
kind: TriggerAuthentication
metadata:
  name: azure-queue-auth
spec:
  secretTargetRef:
  - parameter: connectionString     # 映射到 Azure Queue Scaler 的 connectionString 参数
    name: azure-storage-secret      # Secret 名称
    key: connectionString           # Secret 中的 key
# ScaledObject 引用
apiVersion: keda.sh/v1alpha1
kind: ScaledObject
metadata:
  name: azure-consumer
spec:
  triggers:
  - type: azure-queue
    metadata:
      queueName: myqueue            # 非敏感参数放在 metadata
      # connectionString 由 TriggerAuthentication 提供
    authenticationRef:
      name: azure-queue-auth        # 引用认证

[Pod Identity 配置]

# Azure AD Workload Identity
apiVersion: keda.sh/v1alpha1
kind: TriggerAuthentication
metadata:
  name: azure-pod-identity-auth
spec:
  podIdentity:
    provider: azure-workload
    identityId: <uuid>              # 可选,指定托管标识 ID
# AWS IRSA
apiVersion: keda.sh/v1alpha1
kind: TriggerAuthentication
metadata:
  name: aws-irsa-auth
spec:
  podIdentity:
    provider: aws
    roleArn: arn:aws:iam::123456789012:role/keda-role

[ClusterTriggerAuthentication]

# 集群级认证配置,可在任意命名空间引用
apiVersion: keda.sh/v1alpha1
kind: ClusterTriggerAuthentication
metadata:
  name: global-rabbitmq-auth
spec:
  secretTargetRef:
  - parameter: host
    name: keda-secrets/rabbitmq     # cluster-scoped 需包含命名空间前缀
    key: host
# 跨命名空间引用
spec:
  triggers:
  - type: rabbitmq
    authenticationRef:
      name: global-rabbitmq-auth
      kind: ClusterTriggerAuthentication   # 指定集群级
15 TriggerAuthentication 的 podIdentity 支持哪些云厂商?如何配置?

答案:

podIdentity 支持 Azure AD Workload Identity、AWS IRSA(IAM Roles for Service Accounts)和 GCP Workload Identity。KEDA Operator 使用这些云原生的无密钥认证方式访问事件源。

[Azure AD Workload Identity]

# 前提:KEDA Operator 的 ServiceAccount 已配置 Azure AD 集成
apiVersion: keda.sh/v1alpha1
kind: TriggerAuthentication
metadata:
  name: azure-servicebus-auth
spec:
  podIdentity:
    provider: azure-workload
    identityId: /subscriptions/.../userAssignedIdentities/my-identity  # 可选
# ScaledObject 使用
apiVersion: keda.sh/v1alpha1
kind: ScaledObject
spec:
  triggers:
  - type: azure-servicebus
    metadata:
      queueName: myqueue
      namespace: sb-namespace
    authenticationRef:
      name: azure-servicebus-auth

[AWS IRSA]

# 前提:KEDA Operator ServiceAccount 已添加 IAM Role 注解
# kubectl annotate sa keda-operator -n keda eks.amazonaws.com/role-arn=arn:aws:iam::...
apiVersion: keda.sh/v1alpha1
kind: TriggerAuthentication
metadata:
  name: aws-sqs-auth
spec:
  podIdentity:
    provider: aws
    roleArn: arn:aws:iam::123456789012:role/keda-sqs-role
# or
spec:
  podIdentity:
    provider: aws-eks            # 已废弃,v3 移除
# 可选的 identityOwner 控制
spec:
  podIdentity:
    provider: aws
    identityOwner: keda           # keda(默认,使用 Operator 身份)
    identityOwner: workload       # workload(使用目标 Pod 身份)

[GCP Workload Identity]

# 前提:KEDA 运行在 GKE 并配置 Workload Identity 绑定
apiVersion: keda.sh/v1alpha1
kind: TriggerAuthentication
metadata:
  name: gcp-pubsub-auth
spec:
  podIdentity:
    provider: gcp
# ScaledObject 引用
spec:
  triggers:
  - type: gcp-pubsub
    metadata:
      topic: my-topic
      subscription: my-sub
    authenticationRef:
      name: gcp-pubsub-auth

[身份发现顺序]

graph LR
    A["KEDA Operator 默认使用自身 Pod 的身份进行外部访问"]
    A --> B["azure-workload: 使用 Operator ServiceAccount 的托管标识"]
    A --> C["aws/aws-eks: 使用 Operator ServiceAccount 绑定的 IAM Role"]
    A --> D["gcp: 使用 Operator 节点的 GCP Service Account"]
    A --> E["identityOwner: workload<br/>改用目标部署的 Pod 身份(仅 AWS)"]
16 TriggerAuthentication 如何集成 HashiCorp Vault?

答案:

KEDA 支持直接从 HashiCorp Vault 读取密钥,支持 Token 认证和 Kubernetes 认证两种模式。

[Kubernetes 认证]

apiVersion: keda.sh/v1alpha1
kind: TriggerAuthentication
metadata:
  name: vault-auth
spec:
  hashiCorpVault:
    address: http://vault.example.com:8200
    authentication: kubernetes              # Vault Kubernetes Auth 方法
    role: my-role                           # Vault Role(绑定 SA)
    mount: k8s                              # Vault auth mount path
    credential:
      serviceAccount: /var/run/secrets/kubernetes.io/serviceaccount/token  # 默认路径
    secrets:
    - parameter: password                   # 映射到 Scaler 的 password 参数
      key: db_password                      # Vault 中数据的 key
      path: secret/data/db/mysql            # Vault secret path
    - parameter: host
      key: host
      path: secret/data/kafka
apiVersion: keda.sh/v1alpha1
kind: ScaledObject
spec:
  triggers:
  - type: mysql
    metadata:
      dbName: mydb
    authenticationRef:
      name: vault-auth

[Token 认证]

apiVersion: keda.sh/v1alpha1
kind: TriggerAuthentication
metadata:
  name: vault-token-auth
spec:
  hashiCorpVault:
    address: http://vault.example.com:8200
    authentication: token                  # 使用 Vault Token
    credential:
      token: s.abcdef123456789             # 可直接指定 Token
    secrets:
    - parameter: connectionString
      key: connectionString
      path: secret/data/rabbitmq
# 从 Secret 读取 Token
spec:
  hashiCorpVault:
    authentication: token
    credential:
      tokenFromSecret:
        name: vault-token
        key: token

[Vault Secrets 路径说明]

  • K/V v2:路径格式 secret/data/{path}(返回 data.data.{key} 下的值)
  • K/V v1:路径格式 secret/{path}
  • 如需指定版本:secret/data/db/mysql?version=2
17 ScaledObject 如何引用 TriggerAuthentication?authenticationRef 的作用域是什么?

答案:

authenticationRef 将 ScaledObject/ScaledJob 的 trigger 与 TriggerAuthentication 绑定,指定每个触发器使用哪套认证凭据。

[引用方式]

apiVersion: keda.sh/v1alpha1
kind: ScaledObject
metadata:
  name: consumer
  namespace: ns-a
spec:
  triggers:
  - type: kafka
    metadata:
      topic: my-topic
      bootstrapServers: kafka:9092
      consumerGroup: my-group
    authenticationRef:                        # 每个 trigger 独立认证
      name: kafka-auth                        # TriggerAuthentication 名称(同命名空间)
      # kind 默认为 TriggerAuthentication(命名空间级)
  - type: rabbitmq
    metadata:
      queueName: my-queue
    authenticationRef:
      name: global-rabbit-auth
      kind: ClusterTriggerAuthentication     # 跨命名空间引用

[作用域规则]

类型作用域可引用的命名空间
TriggerAuthentication命名空间仅同命名空间
ClusterTriggerAuthentication集群任意命名空间

[多 Trigger 多认证]

# 一个 ScaledObject 的不同 trigger 可以使用不同的认证源
spec:
  triggers:
  - type: kafka
    authenticationRef:
      name: kafka-auth-vault               # 来自 Vault
  - type: prometheus
    authenticationRef:
      name: prom-auth-env                  # 来自环境变量
  - type: rabbitmq
    authenticationRef:
      name: global-rabbit-auth
      kind: ClusterTriggerAuthentication   # 集群级共享认证

[认证参数覆盖]

TriggerAuthentication 的 parameter 必须与 Scaler 期望的参数名一致

常见 Scaler 参数名:
  - host / hosts / server / serverAddress
  - username / password
  - connectionString
  - apiKey
  - sasl / tls / ca / cert / key
  - awsRegion / awsAccessKeyId / awsSecretAccessKey
  - tenantId / clientId / clientSecret

TriggerAuthentication 的 parameter 值会覆盖 ScaledObject metadata 中的同名参数

[注意事项]

  • authenticationRef 是 trigger level 的,每个 trigger 独立指定
  • 同一 ScaledObject 的不同 trigger 可引用不同的 TriggerAuthentication
  • authenticationRef 为空时,Scaler 使用 metadata 中的明文参数
  • 生产环境禁止在 metadata 中明文传递敏感信息,必须使用 TriggerAuthentication
18 KEDA 内置哪些 Scaler 类别?如何选择合适的 Scaler?

答案:

KEDA 提供 80+ 内置 Scaler,覆盖消息队列、数据存储、监控系统、CI/CD、云服务等类别。

[Scaler 类别]

类别Scaler 数量代表
消息队列15+Kafka、RabbitMQ、ActiveMQ、Pulsar、NATS、SQS、Azure Service Bus
数据存储15+PostgreSQL、MySQL、MongoDB、Redis、Elasticsearch、Cassandra
监控/分析15+Prometheus、Datadog、Dynatrace、Loki、New Relic、Splunk
云服务20+AWS CloudWatch/DynamoDB/Kinesis, Azure Event Hubs/Blob/Monitor, GCP Pub/Sub
CI/CD2GitHub Runner、Azure Pipelines、Selenium Grid
调度2Cron、PredictKube
K8s 内建3CPU、Memory、Kubernetes Workload
扩展2External、External Push

[选型指南]

问题推荐 Scaler
我的应用从消息队列消费Kafka、RabbitMQ、SQS、Azure Service Bus
我需要根据数据库压力缩放PostgreSQL、MySQL、Redis Lists/Streams
我使用 Prometheus 监控Prometheus Scaler(自定义 PromQL)
我想按时间规律缩放Cron Scaler(定时扩缩)
我需要 K8s 内建指标CPU、Memory、Kubernetes Workload
我没有合适的内置 ScalerExternal(gRPC 自定义)或 External Push
我运行 CI 流水线GitHub Runner、Azure Pipelines

[External Scaler]

# 通过 gRPC 协议实现自定义 Scaler
apiVersion: keda.sh/v1alpha1
kind: ScaledObject
metadata:
  name: custom
spec:
  triggers:
  - type: external
    metadata:
      scalerAddress: custom-scaler:9000      # gRPC Scaler 地址
      # 自定义元数据
      myParam: value
    authenticationRef:
      name: custom-auth
# External Scaler 需实现以下 gRPC 接口:
# rpc IsActive(ctx, ScaledObjectRef) → IsActiveResponse
# rpc GetMetricSpec(ctx, ScaledObjectRef) → MetricSpec
# rpc GetMetrics(ctx, GetMetricRequest) → GetMetricResponse
# rpc StreamIsActive(ctx, ScaledObjectRef) → Stream → IsActiveResponse(可选,push 模式)
19 Prometheus Scaler 如何配置?如何通过 PromQL 驱动缩放?

答案:

Prometheus Scaler 允许使用任意 PromQL 查询结果作为缩放指标,是最灵活的内置 Scaler 之一。

[配置示例]

apiVersion: keda.sh/v1alpha1
kind: ScaledObject
metadata:
  name: http-api
spec:
  scaleTargetRef:
    name: api-server
  triggers:
  - type: prometheus
    metadata:
      serverAddress: http://prometheus:9090
      metricName: http_requests_rate        # 指标名称(自定义)
      query: |
        sum(rate(http_requests_total{job="api"}[2m]))        
      threshold: "100"                      # 每个副本目标处理 100 req/s
      activationThreshold: "10"             # 低于 10 时不扩容
      namespace: default                    # 指标所属命名空间(用于隔离)
# 高级查询:按路径分流
  - type: prometheus
    metadata:
      serverAddress: http://prometheus:9090
      metricName: api_error_rate
      query: |
        sum(rate(http_requests_total{status=~"5.."}[1m]))
        /
        sum(rate(http_requests_total[1m]))        
      threshold: "0.01"                    # 错误率 > 1% 时扩容
# 使用 cortex/thanos 等多租户 Prometheus
  - type: prometheus
    metadata:
      serverAddress: http://thanos-query:9090
      metricName: queue_depth
      query: max(kafka_consumer_lag)
      threshold: "1000"
      namespace: monitoring
      headers: "X-Scope-OrgID: my-tenant"  # 自定义 HTTP Header

[缩放逻辑]

graph LR
    A["HPA 查询 KEDA → KEDA 执行 PromQL → 获取返回值的第一个数据点"] --> B["desiredReplicas = ceil(query_result / threshold)"]
    B --> C["query_result = 500, threshold = 100<br/>desired = ceil(500/100) = 5 replicas"]
    B --> D["query_result = 0(且未设 activationThreshold)<br/>desired = 0 → scale to zero"]
    B --> E["query_result < activationThreshold<br/>从 0 激活时不扩容"]

[Prometheus Scaler 最佳实践]

  • metricName 在同命名空间的 ScaledObject 间必须唯一
  • 查询结果必须是单一数值(KEDA 取结果集的第一个值)
  • 使用 rate()/increase() 等函数处理 Counter 类型指标
  • 避免高基数查询导致 Prometheus 负载过大
  • activationThreshold 可防止指标毛刺导致 0→1 抖动
  • 支持缺省时跳过 TLS 验证(unsafeSsl: "true"
20 Cron Scaler 的工作原理是什么?如何实现定时扩缩?

答案:

Cron Scaler 按 CRON 表达式在指定时间调整工作负载副本数,适用于可预测的流量模式。不同于其他 Scaler 从外部事件源采集指标,Cron Scaler 基于时间触发。

[配置示例]

apiVersion: keda.sh/v1alpha1
kind: ScaledObject
metadata:
  name: cron-scaler
spec:
  scaleTargetRef:
    name: my-app
  minReplicaCount: 1                        # 基础副本数
  maxReplicaCount: 50                       # 最大副本数
  triggers:
  - type: cron
    metadata:
      timezone: Asia/Shanghai
      start: 30 8 * * *                     # 每天 8:30 开始扩容
      end: 30 18 * * *                      # 每天 18:30 开始缩容
      desiredReplicas: "20"                 # 高峰期间保持 20 副本
# 多时间段配置
  - type: cron
    metadata:
      timezone: Asia/Shanghai
      start: 0 9 * * 1-5                    # 工作日 9:00
      end: 0 18 * * 1-5                     # 工作日 18:00
      desiredReplicas: "10"
  - type: cron
    metadata:
      timezone: Asia/Shanghai
      start: 0 10 * * 6,7                   # 周末 10:00
      end: 0 16 * * 6,7                     # 周末 16:00
      desiredReplicas: "5"

[Cron 缩放行为]

graph LR
    A["当前时间"]
    A --> B["在 start 和 end 之间<br/>Cron Scaler 返回 desiredReplicas"]
    B -.-> C["HPA 将副本数调整为 desiredReplicas<br/>受 maxReplicaCount 限制"]
    A --> D["不在时间段内<br/>Cron Scaler 返回 0"]
    D -.-> E["遵循 minReplicaCount<br/>如果 minReplicaCount > 0,保留基础副本"]

[时间重叠处理]

graph LR
    A["多 Cron 时间段重叠<br/>KEDA 取所有激活 Cron 中的最大值"]
    A --> B["Cron1: 9-18点, desiredReplicas=10"]
    A --> C["Cron2: 12-14点, desiredReplicas=20"]
    C -.-> D["12-14点期间: desiredReplicas = max(10, 20) = 20"]

[应用场景]

  • 工作日/周末不同容量
  • 已知促销活动时间段的预扩容
  • 定时批处理窗口的资源预留
  • 降低非高峰期的资源成本

[提示]

  • timezone 省略时默认 UTC
  • startend 使用标准 5 字段 CRON 表达式
  • Cron Scaler 不支持 useCachedMetrics(默认不使用缓存)
  • Cron Scaler 单独使用时不需 TriggerAuthentication
21 Kafka Scaler 如何配置?lagThreshold 和 activationLagThreshold 的区别是什么?

答案:

Kafka Scaler 根据消费者组的消费延迟(Lag)决定缩放,是消息驱动场景中最常用的 Scaler 之一。

[配置示例]

apiVersion: keda.sh/v1alpha1
kind: ScaledObject
metadata:
  name: kafka-consumer
spec:
  scaleTargetRef:
    name: consumer-app
  pollingInterval: 10                     # 高频采集 Lag
  cooldownPeriod: 60
  triggers:
  - type: kafka
    metadata:
      bootstrapServers: kafka-cluster:9092
      consumerGroup: my-group
      topic: my-topic
      lagThreshold: "100"                 # 每个副本允许的 Lag 上限
      activationLagThreshold: "10"        # 激活阈值(低于此不扩容)
      offsetResetPolicy: latest           # earliest / latest
      allowIdleConsumers: "true"          # 允许空闲消费者
      version: "2.8.0"                    # Kafka 版本
      excludePersistentLag: "false"       # 排除持久 Lag
      partitionLimitation: "2"            # 限制分区数
      # SASL 认证(建议使用 TriggerAuthentication)
      # sasl: ...
      # tls: ...
    authenticationRef:
      name: kafka-auth
# SASL + TLS 认证
apiVersion: keda.sh/v1alpha1
kind: TriggerAuthentication
metadata:
  name: kafka-auth
spec:
  secretTargetRef:
  - parameter: sasl
    name: kafka-secret
    key: sasl
  - parameter: tls
    name: kafka-secret
    key: tls

[滞后阈值与激活滞后阈值]

graph LR
    A["总 Lag = sum(所有分区的 consumer lag)"]
    A --> B["totalLag < activationLagThreshold(10)<br/>Scaler 返回 0 → 缩容<br/>到 idleReplicaCount 或 0"]
    A --> C["totalLag 在 10 ~ 100 之间<br/>已激活但不需要额外副本<br/>保持当前副本数"]
    A --> D["totalLag > lagThreshold(100)<br/>desiredReplicas = ceil(totalLag / lagThreshold)<br/>扩容到 2、3、4... 个副本"]

[多 Topic 消费]

# 消费多个 topic(逗号分隔)
  - type: kafka
    metadata:
      topic: topic-a,topic-b,topic-c
      consumerGroup: multi-topic-group
# 正则匹配 topic
  - type: kafka
    metadata:
      topic: orders-.*
      consumerGroup: orders-group

[身份认证]

  • SASL/PLAIN、SASL/SCRAM、SASL/GSSAPI 均支持
  • TLS 双向认证
  • 通过 TriggerAuthentication 传递敏感参数
22 KEDA 的 External Scaler 协议是什么?如何实现自定义 Scaler?

答案:

External Scaler 是通过 gRPC 协议实现的自定义 Scaler,用于 KEDA 内置 Scaler 无法覆盖的场景。KEDA 定义了 IsActiveGetMetricSpecGetMetrics 三个核心 RPC 接口。

[gRPC 协议]

service ExternalScaler {
  // 返回 Scaler 是否处于激活状态(决定是否从 0→1)
  rpc IsActive(ScaledObjectRef) returns (IsActiveResponse);

  // 返回 HPA 所需的指标规格(指标名、目标类型、目标值)
  rpc GetMetricSpec(ScaledObjectRef) returns (GetMetricSpecResponse);

  // 返回当前指标值(HPA 查询时调用)
  rpc GetMetrics(GetMetricsRequest) returns (GetMetricsResponse);

  // 可选:流式激活通知(替代轮询 IsActive)
  rpc StreamIsActive(ScaledObjectRef) returns (stream IsActiveResponse);
}

[ScaledObject 配置]

apiVersion: keda.sh/v1alpha1
kind: ScaledObject
metadata:
  name: custom-scaler
spec:
  triggers:
  - type: external            # 内置 External Scaler
    metadata:
      scalerAddress: custom-scaler-svc:9000   # gRPC 服务地址
      # 自定义元数据,随请求发送到 gRPC Scaler
      endpoint: /api/queue-length
      apiKey: xxx
  - type: external-push       # Push 模式(无需轮询)
    metadata:
      scalerAddress: push-scaler:9000

[External Push Scaler]

# Push 模式:外部系统主动通知 KEDA,避免轮询开销
apiVersion: keda.sh/v1alpha1
kind: ScaledObject
metadata:
  name: push-consumer
spec:
  triggers:
  - type: external-push
    metadata:
      scalerAddress: push-scaler:9000
# 外部系统通过 gRPC 调用 StreamIsActive 推送事件
# 每次事件到达 → KEDA 重新评估是否需要扩容

[Scaler 实现要点]

  • IsActive 返回 boolean:true = 需要至少 1 个副本
  • GetMetricSpec 返回指标规格(指标名、目标类型 AverageValue/Value、目标值)
  • GetMetrics 返回当前指标值(HPA 用它和 target 计算 desired replicas)
  • StreamIsActive 是可选的 Push 模式,避免频繁 Polling
  • Scaler 通常以独立 Deployment + Service 部署
23 KEDA 的 Admission Webhooks 起什么作用?

答案:

KEDA 的 Admission Webhooks 提供验证(Validating)和变更(Mutating)两个钩子,在 ScaledObject/ScaledJob/TriggerAuthentication 资源持久化前进行校验和修正。

[Webhook 功能]

Webhook 类型作用拦截资源
ValidatingWebhook校验配置合法性ScaledObject、ScaledJob、TriggerAuthentication
MutatingWebhook设置默认值、注入配置ScaledObject、ScaledJob

[验证规则]

# ValidatingWebhook 校验的内容(示例):
# 1. 防止多个 ScaledObject 指向同一个 targetRef
#    → 同一 Deployment 不能被两个 ScaledObject 管理
#    → 报错: "ScaledObject already exists for this target"
#
# 2. 校验 scaleTargetRef 引用的资源存在
#    → Deployment/StatefulSet 必须存在
#    → Custom Resource 必须实现 /scale 子资源
#
# 3. 校验 TriggerAuthentication 的 provider 配置
#    → podIdentity.provider 必须是合法值
#    → Vault 地址格式校验
#
# 4. 校验 Scaler 参数完整性
#    → 必填参数不能为空

[变更逻辑]

# MutatingWebhook 自动设置的默认值:
# spec.pollingInterval = 30(未指定时)
# spec.cooldownPeriod = 300
# spec.minReplicaCount = 0
# spec.maxReplicaCount = 100
# spec.scalingStrategy.strategy = "default"

[生产配置]

# KEDA 安装时默认启用 Webhooks
# 可配置失败策略:
apiVersion: admissionregistration.k8s.io/v1
kind: ValidatingWebhookConfiguration
metadata:
  name: keda-admission
spec:
  failurePolicy: Fail            # Fail / Ignore
  # Fail: Webhook 不可用时拒绝创建资源
  # Ignore: Webhook 不可用时允许创建(降级)
24 KEDA 如何与 Prometheus/Grafana 集成?暴露哪些指标?

答案:

KEDA Operator 暴露 Prometheus 格式的内部指标,涵盖 Scaler 执行状态、Operator 操作计数、Metrics Server 请求量等,用于监控 KEDA 本身运行健康度和缩放行为。

[指标类别]

指标类别指标名说明
Scaler 执行keda_scaler_errors_totalScaler 采集错误次数
Scaler 执行keda_scaler_activeScaler 是否激活(1/0)
Scaler 执行keda_scaler_metrics_valueScaler 返回的原始指标值
Scaler 执行keda_scaler_metrics_latencyScaler 采集延迟(秒)
Operator 操作keda_scaled_object_errors_totalScaledObject 调和错误
Operator 操作keda_resource_creation_total创建 HPA/Job 的计数
Operator 操作keda_resource_creation_errors_total资源创建失败计数
Metrics Serverkeda_metrics_adapter_grpc_errors_totalgRPC Scaler 调用错误
Metrics Serverkeda_metrics_adapter_request_duration指标请求处理时间
内部状态keda_internal_scale_upScale-up 事件数
内部状态keda_internal_scale_downScale-down 事件数

[Prometheus 采集配置]

# KEDA Operator 默认在 8080 端口暴露指标
# ServiceMonitor 示例
apiVersion: monitoring.coreos.com/v1
kind: ServiceMonitor
metadata:
  name: keda-operator
  namespace: keda
spec:
  selector:
    matchLabels:
      app: keda-operator
  endpoints:
  - port: metrics
    interval: 15s
    path: /metrics
# Prometheus 直接采集
# keda-operator 的 Service 已包含 prometheus.io/scrape: "true" 注解

[Grafana 监控]

  • 官方提供 KEDA 运维 Dashboard(面板 ID 可从社区获取)
  • 关键面板:Scaler 健康度、缩放事件时间线、ScaledObject 状态分布
  • 告警建议:Scaler 错误率 > 0、ScaledObject 调和失败、Metrics Server 延迟 > 5s
25 KEDA 如何集成 Istio 服务网格?需要哪些额外配置?

答案:

KEDA 可与 Istio 协同运行,但需注意 KEDA Operator 和目标工作负载的网络策略、mTLS 和权限配置。

[集成要点]

关注点配置
Operator 注入KEDA Operator 本身不应注入 Sidecar(避免启动循环)
目标工作负载ScaledObject 管理的 Deployment 正常注入 Sidecar
mTLSPeerAuthentication 需放行 KEDA Metrics Server 的指标查询
网络策略允许 KEDA Metrics Server → 目标 Pod 的 8080/6443 通信

[Operator 排除 Sidecar 注入]

# KEDA 命名空间排除 Sidecar 自动注入
apiVersion: v1
kind: Namespace
metadata:
  name: keda
  annotations:
    sidecar.istio.io/inject: "false"          # 方式 1:命名空间注解
# 或为 KEDA Operator Pod 添加注解
apiVersion: apps/v1
kind: Deployment
metadata:
  name: keda-operator
  namespace: keda
spec:
  template:
    metadata:
      annotations:
        sidecar.istio.io/inject: "false"      # 方式 2:Pod 注解

[授权策略]

# 允许 KEDA Metrics Server 跨命名空间访问指标
apiVersion: security.istio.io/v1beta1
kind: AuthorizationPolicy
metadata:
  name: keda-allow
  namespace: your-app
spec:
  selector:
    matchLabels:
      app: your-app
  action: ALLOW
  rules:
  - from:
    - source:
        namespaces: ["keda"]
    to:
    - operation:
        ports: ["8080"]

[Scaler TLS 配置]

# 当工作负载启用 Strict mTLS 时
# KEDA 的 Prometheus Scaler 或其他 HTTP Scaler 可能需要跳过 TLS 验证
triggers:
- type: prometheus
  metadata:
    unsafeSsl: "true"          # 跳过 TLS 校验(仅内部网络可行)
# 或配置证书
triggers:
- type: prometheus
  metadata:
    ca: /path/to/ca.crt
26 KEDA 的 OpenTelemetry 集成提供哪些能力?

答案:

KEDA 支持 OpenTelemetry Collector 集成(实验性),可将缩放事件和 Scaler 指标通过 OTel 协议导出到外部观测系统。

[集成架构]

graph LR
    A["KEDA Operator"] -->|OTLP| B["OpenTelemetry Collector"]
    B --> C["Jaeger/Zipkin(追踪)"]
    B --> D["Prometheus(指标)"]
    B --> E["Loki/Elasticsearch(日志)"]

[启用配置]

# KEDA Operator 环境变量启用 OTel
apiVersion: apps/v1
kind: Deployment
metadata:
  name: keda-operator
  namespace: keda
spec:
  template:
    spec:
      containers:
      - name: keda-operator
        env:
        - name: KEDA_OTEL_ENABLED
          value: "true"
        - name: OTEL_EXPORTER_OTLP_ENDPOINT
          value: "http://otel-collector:4318"
        - name: OTEL_SERVICE_NAME
          value: "keda-operator"

[导出的数据类型]

数据类型内容状态
TracesScaler 调用链路(IsActive/GetMetrics)实验性
MetricsScaler 耗时、错误计数实验性
Logs缩放决策日志实验性

[CloudEvent 支持]

  • KEDA 可将缩放事件以 CloudEvent 格式发送到 HTTP 端点
  • 配置路径:/docs/latest/operate/cloud-events/
  • 适用于外部审计系统或事件驱动工作流联动
27 KEDA 安装方式有哪些?生产环境推荐配置是什么?

答案:

KEDA 支持 Helm、YAML 直装和 Operator Hub 三种部署方式。生产环境建议使用 Helm 进行版本管理和 GitOps 集成。

[安装方式对比]

方式命令适用场景
Helmhelm repo add kedacore https://kedacore.github.io/charts生产标准,版本管理
YAMLkubectl apply -f https://github.com/kedacore/keda/releases/...快速试用
Operator HubOLM 安装OpenShift 集成

[生产推荐配置]

# Helm values.yaml
# 部署配置
operator:
  name: keda-operator
  replicaCount: 2                          # 多副本高可用
  logLevel: info
  resources:
    requests:
      cpu: 100m
      memory: 128Mi
    limits:
      cpu: 500m
      memory: 256Mi
  watchNamespace: ""                        # 空 = 所有命名空间
  extraEnv:
  - name: KEDA_OTEL_ENABLED
    value: "false"                          # 按需启用 OTel

metricsServer:
  replicaCount: 2                           # Metrics Server 高可用
  resources:
    requests:
      cpu: 100m
      memory: 128Mi
    limits:
      cpu: 500m
      memory: 512Mi
  extraEnv:
  - name: METRICS_SERVER_ENABLE_PROFILING
    value: "false"

webhooks:
  replicaCount: 2                           # Webhook 高可用
  failurePolicy: Fail                       # Fail: 严格校验

# 全局配置
global:
  watchNamespace: ""                        # 监控所有命名空间
  kubeletPort: 10250
# 安装命令
helm install keda kedacore/keda \
  --namespace keda --create-namespace \
  --values values.yaml \
  --version 2.19.0

[生产清单]

  • Operator 副本 2+,PDB 设置 minAvailable: 1
  • Metrics Server 副本 2+,防止缩容期间指标不可用
  • 资源限制:防止 OOM 导致 KEDA 不可用
  • --watch-namespace 限制范围(可选,多租户场景)
  • 配置 Prometheus ServiceMonitor 监控 KEDA 自身指标
  • 启用 Admission Webhooks(failurePolicy: Fail
28 KEDA 的错误排查工具有哪些?如何定位缩放异常?

答案:

KEDA 的排查工具包括 Operator 日志、Kubernetes Events、ScaledObject 状态和 Metrics Server 调试端点。

[排查工具]

工具命令/方法目的
Operator 日志kubectl logs -n keda deploy/keda-operator查看缩放决策日志
ScaledObject 状态kubectl get scaledobject <name> -o yaml查看 CRD 状态和错误信息
Kubernetes Eventskubectl get events -n <ns> --watch查看 KEDA 发布的事件
HPA 状态kubectl get hpa <name> -o yaml查看 HPA 指标和目标值
Metrics APIkubectl get --raw /apis/external.metrics.k8s.io/v1beta1查看可用外部指标
Metric 值kubectl get --raw /apis/external.metrics.k8s.io/v1beta1/namespaces/<ns>/<metric-name>查看指标当前值

[常见问题定位]

# 1. 检查 ScaledObject 状态
kubectl get scaledobject kafka-consumer -o jsonpath='{.status}' | jq .
# 关键字段:
# .status.conditions[] - 就绪状态
# .status.health[] - Scaler 健康状态
# .status.hpaName - 关联的 HPA 名称
# .status.lastActiveTime - 最后激活时间
# .status.externalMetricNames - 生成的外部指标名

# 2. 检查 HPA 事件
kubectl describe hpa keda-hpa-kafka-consumer
# 查看 Events 中的 Scaling 相关事件
# 查看 Metrics 字段是否正常显示当前/目标值

# 3. 检查外部指标是否存在
kubectl get --raw /apis/external.metrics.k8s.io/v1beta1 | jq '.resources[].name'
# 应包含 keda-<namespace>-<scaledobject-name>-<trigger-index>

# 4. 直接查询指标值
kubectl get --raw "/apis/external.metrics.k8s.io/v1beta1/namespaces/default/keda-default-kafka-consumer-0" | jq '.items[0].value'
# 应返回当前指标数值

# 5. 查看 Operator 日志
kubectl logs -n keda deploy/keda-operator --tail=100 | grep kafka-consumer
# 查找 ScaledObject 的调和日志

[排查流程图]

graph LR
    A[工作负载未缩放] --> B{检查 ScaledObject 状态}
    B -->|conditions.Ready=False| C[查看 status.health<br/>定位 Scaler 错误]
    B -->|conditions.Ready=True| D{检查 HPA 状态}
    D -->|metrics 不正常| E[检查 External Metrics API<br/>指标名和数值]
    D -->|metrics 正常| F{检查 Operator 日志}
    F -->|有错误日志| G[根据错误信息修复<br/>Scaler 连接/认证/权限]
    F -->|无错误| H[检查 Pod 资源限制<br/>HPA behavior 配置]
    C --> I[检查 TriggerAuthentication<br/>网络连通性<br/>Scaler 参数]
    E --> I

[典型问题根因]

现象根因排查方向
ScaledObject 状态异常Scaler 连接失败或认证错误检查 TriggerAuthentication 和网络
HPA 不显示指标Metrics Server 未注册或指标名错误检查 external.metrics.k8s.io API
工作负载不扩容HPA behavior 限制或资源上限检查 maxReplicaCount 和 behavior
缩容到 0 后不复活activationThreshold 设置不当检查激活阈值和 pollingInterval
Job 创建过多scalingStrategy 配置不当调整 customScalingQueueLengthDeduction
29 KEDA 的安全最佳实践有哪些?

答案:

KEDA 涉及访问外部事件源和操作 Kubernetes 资源,需从凭证管理、网络策略、RBAC 和资源隔离四个维度进行安全加固。

[安全维度]

维度措施说明
凭证管理禁止 metadata 明文敏感信息必须使用 TriggerAuthentication
凭证管理定期轮换 Secret外部系统的连接串/令牌
凭证管理优先 Pod Identity减少静态凭据,云原生认证
网络策略限制 KEDA 出站仅允许访问指定的事件源
网络策略mTLS 集成与 Istio 配合保护 KEDA 到事件源的通信
RBAC最小权限原则Operator ServiceAccount 仅需必要权限
隔离watchNamespace 限定限制 KEDA 监控的命名空间范围
Webhook启用 ValidatingWebhook防止错误配置进入集群

[TriggerAuthentication 安全]

# 推荐:使用 Pod Identity,避免静态凭据
spec:
  podIdentity:
    provider: azure-workload     # 或 aws / gcp

# 备选:从 Secret 读取,不写明文
spec:
  secretTargetRef:
  - parameter: connectionString
    name: my-secret
    key: connStr

# 禁止:metadata 中明文传递
spec:
  triggers:
  - type: rabbitmq
    metadata:
      host: amqp://user:password@rabbitmq:5672   # ❌ 明文

[RBAC 配置]

# KEDA Operator 默认 ClusterRole 包含跨命名空间资源操作
# 多租户场景下需限制 watchNamespace
# 部署时使用 --watch-namespace 限定范围
helm install keda kedacore/keda \
  --set global.watchNamespace=app-ns-1

[网络策略]

# 限制 KEDA 访问特定事件源
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
  name: keda-egress
  namespace: keda
spec:
  podSelector:
    matchLabels:
      app: keda-operator
  policyTypes:
  - Egress
  egress:
  - to:
    - namespaceSelector: {}       # 允许访问事件源
    - podSelector:
        matchLabels:
          app: kafka-broker
    ports:
    - port: 9092
      protocol: TCP
  - to:                           # 允许 DNS
    ports:
    - port: 53
      protocol: UDP
30 KEDA 的大规模生产实践有哪些?性能瓶颈和优化策略是什么?

答案:

大规模 KEDA 部署(100+ ScaledObject)需关注 Operator 调和性能、Metrics Server 指标采集压力和 HPA 管理开销。

[性能指标]

规模ScaledObject 数资源消耗建议
< 50Operator: 100m/128Mi默认配置即可
50-200Operator: 500m/256Mi多副本,开启 Webhook
200-1000Operator: 1-2C/512Mi分命名空间部署,限制 watchNamespace
超大1000+Operator: 2-4C/1Gi多 KEDA 实例隔离

[优化策略]

# 1. 降低轮询频率
spec:
  pollingInterval: 60                  # 默认 30,低频场景可调大
  cooldownPeriod: 300
# 2. 启用指标缓存
spec:
  triggers:
  - type: kafka
    useCachedMetrics: true             # 减少 Scaler 调用频率
# 3. 限定 Operator 监控范围
# Helm values:
global:
  watchNamespace: app-team-a           # 只监控特定命名空间
# 4. 合并 Scaler(减少 HPA 数量)
spec:
  triggers:
  - type: prometheus
    name: cpu
  - type: prometheus
    name: queue
  advanced:
    scalingModifiers:
      formula: "max(cpu, queue)"       # 多个指标合并到同一个 HPA

[避免 ScaledObject 冲突]

  • 同一 Deployment 只能被一个 ScaledObject 管理
  • 多个 ScaledObject 指向同一 Deployment 会导致 HPA 冲突
  • 使用 scalingModifiers 合并多指标,而非创建多个 ScaledObject

[大集群注意事项]

  • Metrics Server 缓存的指标数据量随 ScaledObject 数线性增加
  • HPA 数量过多(>1000)可能对 K8s API Server 造成压力,建议分批更新
  • Operator 调和循环按 pollingInterval 调度,200+ ScaledObject 时确保 Operator 有足够 CPU
  • 使用 keda_scaler_errors_totalkeda_scaler_metrics_latency 监控 Scaler 健康状态

[高可用部署]

# 多副本 + PDB
apiVersion: apps/v1
kind: Deployment
metadata:
  name: keda-operator
  namespace: keda
spec:
  replicas: 2
  strategy:
    rollingUpdate:
      maxSurge: 1
      maxUnavailable: 0
apiVersion: policy/v1
kind: PodDisruptionBudget
metadata:
  name: keda-operator
spec:
  minAvailable: 1
  selector:
    matchLabels:
      app: keda-operator