如何在AWS EKS中基于自定义CloudWatch指标实现阶梯式副本扩缩容
Kubernetes 原生HPA做不到你要的这种固定区间对应固定副本数的阶梯扩缩。原生HPA的逻辑是拿当前指标值和你设的目标值按比例算副本数,就算你调扩缩步长、冷却时间这些参数,也没法实现这种一一对应的硬映射规则。你完全不用自己写轮询组件,有两个生产级现成方案可以直接用:
你需要实现的扩缩规则如下:
if 0 < sqs_message_count < 15: set replicas: 1 if 15 <= sqs_message_count < 32: set replicas: 2 if 32 <= sqs_message_count < 53: set replicas: 4 if 53 <= sqs_message_count < 105: set replicas: 7 if 105 <= sqs_message_count < 178: set replicas: 11 if 178 <= sqs_message_count < 371: set replicas: 14 if sqs_message_count => 371: set replicas: 16
方案1:用KEDA(最灵活,集群内原生体验)
KEDA是CNCF毕业的成熟扩缩容组件,专门做事件驱动场景的工作负载扩缩,是这类场景的首选:
- 它自带AWS SQS的触发器,不用你自己写代码拉SQS消息数,也不用额外部署CloudWatch指标适配器,只要给KEDA用的服务账号配SQS读权限、必要的CloudWatch读权限就行
- 两种方式可以完美匹配你的阶梯规则:
- 简单配置的话,直接在ScaledObject的HPA行为配置里写阶梯策略,把你列的消息数区间和对应副本数的调整规则填进去就行
- 要100%严格匹配规则的话,可以用内置的表达式能力直接做区间判断,返回对应目标副本数,让HPA按1:1的目标值扩缩,完全不会出现偏差
- 基础配置骨架参考:
apiVersion: keda.sh/v1alpha1 kind: ScaledObject metadata: name: sqs-consumer-scaler spec: scaleTargetRef: name: 你的SQS消费者工作负载名 minReplicaCount: 1 maxReplicaCount: 16 triggers: - type: aws-sqs-queue metadata: queueURL: "你的SQS队列完整URL" awsRegion: "集群所在AWS区域,比如us-east-1" advanced: horizontalPodAutoscalerConfig: behavior: scaleUp: stabilizationWindowSeconds: 30 policies: - type: Pods value: 2 periodSeconds: 30 scaleDown: stabilizationWindowSeconds: 300
方案2:用AWS Application Auto Scaling(不用装集群组件)
如果你不想在EKS集群里部署第三方开源组件,可以直接用AWS托管的Application Auto Scaling服务:
- 这个服务原生支持阶梯扩缩策略(Step Scaling),本来就是为这种固定区间对应固定扩缩动作的场景设计的,你可以直接把列出的7条消息数区间规则一条条配进去,完全不用写代码
- 配置流程很简单:先把你的EKS工作负载注册到Application Auto Scaling,给服务配好对应EKS的扩缩权限,然后对接CloudWatch里的SQS
ApproximateNumberOfMessages指标,给每个区间绑定对应的副本数调整动作就行 - 所有扩缩逻辑全托管在AWS侧,不用你维护集群内的组件,稳定性有保障
避坑提醒
别用原生HPA加CloudWatch指标适配器的方案,这个组合还是走HPA的比例计算逻辑,你调再细的参数也没法精确匹配你列的固定副本数规则,折腾半天还是会出现不符合预期的副本数,没必要浪费时间。自己写轮询组件更没必要,上面两个方案都是各大厂生产环境跑了很多年的方案,配置工作量最多半天,比自己开发维护组件成本低太多。
内容的提问来源于stack exchange,提问作者Kaustubh Desai
相关产品推荐
相关产品推荐

