こんにちはますのです。
ECS on Fargateのコストが積み重なってきましてどうにかしたいと思う今日この頃。
AWS営業の方から「技術相談会で技術者とディスカッションしませんか?」とお話を頂きディスカッションしてまいりました。
その他良い方法あったりしますか??
決まった時間にアクセスの上昇と下降が見えますね。
ECSのスケジュール設定で時間帯で縮退するのはどうでしょう?
LambdaやらStepFunctionsを使うのかな?と思いましたが、どうやらCLIでオートスケーリングのcron設定をするだけの様子。
やりたいこと
今回やりたいことはこんな感じ。
- 月曜日~金曜日の8時-21時は2台構成にする
- 月曜日~金曜日の8時-21時以外は1台構成にする
- 土曜日~日曜日は終日1台構成にする
環境構築
FargateをGithubActionsから作成
まずはFargateの環境をサクサクっと作ります。
今回はnginxを動かすためのDockerfileを作成し、GithubActionsでデプロイしました。
参考:GitHub ActionsからサクッとFargateにデプロイしてみた
CLI環境の準備
続いてAWS CLIの環境準備です。
Fargateへアクセス可能な権限を保持しているものをご用意ください。
今回はお気軽にということでCloudShellを起動しました。
画面右上のマーク「CloudShell」をクリックして完了です。
Fargateのオートスケール設定
本題です。実際にオートスケールの設定をしていきます。
オートスケールを設定する際のcron記述は「UTC時間」で設定する必要があるため注意が必要です。
参考:AWSでのCron表記でハマったので仕様を確認しておく
オートスケール設定
まず初めにオートスケールの「タスクの最小数」「タスクの最大数」を設定します。
aws application-autoscaling \
register-scalable-target \
--service-namespace ecs \
--resource-id service/(クラスター名)/(サービス名) \
--scalable-dimension ecs:service:DesiredCount \
--min-capacity 1 \
--max-capacity 2
クラスター>サービス>Auto Scalingタブ:最小タスク数、最大タスク数が設定されました。
停止スケジュールをcronで設定する
続いてFargateの停止処理(1台での縮退運転)設定です。
月曜日~金曜日の21時に定期実行する設定とします。
※画像では曜日設定を1-5としましたが英語表記の方が分かりやすいのでコードでは修正
aws application-autoscaling put-scheduled-action \
--service-namespace ecs \
--resource-id service/(クラスター名)/(サービス名) \
--scheduled-action-name (任意のスケジュール名称) \
--schedule "cron(00 12 ? * MON-FRI *)" \
--scalable-dimension ecs:service:DesiredCount \
--scalable-target-action MinCapacity=1,MaxCapacity=1
夜間停止する場合にも使えて良さそうです。
テストで「月-金 16:45に台数0」を仕込んだところ0台へ変更されました。
以下のようなエラーが出た場合は最初のオートスケール設定が失敗している可能性があります。
An error occurred (ObjectNotFoundException) when calling the PutScheduledAction operation: No scalable target registered for service namespace: ecs, resource ID: service/test-scale/test-scale-service, scalable dimension: ecs:service:DesiredCount
クラスター>サービス>タブ:AutoScalingで「最小タスク数」「最大タスク数」が設定されているか確認しましょう。
起動スケジュールをcronで設定する
続いてFargateの起動処理(2台での冗長運転)を設定します。
月曜日~金曜日の朝8時に定期実行する設定とします。
aws application-autoscaling put-scheduled-action \
--service-namespace ecs \
--resource-id service/(クラスター名)/(サービス名) \
--scheduled-action-name (任意のスケジュール名称) \
--schedule "cron(0 23 ? * SUN-THU *)" \
--scalable-dimension ecs:service:DesiredCount \
--scalable-target-action MinCapacity=2,MaxCapacity=4
cronの設定を確認する
今まで設定した内容が登録されたかCLIより確認します。
参考:describe-scheduled-actions
aws application-autoscaling describe-scheduled-actions \
--service-namespace ecs \
--resource-id service/(クラスター名)/(サービス名)
設定したcronの内容が2つjson形式で返ってくれば設定完了です。
こちらのcron設定はAWSのマネージメントコンソール上から確認が出来ないため、チームで管理する時は共有必須でございます。
参考サイト
参考:GitHub ActionsからサクッとFargateにデプロイしてみた
参考:AWSでのCron表記でハマったので仕様を確認しておく