簡體   English   中英

AWS ECS:使用單容器主機自動擴展 EC2 自動擴展組

[英]AWS ECS: Auto-Scaling an EC2 Auto-Scaling Group with Single-Container Hosts

我有一個相當有趣的情況,我試圖弄清楚如何在 AWS ECS/EC2 上進行配置。

我有一個具有以下要求的 Dockerized 應用程序:

  • 非常低的 CPU 使用率(~256 CPU)
  • 中等內存使用(~256 MB)
  • 每個容器都需要一個僅分配給該容器的公共 IP 地址(它不與任何其他容器共享)。

由於成本原因,Fargate 不是一個選項,因此我們正在尋找基於 EC2 的解決方案。

由於 CPU 和內存使用率很低,並且我需要為每個容器提供唯一的公共 IP 地址,因此 ECS 容量提供者的最佳選擇似乎是使用最小實例( t4g.nanot3a.nano )的 EC2 自動擴展組等),以及hostbridge網絡模式(如果我明確指定靜態主機/容器端口映射,則任何一種模式都將限制為每個主機一個容器)。 這為我提供了主機到容器的一對一映射,這正是我所需要的。

問題是,如何為此設置 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 服務顯示:

  • 所需數量:5
  • 待定計數:0
  • 運行次數:1

在事件日志中,它說:

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_typecapacity_provider_strategy ,它應該使用集群的默認策略(確實如此),但 Terraform 顯示出永久的差異。

在此更改之后,一切都開始正常縮放!

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM