![](/img/trans.png)
[英]How to run a simple Docker container when an EC2 is launched in an AWS auto-scaling group?
[英]AWS ECS: Auto-Scaling an EC2 Auto-Scaling Group with Single-Container Hosts
我有一個相當有趣的情況,我試圖弄清楚如何在 AWS ECS/EC2 上進行配置。
我有一個具有以下要求的 Dockerized 應用程序:
由於成本原因,Fargate 不是一個選項,因此我們正在尋找基於 EC2 的解決方案。
由於 CPU 和內存使用率很低,並且我需要為每個容器提供唯一的公共 IP 地址,因此 ECS 容量提供者的最佳選擇似乎是使用最小實例( t4g.nano
、 t3a.nano
)的 EC2 自動擴展組等),以及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"
}
}
我已將自動擴展組配置為具有托管擴展的 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"
}
}
我已將此容量提供程序配置為 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
}
}
我已經設置了 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]
}
}
我為 ECS 服務設置了 App Autoscaling Target:
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"
}
我已經為該目標設置了應用程序自動縮放策略:
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"
}
}
}
這在它部署、服務運行以及我的應用程序正常運行的意義上是“有效的”。 但是,縮放不起作用。 正如您在aws_autoscaling_group
中看到的,我已將最小值設置為 1 個實例,將最大值設置為 20 個實例。 在aws_appautoscaling_target
中,我至少有 5 個(在生產中為 1,但在測試中為 5)和最多 20 個(最大值與最大實例數匹配,因為它是一對一的)。
當我部署它時,AWS 控制台中的 ECS 服務顯示:
在事件日志中,它說:
service my-service 無法放置任務,因為沒有容器實例滿足其所有要求。 最接近的匹配容器實例 xyzabc1234 的可用內存不足。
因此,它試圖實現所需的最小容器數量(5),並且它認識到 EC2 實例不足,但由於某種原因(這是我無法弄清楚的),它並沒有擴展 EC2 實例的數量以滿足所需的容器數量。
從AWS 的文檔中,它說:
當啟動的任務無法放置在可用實例上時,Auto Scaling 組會通過啟動新實例進行橫向擴展。 當有正在運行的實例沒有任務時,Auto Scaling 組通過終止沒有正在運行的任務的實例來縮減。
由於啟動的任務不能放在任何可用的實例上,它似乎應該自動擴展 Auto Scaling 組。
關於為什么它沒有這樣做的任何想法?
我發現了問題:
resource "aws_ecs_service" "this" {
...
launch_type = "EC2"
...
}
如果您指定啟動類型,它將覆蓋集群的默認容量提供程序策略,並且不會使用托管 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]
}
}
如果您不提供launch_type
或capacity_provider_strategy
,它應該使用集群的默認策略(確實如此),但 Terraform 顯示出永久的差異。
在此更改之后,一切都開始正常縮放!
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.