現状、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スケジュールをセットしておく。
デモ
【シナリオ】
- 14:47になったらスケールアウト開始(タスク数を1にする)
- 15:05になったらスケールイン開始(タスク数を0にする)
スケールアウト(14:47にスケールアウト開始)
スケールイン(15:05にスケールイン開始)
② ①のイベントをトリガにするlambda登録
③時間になった時のECSの状態
※Lambdaの実行ログは、CloudWatchLogsから見れる