Jor*_*dan 3 amazon-ec2 amazon-web-services amazon-ecs autoscaling terraform
我有一个相当有趣的情况,我正在尝试弄清楚如何在 AWS ECS/EC2 上进行配置。
我有一个 Dockerized 应用程序,具有以下要求:
由于成本原因,Fargate 不是一个选择,因此我们正在考虑基于 EC2 的解决方案。
由于 CPU 和内存使用率较低,并且我需要为每个容器提供唯一的公共 IP 地址,因此 ECS 容量提供商的最佳选择似乎是使用最小实例( 、 等)的 EC2 自动缩放组t4g.nano,t3a.nano并且或host网络bridge模式(如果我明确指定静态主机/容器端口映射,则任一模式都将限制为每个主机一个容器)。这为我提供了主机到容器的一对一映射,这正是我所需要的。
问题是,如何为此设置 ECS 集群管理的自动缩放?
我已经配置了 EC2 自动缩放组 (Terraform):
resource "aws_autoscaling_group" "ecs" {
name = "ecs"
vpc_zone_identifier = var.subnet_ids
min_size = 1
max_size = 20
capacity_rebalance = true
default_cooldown = 0
health_check_type = "EC2"
mixed_instances_policy {
...
}
instance_refresh {
strategy = "Rolling"
}
}
Run Code Online (Sandbox Code Playgroud)
我已将自动扩展组配置为具有托管扩展功能的 ECS 容量提供商:
resource "aws_ecs_capacity_provider" "ec2" {
name = "ec2"
auto_scaling_group_provider {
auto_scaling_group_arn = aws_autoscaling_group.ecs.arn
managed_scaling {
target_capacity = 100
instance_warmup_period = 30
minimum_scaling_step_size = 1
maximum_scaling_step_size = aws_autoscaling_group.ecs.max_size
status = "ENABLED"
}
managed_termination_protection = "DISABLED"
}
}
Run Code Online (Sandbox Code Playgroud)
我已将此容量提供程序配置为 ECS 集群的唯一提供程序:
resource "aws_ecs_cluster_capacity_providers" "this" {
cluster_name = aws_ecs_cluster.this.name
capacity_providers = [
aws_ecs_capacity_provider.ec2.name
]
default_capacity_provider_strategy {
capacity_provider = aws_ecs_capacity_provider.ec2.name
weight = 100
base = 0
}
}
Run Code Online (Sandbox Code Playgroud)
我已经设置了 ECS 服务:
resource "aws_ecs_service" "this" {
name = local.task_family
cluster = aws_ecs_cluster.this.id
task_definition = aws_ecs_task_definition.this.arn
desired_count = 1
launch_type = "EC2"
lifecycle {
ignore_changes = [desired_count]
}
}
Run Code Online (Sandbox Code Playgroud)
我已经为 ECS 服务设置了应用程序自动缩放目标:
resource "aws_appautoscaling_target" "ecs" {
min_capacity = 5
max_capacity = 20
resource_id = "service/${aws_ecs_cluster.this.name}/${aws_ecs_service.this.name}"
scalable_dimension = "ecs:service:DesiredCount"
service_namespace = "ecs"
}
Run Code Online (Sandbox Code Playgroud)
我已经为该目标设置了应用程序自动缩放策略:
resource "aws_appautoscaling_policy" "ecs_policy" {
name = "ecs-scaling"
policy_type = "TargetTrackingScaling"
resource_id = aws_appautoscaling_target.ecs.resource_id
scalable_dimension = aws_appautoscaling_target.ecs.scalable_dimension
service_namespace = aws_appautoscaling_target.ecs.service_namespace
target_tracking_scaling_policy_configuration {
target_value = 70
scale_in_cooldown = 0
scale_out_cooldown = 0
predefined_metric_specification {
predefined_metric_type = "ECSServiceAverageCPUUtilization"
}
}
}
Run Code Online (Sandbox Code Playgroud)
这“有效”是指它已部署、服务正在运行并且我的应用程序可以正常运行。但是,缩放不起作用。正如您在 中所看到的aws_autoscaling_group,我已将最小值设置为 1 个实例,将最大值设置为 20 个实例。在 中aws_appautoscaling_target,我最少有 5 个(在生产中为 1 个,但在测试中为 5 个),最多为 20 个(最大值与最大实例数匹配,因为它是 1 对 1)。
当我部署此服务时,AWS 控制台中的 ECS 服务显示:
在事件日志中,它说:
服务 my-service 无法放置任务,因为没有容器实例满足其所有要求。最接近的匹配容器实例 xyzabc1234 没有足够的可用内存。
因此,它正在尝试实现所需的最小容器数量 (5),并且它认识到 EC2 实例不足,但由于某种原因(这是我无法弄清楚的原因),它没有扩展 EC2 实例的数量以满足所需的集装箱数量。
从AWS 的文档来看,它说:
当启动的任务无法放置在可用实例上时,Auto Scaling 组会通过启动新实例进行横向扩展。当存在正在运行但没有任务的实例时,Auto Scaling 组会通过终止没有正在运行的任务的实例来进行缩减。
由于启动的任务不能放置在任何可用实例上,因此它似乎应该自动扩展 Auto Scaling 组。
关于为什么它失败的任何想法?
我发现了这个问题:
resource "aws_ecs_service" "this" {
...
launch_type = "EC2"
...
}
Run Code Online (Sandbox Code Playgroud)
如果您指定启动类型,它将覆盖集群的默认容量提供程序策略,并且不会使用托管 EC2 自动扩展。正确的做法是:
resource "aws_ecs_service" "this" {
name = local.task_family
cluster = aws_ecs_cluster.this.id
task_definition = aws_ecs_task_definition.this.arn
desired_count = 1
capacity_provider_strategy {
capacity_provider = aws_ecs_capacity_provider.ec2.name
weight = 100
base = 0
}
lifecycle {
ignore_changes = [desired_count]
}
}
Run Code Online (Sandbox Code Playgroud)
如果您不提供launch_typeor capacity_provider_strategy,它应该使用集群的默认策略(确实如此),但 Terraform 显示出永久的差异。
进行此更改后,一切都开始正常扩展!
| 归档时间: |
|
| 查看次数: |
1186 次 |
| 最近记录: |