AWS Batch でジョブが RUNNABLE
状態でスタックしたときの対処方法に、今回のアップデートで新しい機能が追加されました。RUNNABLE 状態でスタックしたジョブを EventBridge で検知でき、一部の原因に対してはジョブを自動的にキャンセルできるようになりました。
背景
AWS Batch でジョブをサブミットした後、設定ミスなどの理由で RUNNABLE
状態のままで止まってしまい、後続のステータスに遷移しないことがあります。
よくある原因としては、コンピューティング環境の 最大 vCPU 数設定とジョブの要求 vCPU 数の不一致や IAM ロールの権限不足などが挙げられます。
参考: Troubleshoot AWS Batch jobs stuck in RUNNABLE status | AWS re:Post
DevelopersIO にも以下の記事があります。
- AWS Batch で サブミットしたジョブが [RUNNABLE] のまま止まっている理由について教えてください | DevelopersIO
- AWS Batch プレイスメントグループの指定ミスでサブミットしたジョブが [RUNNABLE] のまま止まっているときの対処方法 | DevelopersIO
新機能
今回のアップデートで、以下の新機能が追加されました。
RUNNABLE
状態でスタックしたジョブを EventBridge のイベント "Batch Job Queue Blocked" で検知できる- ジョブキューに "ジョブの状態制限" を設定することで、一部の
RUNNABLE
の理由(スタック原因)に対してはスタックしたジョブを自動的にキャンセルできる - ジョブが自動キャンセルされた際は、"Batch Job State Change" イベントが発行される
検証
実際に検証してみました。検証のためにジョブをサブミット後RUNNABLE
状態でスタックさせる状況を意図的に作成します。今回はコンピューティング環境の最大 vCPU 数を超える vCPU 数を要求するジョブをサブミットしスタックさせます。
コンピューティング環境の最大 vCPU 数を 4 としました。
ジョブをサブミット時に要求する vCPU 数は 4 を超える値とします。
以降の設定ではこちらのジョブをサブミットしてアップデートの動作を確認することとします。
EventBridge で RUNNABLE 状態のスタックを検知
EventBridge の AWS Batch のイベントタイプにBatch Job Queue Blockedが追加されていました。このイベントタイプを使いRUNNABLE
でスタックしたジョブを検知した結果を確認します。
{
"source": ["aws.batch"],
"detail-type": ["Batch Job Queue Blocked"]
}
ターゲットは CloudWatch Logs にイベントを記録する設定としました。
意図的にRUNNABLE
でスタックさせるジョブをサブミットしました。期待どおり放置してもRUNNABLE
のままうんともすんとも進みません。
CloudWatch Logs に保存したログを確認します。
statusReason:
で以下のメッセージを確認できます。「ジョブキューに関連付けられたコンピューティング環境が、ジョブの CPU 要求数を満たすことができない」ということで原因の説明があります。
"MISCONFIGURATION:COMPUTE_ENVIRONMENT_MAX_RESOURCE - CE(s) associated with the job queue cannot meet the CPU requirement of the job."
{
"version": "0",
"id": "2c0d7c5c-fc63-874a-d2fe-54fe4db06294",
"detail-type": "Batch Job Queue Blocked",
"source": "aws.batch",
"account": "123456789012",
"time": "2024-03-30T00:49:21Z",
"region": "ap-northeast-1",
"resources": [
"arn:aws:batch:ap-northeast-1:123456789012:job/1d74dae1-5a4e-4d9f-8244-dbe2cfb14dc3"
],
"detail": {
"jobArn": "arn:aws:batch:ap-northeast-1:123456789012:job/1d74dae1-5a4e-4d9f-8244-dbe2cfb14dc3",
"jobName": "devio-0330",
"jobId": "1d74dae1-5a4e-4d9f-8244-dbe2cfb14dc3",
"jobQueue": "arn:aws:batch:ap-northeast-1:123456789012:job-queue/devio-job-queue",
"status": "RUNNABLE",
"attempts": [],
"statusReason": "MISCONFIGURATION:COMPUTE_ENVIRONMENT_MAX_RESOURCE - CE(s) associated with the job queue cannot meet the CPU requirement of the job.",
"createdAt": 1711759556898,
"retryStrategy": {
"attempts": 1,
"evaluateOnExit": []
},
"dependsOn": [],
"jobDefinition": "arn:aws:batch:ap-northeast-1:123456789012:job-definition/devio-job-def-20240308:5",
"parameters": {},
"container": {
"image": "public.ecr.aws/amazonlinux/amazonlinux:latest",
"command": [
"sleep",
"30"
],
"executionRoleArn": "arn:aws:iam::123456789012:role/ecsTaskExecutionRole",
"volumes": [],
"environment": [],
"mountPoints": [],
"ulimits": [],
"networkInterfaces": [],
"resourceRequirements": [
{
"value": "32",
"type": "VCPU"
},
{
"value": "2048",
"type": "MEMORY"
}
],
"logConfiguration": {
"logDriver": "awslogs",
"options": {},
"secretOptions": []
},
"secrets": []
},
"tags": {
"resourceArn": "arn:aws:batch:ap-northeast-1:123456789012:job/1d74dae1-5a4e-4d9f-8244-dbe2cfb14dc3"
},
"platformCapabilities": [
"EC2"
],
"eksAttempts": []
}
}
RUNNABLE
状態でスタックしているジョブを EventBridge で検知、イベントログからスタックしている理由まで確認できました。
スタックしたジョブの自動キャンセル
次にジョブキューに "ジョブの状態制限" を設定し、スタックしたジョブを自動的にキャンセルできるか確認しました。
ジョブキューの設定に新たにジョブの状態制限の項目が追加されていました。
現在、設定可能な各理由(statusReason
)に対してジョブを自動で停止するまでの時間を設定しました。タイムアウトまでの時間は 10 分 〜 24 時間の間で設定できます。
各理由(statusEeason
)と自動キャンセルに対応しているかの確認は AWS ブログの記載がわかりやすかったです。現時点だとジョブがスタックしたことを EventBridge で検知はできても、自動キャンセル設定に対応していないstatusReason
は 2 つ確認できました。
スタックしたジョブの自動キャンセル設定とは直接関係ありませんが、ジョブを打ち切ったというイベントも発行されるためBatch Job State Chageで拾えます。EventBridge のルールを設定してみました。
{
"source": ["aws.batch"],
"detail-type": ["Batch Job State Change"]
}
ジョブのスタック時の EventBridge ルールと同様に CloudWatch Logs に保存します。
意図的にRUNNABLE
でスタックさせるジョブをサブミットしました。10 分ほど放置するとジョブがFAILED
で終了しました。RUNNABLE
状態でスタックせずに打ち切ってくれています。
CloudWatch Logs に保存したログからstatusReason:
で以下のジョブのキャンセル理由を確認できます。
"Canceled by JobStateTimeLimit action due to reason: MISCONFIGURATION:COMPUTE_ENVIRONMENT_MAX_RESOURCE",
{
"version": "0",
"id": "d06fa803-b52e-2a1d-f1f7-c08935c494ec",
"detail-type": "Batch Job State Change",
"source": "aws.batch",
"account": "123456789012",
"time": "2024-03-30T02:00:33Z",
"region": "ap-northeast-1",
"resources": [
"arn:aws:batch:ap-northeast-1:123456789012:job/3df44b1b-1a30-46d8-8f1a-d11c3dfb657a"
],
"detail": {
"jobArn": "arn:aws:batch:ap-northeast-1:123456789012:job/3df44b1b-1a30-46d8-8f1a-d11c3dfb657a",
"jobName": "test-devio-0330-cancel",
"jobId": "3df44b1b-1a30-46d8-8f1a-d11c3dfb657a",
"jobQueue": "arn:aws:batch:ap-northeast-1:123456789012:job-queue/devio-job-queue",
"status": "FAILED",
"attempts": [],
"statusReason": "Canceled by JobStateTimeLimit action due to reason: MISCONFIGURATION:COMPUTE_ENVIRONMENT_MAX_RESOURCE",
"createdAt": 1711763392195,
"dependsOn": [],
"jobDefinition": "arn:aws:batch:ap-northeast-1:123456789012:job-definition/devio-job-def-20240308:5",
"parameters": {},
"container": {
"image": "public.ecr.aws/amazonlinux/amazonlinux:latest",
"command": [
"sleep",
"30"
],
"executionRoleArn": "arn:aws:iam::123456789012:role/ecsTaskExecutionRole",
"volumes": [],
"environment": [],
"mountPoints": [],
"ulimits": [],
"networkInterfaces": [],
"resourceRequirements": [
{
"value": "32",
"type": "VCPU"
},
{
"value": "2048",
"type": "MEMORY"
}
],
"logConfiguration": {
"logDriver": "awslogs",
"options": {},
"secretOptions": []
},
"secrets": []
},
"tags": {
"resourceArn": "arn:aws:batch:ap-northeast-1:123456789012:job/3df44b1b-1a30-46d8-8f1a-d11c3dfb657a"
},
"platformCapabilities": [
"EC2"
],
"eksAttempts": [],
"isCancelled": true
}
}
ジョブキューに設定を追加すれば、一部の理由であればスタックしているジョブを打ち切れることを確認できました。
まとめ
今回のアップデートにより、AWS Batch の運用が楽になりました。
RUNNABLE
状態のジョブを EventBridge で自動検知できるようになり、一部の原因に対してはジョブを自動的にキャンセルできます。
しかし、自動キャンセル対象外の RUNNABLE
理由(スタック原因)もあります。
おわりに
現在自動キャンセルの対象が今後増えていくことを期待しています。とはいえ EventBridge でスタックしたジョブを検知できるようになったため、ユーザー側で独自の実装すれば自動化はできますね。