cod*_*ark 9 amazon-ec2 amazon-web-services amazon-ecs autoscaling amazon-ecr
我最近开始使用ECS.我能够在ECR中部署容器映像,并为具有CPU /内存限制的容器创建任务定义.我的用例是每个容器都是一个长期运行的应用程序(没有网络服务器,不需要端口映射).容器将按需一次生成,并一次按需删除1.
我能够创建一个包含N个服务器实例的集群.但我希望服务器实例能够自动向上/向下扩展.例如,如果群集中没有足够的CPU /内存,我想要创建一个新实例.
如果有一个实例没有运行容器,我希望缩小/删除该特定实例.这是为了避免在其中运行任务的服务器实例自动缩小终止.
需要哪些步骤才能实现这一目标?
考虑到您已经创建了 ECS 集群,AWS 提供了有关使用 CloudWatch 警报扩展集群实例的说明。
假设您想根据内存预留扩展集群,在较高级别上,您需要执行以下操作:
因为它更像是我的专长,所以我编写了一个示例CloudFormation模板,它应该可以帮助您开始大部分工作:
Parameters:
MinInstances:
Type: Number
MaxInstances:
Type: Number
InstanceType:
Type: String
AllowedValues:
- t2.nano
- t2.micro
- t2.small
- t2.medium
- t2.large
VpcSubnetIds:
Type: String
Mappings:
EcsInstanceAmis:
us-east-2:
Ami: ami-1c002379
us-east-1:
Ami: ami-9eb4b1e5
us-west-2:
Ami: ami-1d668865
us-west-1:
Ami: ami-4a2c192a
eu-west-2:
Ami: ami-cb1101af
eu-west-1:
Ami: ami-8fcc32f6
eu-central-1:
Ami: ami-0460cb6b
ap-northeast-1:
Ami: ami-b743bed1
ap-southeast-2:
Ami: ami-c1a6bda2
ap-southeast-1:
Ami: ami-9d1f7efe
ca-central-1:
Ami: ami-b677c9d2
Resources:
Cluster:
Type: AWS::ECS::Cluster
Role:
Type: AWS::IAM::Role
Properties:
ManagedPolicyArns:
- arn:aws:iam::aws:policy/service-role/AmazonEC2ContainerServiceforEC2Role
AssumeRolePolicyDocument:
Version: 2012-10-17
Statement:
-
Effect: Allow
Action:
- sts:AssumeRole
Principal:
Service:
- ec2.amazonaws.com
InstanceProfile:
Type: AWS::IAM::InstanceProfile
Properties:
Path: /
Roles:
- !Ref Role
LaunchConfiguration:
Type: AWS::AutoScaling::LaunchConfiguration
Properties:
ImageId: !FindInMap [EcsInstanceAmis, !Ref "AWS::Region", Ami]
InstanceType: !Ref InstanceType
IamInstanceProfile: !Ref InstanceProfile
UserData:
Fn::Base64: !Sub |
#!/bin/bash
echo ECS_CLUSTER=${Cluster} >> /etc/ecs/ecs.config
AutoScalingGroup:
Type: AWS::AutoScaling::AutoScalingGroup
Properties:
MinSize: !Ref MinInstances
MaxSize: !Ref MaxInstances
LaunchConfigurationName: !Ref LaunchConfiguration
HealthCheckGracePeriod: 300
HealthCheckType: EC2
VPCZoneIdentifier: !Split [",", !Ref VpcSubnetIds]
ScaleUpPolicy:
Type: AWS::AutoScaling::ScalingPolicy
Properties:
AdjustmentType: ChangeInCapacity
AutoScalingGroupName: !Ref AutoScalingGroup
Cooldown: '1'
ScalingAdjustment: '1'
MemoryReservationAlarmHigh:
Type: AWS::CloudWatch::Alarm
Properties:
EvaluationPeriods: '2'
Statistic: Average
Threshold: '70'
AlarmDescription: Alarm if Cluster Memory Reservation is to high
Period: '60'
AlarmActions:
- Ref: ScaleUpPolicy
Namespace: AWS/ECS
Dimensions:
- Name: ClusterName
Value: !Ref Cluster
ComparisonOperator: GreaterThanThreshold
MetricName: MemoryReservation
ScaleDownPolicy:
Type: AWS::AutoScaling::ScalingPolicy
Properties:
AdjustmentType: ChangeInCapacity
AutoScalingGroupName: !Ref AutoScalingGroup
Cooldown: '1'
ScalingAdjustment: '-1'
MemoryReservationAlarmLow:
Type: AWS::CloudWatch::Alarm
Properties:
EvaluationPeriods: '2'
Statistic: Average
Threshold: '30'
AlarmDescription: Alarm if Cluster Memory Reservation is to Low
Period: '60'
AlarmActions:
- Ref: ScaleDownPolicy
Namespace: AWS/ECS
Dimensions:
- Name: ClusterName
Value: !Ref Cluster
ComparisonOperator: LessThanThreshold
MetricName: MemoryReservation
Run Code Online (Sandbox Code Playgroud)
这将创建一个 ECS 集群、一个启动配置、一个 AutoScaling 组以及基于 ECS 内存预留的警报。
现在我们可以开始有趣的讨论了。
为什么我们不能根据 CPU 利用率和内存预留进行纵向扩展?
简短的回答是你完全可以,但你可能会为此付出很多。EC2 有一个已知属性,即在您创建实例时,您至少需要支付 1 小时的费用,因为部分实例小时数按完整小时数收费。为什么这是相关的,假设您有多个警报。假设您有一堆当前处于空闲状态的服务,并且您填满了集群。CPU 警报会缩小集群规模,或者内存警报会扩大集群规模。其中之一可能会将集群扩展到不再触发警报的程度。冷却时间结束后,另一个警报将撤消其上一次操作,下一次冷却后,该操作可能会重做。因此,实例被创建然后在每隔一个冷却时间重复销毁。
想了想,我想到的策略是基于CPU利用率的ECS服务应用自动伸缩,基于集群的内存预留。因此,如果一项服务正在运行,则会添加一个额外的任务来分担负载。这将慢慢填满集群内存预留容量。当内存已满时,集群会向上扩展。当服务冷却时,服务将开始关闭任务。随着集群上的内存预留下降,集群将缩小。
根据您的任务定义,可能需要试验 CloudWatch 警报的阈值。这样做的原因是,如果你把向上扩展的阈值设置得太高,它可能不会随着内存的消耗而向上扩展,然后当自动缩放去放置另一个任务时,它会发现任何一个都没有足够的可用内存实例在集群中,因此无法放置另一个任务。
| 归档时间: |
|
| 查看次数: |
3314 次 |
| 最近记录: |