Posted at

【小ネタ】FargateのAutoScallingをスケジュールベースで動かす方法

現状、ECSのFargateタイプのAutoScallingは下記タイプをサポートしており、スケジュールベースのスケールには対応していない。


  • CPU

  • Memory

  • ALBのリクエスト数

  • CloudWatchアラーム

せっかくFargateになりEC2の存在を気にせずにスケール出来るようになったので、ピークタイムにはコンテナ増やすみたいな事例に対応するためにちょっと検証してみた。


必要なもの

CloudWatchEventsでcronベースのイベントをトリガに、Lambdaを起動してFargateタイプで動くECSのサービス内のタスク数を増減させる形


  • ECS Serviceの更新をするlambda

  • lambdaを実行するための、IAMロール

  • lambdaを定期実行するCloudWatchEventsのイベント


ECS Serviceの更新をするlambda


  • boto3を使って、serviceのdesiredCountを増減させるコード

  • スケールアウト用とスケールイン用の2つを用意(desiredCountの値が違うだけ)

参考:

ECS — Boto 3 Docs 1.9.2 documentation

import boto3

from botocore.exceptions import ClientError

def lambda_handler(event, context):

try:
client = boto3.client('ecs')
service_update_result = client.update_service(
cluster = 'tst-mamari-q-api',
service = 'fargate-tst-docker-apache-prd',
desiredCount = 0 # ここの数を増減させる
)
print(service_update_result)
except ClientError as e:
print("exceptin: %s" % e)


lambdaを実行するための、IAMロール

【必要な権限】


  • ecs serviceの更新


    • ecs系のActionは、Resource絞れるなら指定したほうがベター



  • cloudwatchlogsへの出力権限

{

"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": [
"ecs:DescribeServices",
"ecs:UpdateService"
],
"Resource": [
"*"
]
},
{
"Effect": "Allow",
"Action": [
"logs:CreateLogGroup",
"logs:CreateLogStream",
"logs:PutLogEvents"
],
"Resource": "arn:aws:logs:*:*:*"
}
]
}


lambdaを定期実行するCloudWatchEventsのイベント

トリガに使うので、CloudWatchEventsにcronスケジュールをセットしておく。

883FDE07-FBDC-476C-90CF-44DA4D119417.png


デモ

【シナリオ】

- 14:47になったらスケールアウト開始(タスク数を1にする)

- 15:05になったらスケールイン開始(タスク数を0にする)


スケールアウト(14:47にスケールアウト開始)

① スケールアウトするイベント登録

1BF3D475-48B9-4C55-B587-7087D9F49169.png

② ①のイベントをトリガにするlambda登録

09BDBAC5-B67B-4337-86EA-0D0A6EF90897.png

③時間になった時のECSの状態

D3798586-DC94-4970-A7C6-4765B298F20D.png


スケールイン(15:05にスケールイン開始)

① スケールインするイベント登録

1666BC04-CBA0-4240-AE6F-4A04AA83D13A.png

② ①のイベントをトリガにするlambda登録

213C3579-FA4F-47D4-9B6A-AA8BF8039767.png

③時間になった時のECSの状態

21C7DBFF-FA81-43C2-A97A-1B968B355026.png

※Lambdaの実行ログは、CloudWatchLogsから見れる