如何在ECS集群内存不足时通过AWS CloudFormation实现实例自动扩缩容
具备内存驱动自动扩缩容的ECS服务&任务CloudFormation模板
我最近写了个CloudFormation模板,能一站式创建ECS任务定义、服务,还自带基于*内存使用率(MemoryUtilization)*的自动扩缩容功能——简单说就是当任务的内存使用率触发设定阈值时自动加1个任务,使用率降下来就减1个,省得手动调整资源。
先给大家看看核心的任务定义部分:
EcsTd: Type: AWS::ECS::TaskDefinition DependsOn: LogGroup Properties: Family: !Sub ${EnvironmentName}-${PlatformName}-${Type} ContainerDefinitions: - Name: !Sub ${EnvironmentName}-${PlatformName}-${Type} Image: !Sub ${AWS::AccountId}.dkr.ecr.${AWS::Region}.amazonaws.com/your-repo:your-tag # 可根据业务需求补充容器配置:资源限制、端口映射、环境变量等 MemoryReservation: 512 # 示例内存预留值,按需调整 LogConfiguration: LogDriver: awslogs Options: awslogs-group: !Ref LogGroup awslogs-region: !Ref AWS::Region awslogs-stream-prefix: ecs
任务定义关键细节说明
- 命名规范:任务家族(Family)和容器名称都用
EnvironmentName、PlatformName、Type三个参数拼接,不管是测试还是生产环境,都能轻松区分不同ECS任务,排查问题更高效 - 依赖控制:通过
DependsOn确保日志组(LogGroup)先创建完成,避免容器启动时因找不到日志组报错 - 日志关联:绑定到指定CloudWatch Log Group,方便后续查看容器日志、配置监控告警
自动扩缩容核心配置
要实现内存驱动的扩缩容,还得配上ECS服务的自动扩缩容目标和策略,这是模板里的核心逻辑:
# ECS服务自动扩缩容目标 EcsServiceScalingTarget: Type: AWS::ApplicationAutoScaling::ScalableTarget DependsOn: EcsService Properties: MaxCapacity: 10 # 最大任务数,按需调整 MinCapacity: 1 # 最小任务数 ResourceId: !Sub service/${EcsCluster}/${EcsService.Name} ScalableDimension: ecs:service:DesiredCount ServiceNamespace: ecs # 内存使用率过高时的扩容策略 EcsServiceScaleOutPolicy: Type: AWS::ApplicationAutoScaling::ScalingPolicy Properties: PolicyName: !Sub ${EnvironmentName}-${PlatformName}-scale-out PolicyType: StepScaling ScalingTargetId: !Ref EcsServiceScalingTarget StepScalingPolicyConfiguration: AdjustmentType: ChangeInCapacity Cooldown: 60 # 冷却时间,避免频繁扩缩容 MetricAggregationType: Average StepAdjustments: - MetricIntervalLowerBound: 0 ScalingAdjustment: 1 # 内存使用率达标时,增加1个任务 # 内存使用率过低时的缩容策略 EcsServiceScaleInPolicy: Type: AWS::ApplicationAutoScaling::ScalingPolicy Properties: PolicyName: !Sub ${EnvironmentName}-${PlatformName}-scale-in PolicyType: StepScaling ScalingTargetId: !Ref EcsServiceScalingTarget StepScalingPolicyConfiguration: AdjustmentType: ChangeInCapacity Cooldown: 60 MetricAggregationType: Average StepAdjustments: - MetricIntervalUpperBound: 0 ScalingAdjustment: -1 # 内存使用率低于阈值时,减少1个任务 # 内存使用率告警规则(触发扩容) MemoryHighAlarm: Type: AWS::CloudWatch::Alarm Properties: AlarmName: !Sub ${EnvironmentName}-${PlatformName}-memory-high AlarmDescription: Trigger scale out when MemoryUtilization exceeds threshold Namespace: AWS/ECS MetricName: MemoryUtilization Dimensions: - Name: ClusterName Value: !Ref EcsCluster - Name: ServiceName Value: !Ref EcsService.Name Statistic: Average Period: 60 EvaluationPeriods: 2 Threshold: 70 # 内存使用率阈值,示例为超过70%触发扩容 ComparisonOperator: GreaterThanThreshold AlarmActions: - !Ref EcsServiceScaleOutPolicy # 内存使用率告警规则(触发缩容) MemoryLowAlarm: Type: AWS::CloudWatch::Alarm Properties: AlarmName: !Sub ${EnvironmentName}-${PlatformName}-memory-low AlarmDescription: Trigger scale in when MemoryUtilization is below threshold Namespace: AWS/ECS MetricName: MemoryUtilization Dimensions: - Name: ClusterName Value: !Ref EcsCluster - Name: ServiceName Value: !Ref EcsService.Name Statistic: Average Period: 60 EvaluationPeriods: 2 Threshold: 30 # 内存使用率阈值,示例为低于30%触发缩容 ComparisonOperator: LessThanThreshold AlarmActions: - !Ref EcsServiceScaleInPolicy
扩缩容逻辑说明
- 当ECS任务的平均内存使用率连续2分钟超过70%时,CloudWatch告警会触发扩容策略,自动增加1个任务
- 当平均内存使用率连续2分钟低于30%时,触发缩容策略,减少1个任务
- 冷却时间设为60秒,防止短时间内频繁调整任务数量,避免资源不必要的波动
内容的提问来源于stack exchange,提问作者Kārlis Janisels
相关产品推荐
相关产品推荐

