アフィリエイト広告を利用しています
はじめに
2025年が始まってもう1ヶ月が経ちました。時が過ぎるのは早いものですね。
皆さんは今年の目標を立てましたか?筆者の目標は3つです。
1.年収UP
2.資格取得(応用情報技術者、AWS SAP)
3.技術ブログを15記事以上書く
エンジニアとして大切なことは、常に知識技術のインプットとアウトプットなので、資格取得や技術ブログなどを通じて、今年もより注力して自身をアップデートしていこうと思います。そして、その結果が年収UPにつながっていけばなと思います。
今回もAWSの運用についてです。
ECSのFargate Spotについて
Spotとは?
AWSでEC2やECSを使用するときに、「オンデマンド」や「リザーブド」など料金体系を使用場面に応じて選ぶと思いますが、ここに「スポット」というものがあります。
Spotインスタンスとは、AWS側で余っているリソースを格安で使用できるインスタンスで、料金が通常の7割減で利用できるものの、AWSの需要によって強制的に停止削除される可能性があるインスタンスです。Spotインスタンスというと、EC2というイメージがありますが、2019年にECS FargateでもSpotが使用できるようになり、多くの記事でSpotの導入方法や検証が行われています。
https://aws.amazon.com/jp/ec2/spot/pricing/
https://dev.classmethod.jp/articles/fargate-spot-detail
Spotを利用するときに気を付けたいこと
前段の通り、Spotインスタンスは強制的に終了させられる可能性があり、本番環境へ導入する際は、導入割合を調整したり、Spotが落ちたらオンデマンドインスタンスが起動するように設定をしたりする必要があります。
また、Spotインスタンスが終了する際には、終了の2分前に通知が入り、タスク終了時にコンテナへSIGTERMのシグナルを送信し、StopTimeoutの指定時間が経過後にタスク停止が入ります。
このStopTimeoutが調整されてないと、タスク停止までにコンテナの正常終了が完了せず、意図しないエラーが出てしまいます。ECS Fargate Spotを使用する際は、タスク定義でStopTimeoutを120秒で設定し、タスク停止までにアプリケーションが正常に終了できるようにしましょう。
また、Fargate Spotでは、タスクが停止する前にALBのターゲットグループから登録解除を行う必要があります。ALBには、ターゲットグループからの登録解除を遅らせる設定ができますが、これをSpotのタスクが終了する2分未満に解除されるように設定してください。
未経験からITエンジニアになる【テックハブニュービー】
未経験からITエンジニアに!IT専門転職エージェント@PRO人【アットプロジン】
未経験エンジニア転職ならテックゲート転職
まさかの落とし穴
前段で、「タスク定義でStopTimeoutを120秒で設定」、「ターゲットグループからの登録解除を遅らせる設定」を筆者も対処しましたが、何故かALBで5XXエラーが対処前後でも変わりませんでした。。その原因は、ECSのサービス仕様としてあるサービススケジューラでした。
サービススケジューラとは?
ECSサービススケジューラとは、ECSクラスター内で、タスク定義の指定した数のインスタンスを同時に実行して維持させるものです。タスクの 1 つが失敗または停止した場合、タスク定義の別のインスタンスを起動してそれを置き換え、必要タスク数を維持できます。
ELB-ECSの構成をすると、ロードバランサーのターゲットグループのヘルスチェックを使ってサービススケジューラを実行でき、ターゲットグループに登録されたタスクをサービススケジューラによってタスク数を維持させたり、新しいタスク定義のデプロイをさせたりできます。
タスクの置き換えは、maximumPercent および desiredCount のサービス定義パラメータによって変わりますが、基本的には新しいタスクが正常に起動後、古いタスクを停止終了させる動きとなり、必要タスク数を維持するように動作します。
https://docs.aws.amazon.com/ja_jp/AmazonECS/latest/developerguide/ecs_services.html
筆者の環境では、ELB-ECSの構成にSpotを導入していたのですが、Spotの中断通知後に以下のような動きをしておりました。
Spotの中断通知
↓
新しいタスクを起動しようとする
↓
キャパシティプロバイダ戦略により、Spotの導入割合を維持しようとSpotで起動しようとする
↓
Spotを起動するリソースが無く連続して失敗
↓
新しいタスクの起動ができないまま、Spotが中断
↓
ELBのターゲット登録解除が中断前に完了できずに5XXエラー
この動作の流れが、エラーが解消しない原因でした。
対策方法
サービススケジューラの機能は、AWSの仕様のために変更することができません。
そのため、こちらで対処する必要があります。
ECS Fargateの場合、ECS_ENABLE_SPOT_INSTANCE_DRAININGの環境変数は使用できません。
Spotの中断の通知を受けたら、ECSから送信するSIGTERMハンドラー内で、DeregisterTargetsAPIを呼出してターゲット登録解除をするSDKアプリケーションをサイドカーコンテナで持つか、タスク状態変更のイベントでトリガーするLambdaで、ロードバランサーからタスクを登録解除するという2通りの方法があります。筆者はSDKを組み込んだアプリケーションをサイドカーコンテナで持つ方法で設定しようとしていますが、こちらは別記事で扱っていく予定です。
https://aws.amazon.com/jp/blogs/news/graceful-shutdowns-with-ecs
最後に
今回も、以前少し紹介しましたFargate Spotについて書かせていただきました。
Spotインスタンスは、オンデマンドインスタンスと比べて最大7割減のコストで使用でき、運用コストの面で大変魅力的なインスタンスです。しかし、AWS側で強制停止が伴うことや、設定に考慮が必要な部分が増えるなどのデメリットはあります。導入の際にはご参考にしていただければと思います。

コメント