AWS Batchを試してみる

背景

前回Djangoのカスタムコマンドを試しに追加してみました。

今回はこのカスタムコマンドをAWS Batchで実行してみたいと思います。

AWS Batchとは?

AWS Batchは今回初めて利用するので、何なのかを知っておく必要があります。

AWSサービスの学び方としては、AWS Black Belt Online Seminarを受けるとよいとAWS認定資格試験の本に書いてあったので、見てみることにしました。

その動画はこちらになります。
[AWS Black Belt Online Seminar] AWS Batch 資料及び QA 公開

資料はこちらです。

わかったこととしては、以下のようになります。

  • 通常のバッチを実行するためではなく、ハイパフォーマンスなりソースが必要な場合に用いるサービスである。(資料P.9)
    • しかし通常のバッチ処理をしてはいけないというわけではない
  • S3 Batchというサービスもある
  • 最終的なデータのIN/OUTにはS3を用いることが多い
  • ジョブ完了ステータスからSNSを利用してSlack通知をすることができる
  • ジョブの投入方法(資料P.48)
    • ユーザーが手動で投入(マネジメントコンソール/CLI)
    • S3へのファイルアップロードをトリガーにLambdaからアップロードされたファイルを処理するジョブを投入
    • Cloud Watch Eventsにより決められた時刻にジョブを投入
  • スポットインスタンスの活用を検討すべき
  • 複雑なワークフローを実現するためにはAWS Step Functionsを利用する

なんとなくわかった気がしたので、実際にマネジメントコンソールから設定してみます。

AWS Batchの設定

ではAWS Batchの設定を行いたいと思います。

ジョブの作成には、ジョブ定義とジョブキューが必要です。なので、この二つを作成します。

しかしジョブ定義の作成にはコンテナを指定する必要があったので、まず初めにコンテナイメージの作成から行なっていきます。

コンテナイメージの作成

ECRに登録するためにローカルで作成したイメージにECR用のタグを設定します。ローカルにあるイメージのタグをtest:1.0とすると

1
$ docker tag test:1.0 xxxxxx.dkr.ecr.ap-northeast-1.amazonaws.com/test:1.0

というようにしてECR用のタグを設定します。

コンテナレジストリへの登録

ECRに登録するためECRにログインし、先ほど作成したイメージをpushします。

1
2
$ aws ecr get-login-password --region ap-northeast-1 --profile test | docker login --username AWS --password-stdin xxxxxx.dkr.ecr.ap-northeast-1.amazonaws.com
$ docker push xxxxxx.dkr.ecr.ap-northeast-1.amazonaws.com/test:1.0

ジョブ定義の作成

コンテナイメージをECRに登録できたので、ジョブ定義を作成します。

ジョブ定義に必要な内容は

  • 名前
  • プラットフォーム(EC2 or Fargate)
  • 再試行戦略
    • ジョブの試行回数
  • 実行タイムアウト
  • コンテナプロパティ
    • イメージ
    • コマンドの構文
    • コマンド
    • vCPU
    • メモリ
    • 実行ロール
    • Fargateプラットフォームのバージョン

です。
今回はプラットフォームにFargate、コンテナプロパティのイメージには先ほどECRに登録したイメージを指定します。コンテナプロパティのコマンドにはバッチで実行するコマンドを指定します。

ジョブキューの作成

次にジョブキューを作成します。

ジョブキューの作成には

  • 名前
  • 優先度
  • コンピューティング環境

が必要です。

コンピューティング環境を作成していなかったので、こちらを作成します。

コンピューティング環境の作成

コンピューティング環境の作成では以下の項目を設定します。

  • コンピューティング環境設定
    • コンピューティング環境のタイプ(マネージド or not)
    • コンピューティング環境の名前
  • インスタンスの設定
    • プロビジョニングモデル(Fargateなど)
    • 最大vCPU
  • ネットワーキング
    • VPC ID
    • サブネット

では以下にそれぞれの設定内容を記載します。

コンピューティング環境のタイプ

マネージド型

コンピューティング環境の名前

任意の文字列

プロビジョニングモデル

Fargate

最大vCPU

256

VPC ID

このコンピューティング環境専用のVPCを指定します

サブネット

上記VPCに紐づいたサブネット(パブリック)を指定します。パブリックサブネットにするのはECRへのアクセスを行うためです。

コンピューティング環境の作成ができたら、ジョブキューの作成を完了します。

ジョブの投入

では実際にジョブを作成してバッチを実行してみます。

ジョブから新しいジョブを送信をクリックします。名前は任意ですが、ジョブ定義・ジョブキューは先ほど作成したものを指定します。実行タイムアウトが空欄になっているので最小値の60を指定します。それ以外の項目に関しては、ジョブ定義・ジョブキューの内容が反映されています。

では送信ボタンを押して実行しましょう。


エラー発生

少し待ってからダッシュボードで確認すると、FAILEDに1と表示されてしまいました。FAILEDの1がリンクになっていてクリックしてみると、失敗したジョブが表示されました。

失敗したジョブ名がリンクになっていたのでクリックすると、ジョブの詳しい情報が表示されました。

ステータス理由というところに、エラー内容が記載されていました。

1
ResourceInitializationError: unable to pull secrets or registry auth: pull command failed: : signal: killed

なにかしらの原因でイメージが引っ張ってこれなかったということでしょうか。エラー内容から検索してみます。

ECR接続のためのルーティング設定

エラーメッセージで調査したところ、やはりECRからコンテナイメージをpullできなかったときに表示されるエラーメッセージでした。

ECRからコンテナイメージを取得するための方法が公式ドキュメントに載っていました。
https://aws.amazon.com/jp/premiumsupport/knowledge-center/ecs-pull-container-api-error-ecr/

今回の場合はFargateを利用していて、パブリックサブネット(のつもり)だったので、サブネットの設定で自動割り当てパブリックIPが有効になっているかを確認したのですが、有効になっていました。

もう少し調べてみると、パブリックサブネットと呼べるネットワーク設定の一つに、ルーティングでインターネットゲートウェイを向いていることと書かれていました。調べてみるとデフォルトルートが指定されておらず、ローカルのルーティングしか設定されていませんでした。

VPCのルートテーブルのデフォルトルート(0.0.0.0/0)にインターネットゲートウェイを設定しました。

実行確認

再度ジョブを実行してみると、今度は無事SUCCEEDEDになりました。

まとめ

AWS BatchでDjangoのカスタムコマンドを実行することができました。

次回は今回手動で実行していたジョブをイベントをトリガーに実行するようにしてみようと思います。

参考図書

AWS認定資格試験テキスト AWS認定ソリューションアーキテクト - アソシエイト 改訂第2版