KEDA:Kubernetes 事件驱动自动扩缩容
KEDAKubernetes 事件驱动自动扩缩容Kubernetes 原生的 HPAHorizontal Pod Autoscaler只能基于 CPU 和内存指标进行扩缩容面对消息队列积压、数据库连接数、自定义业务指标等场景时显得力不从心。KEDAKubernetes Event-driven Autoscaling正是为填补这一空缺而生。KEDA 作为 HPA 的扩展层支持 50 种外部事件源Kafka、Redis、RabbitMQ、Prometheus、AWS SQS、Azure Queue 等能够根据这些外部事件动态调整 Pod 副本数甚至可以将副本数缩减至零以节省资源并在有事件到来时迅速从零扩容。KEDA 已是 CNCF 毕业项目在生产环境中被广泛采用。服务器配置KEDA 控制器本身资源占用很少但要发挥弹性扩缩容的价值集群需要有足够的资源池来承载突发流量下的 Pod 扩容需求。推荐配置如下组件规格CPU4 核内存8 GB系统盘60 GB SSD操作系统Ubuntu 22.04 LTS网络公网 IP搭建 K3s 集群可以考虑 雨云服务器 rainyun。注册填2026off领 5 折4 核 8GB 机型在演示 KEDA 弹性扩缩容时能够为多个 Kafka 消费者 Pod 的快速启停提供充足的资源缓冲同时还可以部署 Kafka、Redis 等消息中间件作为测试用的事件源。确认集群状态kubectl get nodes# NAME STATUS ROLES AGE VERSION# k3s-node1 Ready control-plane,master 3d v1.29.0k3s1安装添加 Helm 仓库helm repoaddkedacore https://kedacore.github.io/charts helm repo update安装 KEDAkubectl create namespace keda helminstallkeda kedacore/keda\--namespacekeda\--setwatchNamespace\--setresources.operator.requests.cpu100m\--setresources.operator.requests.memory100Mi\--setresources.metricServer.requests.cpu100m\--setresources.metricServer.requests.memory100Mi验证安装kubectl get pods-nkeda# NAME READY STATUS AGE# keda-operator-7d8f5b6b8-xk9pv 1/1 Running 2m# keda-operator-metrics-apiserver-abc123 1/1 Running 2m# keda-admission-webhooks-6b9b4f9-lmn2p 1/1 Running 2m# 验证 CRD 已注册kubectl get crd|grepkeda# scaledobjects.keda.sh# scaledjobs.keda.sh# triggerauthentications.keda.sh# clustertriggerauthentications.keda.sh核心概念ScaledObjectScaledObject是 KEDA 的核心 CRD用于将外部事件源绑定到一个 Deployment、StatefulSet 或自定义资源上控制其副本数的伸缩。你在 ScaledObject 中定义scaleTargetRef目标工作负载Deployment/StatefulSet 等minReplicaCount最小副本数设为 0 即启用缩零maxReplicaCount最大副本数上限triggers触发扩缩容的事件源列表支持多个触发器cooldownPeriod缩容前的冷却等待时间秒pollingIntervalKEDA 轮询事件源的间隔秒ScaledJobScaledJob用于基于事件驱动的批处理场景。与 ScaledObject 不同ScaledJob 每次扩容时创建新的 Job 来处理消息处理完成后 Job 自动删除适合每条消息都需要一个独立 Pod 处理的场景如视频转码、报告生成等。TriggerAuthentication / ClusterTriggerAuthenticationTriggerAuthentication用于安全地将认证信息API Key、连接字符串、证书等传递给触发器避免直接在 ScaledObject 中硬编码敏感信息。ClusterTriggerAuthentication是集群级别的可跨命名空间共用。与 HPA 的关系KEDA 并不替代 HPA而是作为 HPA 的外部指标提供者External Metrics Provider。KEDA 创建 ScaledObject 后会自动为目标工作负载生成对应的 HPA 对象并向 HPA 暴露外部指标。你可以通过kubectl get hpa看到 KEDA 自动创建的 HPA 资源。实战示例1. 基于 Kafka 消费者积压扩缩容场景根据 Kafka Topic 中未消费的消息数量动态调整消费者 Pod 数量。首先创建 Kafka 连接认证# kafka-trigger-auth.yamlapiVersion:keda.sh/v1alpha1kind:TriggerAuthenticationmetadata:name:kafka-trigger-authnamespace:defaultspec:secretTargetRef:-parameter:saslname:kafka-credentialskey:sasl-parameter:usernamename:kafka-credentialskey:username-parameter:passwordname:kafka-credentialskey:password-parameter:tlsname:kafka-credentialskey:tlskubectl create secret generic kafka-credentials\--from-literalsaslplaintext\--from-literalusernamekafka-user\--from-literalpasswordkafka-password\--from-literaltlsdisable创建 ScaledObject# kafka-scaledobject.yamlapiVersion:keda.sh/v1alpha1kind:ScaledObjectmetadata:name:kafka-consumer-scalernamespace:defaultspec:scaleTargetRef:apiVersion:apps/v1kind:Deploymentname:kafka-consumerminReplicaCount:0# 无消息时缩减为零maxReplicaCount:20# 最多扩容到 20 个 PodpollingInterval:15# 每 15 秒检查一次cooldownPeriod:60# 缩容前等待 60 秒triggers:-type:kafkametadata:bootstrapServers:kafka.kafka.svc.cluster.local:9092consumerGroup:my-consumer-grouptopic:orderslagThreshold:50# 每个 Pod 处理 50 条积压消息offsetResetPolicy:latestauthenticationRef:name:kafka-trigger-authkubectl apply-fkafka-trigger-auth.yaml kubectl apply-fkafka-scaledobject.yaml2. 基于 Redis List 队列深度扩缩容场景根据 Redis List 中待处理任务数量自动调整 Worker Pod 数量# redis-scaledobject.yamlapiVersion:keda.sh/v1alpha1kind:TriggerAuthenticationmetadata:name:redis-trigger-authnamespace:defaultspec:secretTargetRef:-parameter:addressname:redis-secretkey:address-parameter:passwordname:redis-secretkey:password---apiVersion:keda.sh/v1alpha1kind:ScaledObjectmetadata:name:redis-worker-scalernamespace:defaultspec:scaleTargetRef:apiVersion:apps/v1kind:Deploymentname:task-workerminReplicaCount:1maxReplicaCount:30pollingInterval:10cooldownPeriod:120triggers:-type:redisauthenticationRef:name:redis-trigger-authmetadata:listName:task-queuelistLength:20# 每个 Pod 处理 20 个队列项enableTLS:falsedatabaseIndex:0kubectl create secret generic redis-secret\--from-literaladdressredis.default.svc.cluster.local:6379\--from-literalpasswordyour-redis-password kubectl apply-fredis-scaledobject.yaml3. 基于 Prometheus 指标扩缩容场景根据业务自定义指标如 HTTP 请求 QPS进行扩缩容# prometheus-scaledobject.yamlapiVersion:keda.sh/v1alpha1kind:ScaledObjectmetadata:name:api-server-scalernamespace:defaultspec:scaleTargetRef:apiVersion:apps/v1kind:Deploymentname:api-serverminReplicaCount:2maxReplicaCount:50pollingInterval:30cooldownPeriod:180triggers:-type:prometheusmetadata:serverAddress:http://prometheus.monitoring.svc.cluster.local:9090metricName:http_requests_per_second# 当平均每个 Pod QPS 超过 100 时扩容threshold:100query:sum(rate(http_requests_total{namespacedefault,deploymentapi-server}[1m]))kubectl apply-fprometheus-scaledobject.yaml4. ScaledJob 批处理任务场景视频转码任务队列每条消息独立启动一个 Pod 进行处理# video-transcode-scaledjob.yamlapiVersion:keda.sh/v1alpha1kind:ScaledJobmetadata:name:video-transcode-jobnamespace:defaultspec:jobTargetRef:parallelism:5# 最多同时运行 5 个 Jobcompletions:1template:spec:containers:-name:transcoderimage:my-transcoder:latestenv:-name:QUEUE_URLvalue:sqs://my-video-queueresources:requests:cpu:1memory:2Gilimits:cpu:2memory:4GirestartPolicy:NeverpollingInterval:30maxReplicaCount:20successfulJobsHistoryLimit:3failedJobsHistoryLimit:5triggers:-type:redisauthenticationRef:name:redis-trigger-authmetadata:listName:video-transcode-queuelistLength:1# 每条消息触发一个 Jobkubectl apply-fvideo-transcode-scaledjob.yaml5. Cron 触发器定时扩缩容场景工作时间保持最少 5 个副本非工作时间缩减至 1 个# cron-scaledobject.yamlapiVersion:keda.sh/v1alpha1kind:ScaledObjectmetadata:name:business-hours-scalernamespace:defaultspec:scaleTargetRef:apiVersion:apps/v1kind:Deploymentname:web-appminReplicaCount:1maxReplicaCount:20triggers:-type:cronmetadata:timezone:Asia/Shanghaistart:0 9 * * 1-5# 工作日早 9 点开始end:0 18 * * 1-5# 工作日晚 6 点结束desiredReplicas:5# 工作时间维持 5 个副本常用命令# 查看所有 ScaledObject 及其状态kubectl get scaledobject-Akubectl describe scaledobject kafka-consumer-scaler-ndefault# 查看 KEDA 自动创建的 HPAkubectl get hpa-ndefault kubectl describe hpa keda-hpa-kafka-consumer-scaler-ndefault# 查看 ScaledJobkubectl get scaledjob-A# 查看 TriggerAuthenticationkubectl get triggerauthentication-Akubectl get clustertriggerauthentication-A# 查看 KEDA 控制器日志排查扩缩容问题kubectl logs-nkeda deploy/keda-operator-fkubectl logs-nkeda deploy/keda-operator-metrics-apiserver-f# 监控扩缩容事件kubectl get events-ndefault --field-selectorreasonKEDAScaleTargetActivated kubectl get events-ndefault --field-selectorreasonKEDAScaleTargetDeactivated# 查看当前外部指标值用于验证触发器是否正常工作kubectl get--raw/apis/external.metrics.k8s.io/v1beta1/namespaces/default/s0-kafka-orders|python3-mjson.tool# 强制立即触发扩缩容检查通过重启 KEDA operatorkubectl rollout restart deploy/keda-operator-nkeda# 临时暂停 ScaledObject不影响工作负载只暂停 KEDA 管理kubectl patch scaledobject kafka-consumer-scaler-ndefault\--typemerge\-p{metadata:{annotations:{autoscaling.keda.sh/paused-replicas:2}}}# 恢复 ScaledObjectkubectl patch scaledobject kafka-consumer-scaler-ndefault\--typemerge\-p{metadata:{annotations:{autoscaling.keda.sh/paused-replicas:null}}}KEDA 将 Kubernetes 的弹性扩缩容能力提升到了一个全新的维度。通过与 Kafka、Redis、Prometheus 等生产级事件源的深度集成以及独特的缩零能力KEDA 在显著提升系统弹性的同时大幅降低了空闲资源的浪费。无论是高并发消息处理、批量数据处理还是业务流量的波峰波谷应对KEDA 都能给出优雅的解决方案。