跳到主要内容

KEDA 实战:基于消息队列的事件驱动伸缩

这篇想达成的效果

  • 在集群里装好 KEDA,不改业务代码也能按事件伸缩。
  • 用 RabbitMQ 队列长度触发 HPA 扩容,再用 Cron 定时收缩。
  • 实际验证扩缩是否发生,并给出常见故障排查。

安装 KEDA(Helm)

kubectl create namespace keda --dry-run=client -o yaml | kubectl apply -f -
helm repo add kedacore https://kedacore.github.io/charts
helm repo update
helm upgrade --install keda kedacore/keda --namespace keda
kubectl -n keda get pods

默认会安装 keda-operator 和 metrics API(keda-metrics-apiserver)。

准备一个演示应用和 RabbitMQ

  1. 部署 RabbitMQ(简单版):
kubectl create namespace autoscale-demo --dry-run=client -o yaml | kubectl apply -f -
helm repo add bitnami https://charts.bitnami.com/bitnami
helm upgrade --install rabbitmq bitnami/rabbitmq \
--namespace autoscale-demo \
--set auth.username=user --set auth.password=pass \
--set auth.erlangCookie=secretcookie
kubectl -n autoscale-demo get svc rabbitmq
  1. 部署一个消费队列的 Worker(会打印消息):
apiVersion: apps/v1
kind: Deployment
metadata:
name: queue-worker
namespace: autoscale-demo
spec:
replicas: 1
selector:
matchLabels:
app: queue-worker
template:
metadata:
labels:
app: queue-worker
spec:
containers:
- name: worker
image: ghcr.io/kedacore/sample-queue-worker:latest
env:
- name: RABBITMQ_HOST
value: rabbitmq.autoscale-demo.svc
- name: RABBITMQ_USER
value: user
- name: RABBITMQ_PASSWORD
value: pass
- name: RABBITMQ_QUEUE
value: demo
kubectl apply -f queue-worker.yaml
kubectl -n autoscale-demo get deploy queue-worker

创建 ScaledObject(按队列长度伸缩)

apiVersion: keda.sh/v1alpha1
kind: ScaledObject
metadata:
name: queue-worker-so
namespace: autoscale-demo
spec:
scaleTargetRef:
name: queue-worker
minReplicaCount: 1
maxReplicaCount: 5
triggers:
- type: rabbitmq
metadata:
host: "amqp://user:pass@rabbitmq.autoscale-demo.svc:5672/"
queueName: demo
queueLength: "10" # 队列消息 >=10 时开始扩容
kubectl apply -f scaledobject.yaml
kubectl -n autoscale-demo get scaledobject

投递消息并观察扩缩容

  1. 投递 100 条消息:
kubectl -n autoscale-demo exec deploy/rabbitmq -- bash -c \
"for i in $(seq 1 100); do echo msg$i | rabbitmqadmin --host=localhost --username=user --password=pass publish routing_key=demo payload=msg$i; done"

如 rabbitmqadmin 未安装,可进入 Pod kubectl exec -it statefulset/rabbitmq ... 安装,或用 curl 调用管理 API。

  1. 观察副本变化:
kubectl -n autoscale-demo get hpa,deploy queue-worker -w

应看到 HPA(由 KEDA 管理)把副本扩到队列消化完毕,然后回落到 1。

Cron 定时伸缩示例(可选)

apiVersion: keda.sh/v1alpha1
kind: ScaledObject
metadata:
name: queue-worker-cron
namespace: autoscale-demo
spec:
scaleTargetRef:
name: queue-worker
minReplicaCount: 0
maxReplicaCount: 3
triggers:
- type: cron
metadata:
timezone: Asia/Shanghai
start: 0 9 * * * # 每天 09:00 扩到3个
end: 0 18 * * * # 每天 18:00 缩回min
desiredReplicas: "3"

应用后在 09:00~18:00 之间自动拉起副本。

排障清单

  • HPA 不扩:kubectl get hpa -A 看是否有 keda- 前缀;查看 keda-operator 日志是否报 Metric 无法获取。
  • 无法连接 RabbitMQ:确认 host 字段用户名密码正确,Service 名称是否能解析;在 Worker Pod 里 telnet rabbitmq 5672 验证连通性。
  • 队列长度不更新:RabbitMQ 管理接口权限不足,或 queueName 不存在;用 rabbitmqadmin list queues name messages 核实。
  • Cron 没生效:检查时区字段,观察 keda-operator 日志;确认时间达标时是否创建了临时 HPA。

生产落地要点

  • 给 KEDA 自身和 HPA 目标设置明确的 min/max,避免抖动;结合 PDB 确保扩缩容时服务可用。
  • RabbitMQ/Redis/Kafka 等触发源建议使用 TLS/鉴权,避免明文凭证;凭证放 Secret,通过 authRef 引用。
  • 高并发场景建议配合 Cluster Autoscaler,避免扩 Pod 时节点不够。
  • 审计:关注 keda-operator、metrics-apiserver 日志,遇到无法取指标时及时告警。

总结

把 KEDA 装上再加一个 ScaledObject,你就能根据队列、Cron 或其他几十种触发器让 Deployment 自动伸缩。上面的命令可以在真实集群里跑一遍,确认队列涨时副本跟着升,消息消化完又自动回落。之后你可以换成自己的触发源,把凭证收紧,和 CA/HPA 配套用在生产环境。