背景
仕事でAWS ECS(Elastic Container Service)を使ってWebアプリを開発・運用しています。ECSのScheduled Taskを使って定期的にバッチを実行をしているのですが、ある日バッチの実行結果の通知が届かず、またCloudWatch logsでもログを確認できませんでした。CloudTrailでECSのRunTask APIの呼び出し履歴を確認すると、以下の実行結果があり、調べるとキャパシティ不足でタスク起動に失敗したことが分かりました。
{
"eventVersion": "1.09",
"eventSource": "ecs.amazonaws.com",
"eventName": "RunTask",
(中略)
"responseElements": {
"failures": [
{
"reason": "Capacity is unavailable at this time. Please try again later or in a different availability zone"
}
],
"tasks": []
}
}
対応を検討する以前にまず上記事象がどれくらいの頻度で発生しているのかを確認するためにaws cloudtrail lookup-events
コマンドを使ってRunTask APIの実行結果、ステータスコードは200が返って来たが、結局タスク起動に失敗した件数をカウントしました。
前提条件
- AWS CLIをインストールし、接続情報の設定が完了していること
- jqコマンドをインストールしていること
- Mac環境であること(WindowsやLinux環境の場合はコマンドの一部を要修正)
コマンド
RunTask APIの実行結果、ステータスコードは200が返って来たが、結局タスク起動に失敗したCloudTrailのイベントレコードを取得するコマンドは以下のようになりました。
aws cloudtrail lookup-events \
--lookup-attributes AttributeKey=EventName,AttributeValue=RunTask \
--start-time $(date -u -v -90d '+%Y-%m-%dT%H:%M:%SZ') \
--query 'Events[*].CloudTrailEvent' \
--output text | jq -c 'select(.responseElements.failures | length > 0)'
それぞれのオプションを説明すると、
-
--lookup-attributes
: 特定のイベントをフィルタリングするためのオプションで、今回EventNameとしてRunTaskを指定しています。RunTaskはECSタスクの起動を試みる際に記録されるイベントになります。 -
--start-time
: 過去のイベントを検索するための開始時刻を指定します。3ヶ月前(90日前)から現在までのイベントを対象にしています。dateコマンドを使用して動的に生成します。 -
--query
: クエリを使用して、特定のデータをフィルタリングします。イベントの詳細情報であるCloudTrailEventを取得します。 -
--output text
: 出力形式をテキストに指定します。jqでさらに処理が可能になります。 -
jq -c 'select(.responseElements.failures | length > 0)'
: jqコマンドを使用して、取得したイベントの中からfailuresフィールドにエラーが存在するものをフィルタリングします。
上記コマンドで、RunTask APIの実行結果、ステータスコードは200が返って来たが、結局タスク起動に失敗したCloudTrailのイベントレコードを取得できるようになりました。
参考
RunTask API を用いた ECS タスク実行時に気をつけたいこと4選
Fargateを利用したECS Scheduled Taskでタスクが起動しない事象について