iT邦幫忙

2023 iThome 鐵人賽

DAY 29
0

到目前為止我們都是手動調整 ASG 的 desired capacity 來調整 container instance 的數量,今天要來介紹會根據 ECS service task 數量以及 container instance 的使用情形動態調整 container instance 數量的功能——ECS Cluster Auto Scaling。(本日程式碼

ECS Capacity Provider

ECS capacity provider 管理 ECS cluster 中 infrastructure 的 scaling,以 EC2 instance 執行 task 來說就是 ECS cluster 裡有多少 EC2 instance。一個 cluster 可以有一到多個 capacity provider,task 如何分配給各 capacity provider 則由 capacity provider strategy 決定。

ECS Cluster Auto Scaling

ECS 可以管理向它註冊的 EC2 instance 們的 scaling,這稱為 ECS cluster auto scaling。ECS cluster auto scaling 由開啟 managed scaling 功能的 ECS Auto Scaling group capacity provider 達成。

auto scaling group capacity provider 會在 cloudwatch 產生兩個 metrics(指標)跟一個 attach 到 auto scaling group 的 target tracking policy。ECS 依據這兩個 metric 跟 policy 決定要 scale-in(減少 instance)、scale-out(增加 instance)或者不需要動作。

兩個 metric 分別是:

  1. CapacityProviderReservation
    某個 capacity provider 的 instance 中被 ECS task 使用的比例,如果每個 instance 都有 task 在上面 run(不管幾個 task),這個值就是 100。如果有 1 台 instance 沒有 task、這個 capacity provider 總共有 5 台 instance,值就是 4 / 5 * 100 = 80

  2. DesiredCapacity
    auto scaling group 的 capacity 數量。

ECS 會每分鐘收集資訊來決定 auto scaling group 是否需要 scale in 或 scale out。當啟動的 task 沒有 available instance 可以放的時候(可能是 CPU 或 memory 不夠),ECS 就會要 ASG 開更多 instance(scale out)。反之,當 instance 身上都沒有 task 的時候,ECS 會關掉沒有 task 在 run 的 instance(scale in)。

決定是否要 scale in/out 的資訊是 CapacityProviderReservation 與 target capacity 的值的關係。target capacity 的值是希望 CapacityProviderReservation 達到的值,通常設為 100,所以 CapacityProviderReservation 有以下三種情況:

  • CapacityProviderReservation == 100:ASG 不需要 scale in/out,因為所有 instance 都有 task 在使用。

  • CapacityProviderReservation > 100:目前沒有 available instance 給新開的 task 使用,這時候 ASG 要 scale out。CapacityProviderReservation metric 會產生一個 cloudwatch alarm,這個 alarm 會增加 auto scaling group 的 DesiredCapacity ,接著 auto scaling group 就會依據 DesiredCapacity 的值去開啟新的 instance 並且 register 到 ECS cluster。

  • CapacityProviderReservation < 100:表示至少有一台 instance 是沒有 running task 的,這時候可以 scale in auto scaling group。CapacityProviderReservation metric 會產生一個 cloudwatch alarm 去減少 DesiredCapacity ,之後 ASG 一樣依據這個值來從 ECS cluster deregister 沒有在使用的 instance 並且 terminate instance。

ECS auto scaling 只會修改 EC2 auto scaling group 的 desired capacity,不會動 max capacity 跟 min capacity,所以我們可以用 max 跟 min capacity 限制 EC2 instance 的數量。

這就是 ECS cluster auto scaling 的運作方式~

實際操作觀察

知道運作過程後,我們來實際玩(?)一下。一開始用網頁介面建立 ECS cluster 的時候,就已經建好 ECS capacity provider,只是……前面忘記 import 了😅 ,補一下 import:

import {
    id = "Infra-ECS-Cluster-my-app-431cf07b-EC2CapacityProvider-ctTJPXlEGS2v"
    to = aws_ecs_capacity_provider.cp
}

import {
    id = "my-app"
    to = aws_ecs_cluster_capacity_providers.cp
}

這兩個 import block 產生的 resource aws_ecs_capacity_provideraws_ecs_cluster_capacity_providers

resource "aws_ecs_capacity_provider" "cp" {
  name     = "Infra-ECS-Cluster-my-app-431cf07b-EC2CapacityProvider-ctTJPXlEGS2v"
  tags     = {}
  tags_all = {}
  auto_scaling_group_provider {
    auto_scaling_group_arn         = aws_autoscaling_group.asg.arn
    managed_termination_protection = "DISABLED"
    managed_scaling {
      instance_warmup_period    = 300
      maximum_scaling_step_size = 10000
      minimum_scaling_step_size = 1
      status                    = "ENABLED"
      target_capacity           = 100
    }
  }
}

resource "aws_ecs_cluster_capacity_providers" "cp" {
  capacity_providers = ["FARGATE", "FARGATE_SPOT", aws_ecs_capacity_provider.cp.name]
  cluster_name       = aws_ecs_cluster.cluster.name
  default_capacity_provider_strategy {
    base              = 0
    capacity_provider = aws_ecs_capacity_provider.cp.name
    weight            = 1
  }
}

雖然 ECS cluster 有建立 capacity provider,但是 ECS service 沒有設定它要使用的 capacity provider、而是用 EC2 launch type(在 Day 9)。現在要讓 auto scaling 有做用要幫 resource

aws_ecs_service.service 補上 capacity provider:

capacity_provider_strategy {
  capacity_provider = aws_ecs_capacity_provider.cp.name
  weight            = 1
}

並且刪掉 launch_type = "EC2"

apply resource 後,把 auto scaling group 的 max capacity 調成 3 但是不動 desired count(維持 0),再把 ECS service 的 task count 調成 2。

接下來觀察 ECS task 跟 cloudwatch alarm,ECS task 會先進入 Provisioning 狀態:

https://ithelp.ithome.com.tw/upload/images/20231009/20160671NWlPpZ01pl.png

在 Cloudwatch 會有兩個 alarm,分別是在 CapacityProviderReservation 在 15 分鐘內一直小於 100 的 scale in alarm,以及 1 分鐘內大於 100 的 scale out alarm:

https://ithelp.ithome.com.tw/upload/images/20231009/20160671xvsCCA0m4L.png

因為我們是增加要執行的 task 數量,所以過一下子 scale out 的 alarm 就會進入 alarm 狀態:

https://ithelp.ithome.com.tw/upload/images/20231009/20160671HP9oytQpBe.png

這個 alarm 的 action 會去調整 auto scaling group 的 desired count,在 CapacityProviderReservation > 100 的狀況下,ASG 的 desired count 會被調高,後續動作就跟我們手動調整一樣:EC2 instance 啟動並 register 進 ECS cluster,ECS task 開始在 EC2 instance 上執行。

以上就是 scale out 的運作過程,各位可以試試看減少 desired task 的數量,container instance 出現 running task 為 0 的情況,觀察 scale in 的運作~


上一篇
Day 28 CDN cache 與 CodePipeline 清 cache
下一篇
Day 30 ECS Service Auto Scaling
系列文
AWS ECS + Gitlab + Laravel + Terraform 從入門到摔坑30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言