こんにちは、幅広い視野を持つエンジニアを目指しています田中と申します
この記事はAWS Batchを利用してコンテナを定期実行する~前編~の記事の続きとなります
ECRとECS, dockerを使用します(単語の定義程度の理解で問題ありません)
TL;DR
目次
はじめに
前編をまだ読まれていない方は読んでくださいね
AWS Batchを利用してコンテナを定期実行する~前編~
目標
- AWS Batchで応用的な処理を実行する
- AWS Batchをジョブスケジューラとして利用する
手順
AWS Batchでカスタムイメージを使用するまで
Jenkinsのシェル実行機能
画像のようにJenkinsのジョブではシェルスクリプトで処理を行うことができますが、AWS Batchでは可能でしょうか。検証してみます
ジョブ設定1
手始めにdockerコンテナのcgroup情報を見てましょう
まず、Jenkinsのジョブと同じようにShebangを書いてシェルスクリプトを記述してみました
すると・・・
エラーになってしまいました。シェルスクリプトとして解釈してくれないようです
公式ドキュメントにはコマンドとしか言及されていません(ジョブ定義のパラメータ - AWS Batch)
そして、どうやら改行も無視されてしまうようです
ところで、EC2のユーザデータやECSのコマンドも1行で書くお約束でした
下記画像はECSのチュートリアルのタスク定義です
ワンライナーでコンテンツ書き込むんですね・・・
これをAWS Batchでも試します
こんな感じでしょうか
結果はNGでした。何か妨害工作(exec経由の単一プロセス実行)を感じます…
コマンドの連続実行やパイプはできないようです。もう少し試行錯誤します
脱線
- 依存ジョブを作る
- インスタンスを毎回作るので遅い
- 次のコマンドに結果を渡せない
- 依存ジョブの最大は25個まで
- ECSクラスタを利用する
AWS BatchはECSクラスタ、つまりはdockerホストなのでAWS CLIからECSのタスクとして発行します
- AWS CLIのdokcerイメージを利用する
- AWS CLIのコンテナを使ってECSのタスクを発行する
AWS CLIのイメージのCommandに以下のようにしてみます(API KEYやSECRET KEY、regionを環境変数として指定します)
dockerイメージを自作
Blackbeltの36ページにはイメージには事前に実行するプログラムを含ませておくように書かれています
予めよく読むべきでした
気を取り直してECRを設定します
AWSコンソールからコンピューティング→Elastic Container Serviceを選びましょう
左メニューからリポジトリを選択し、リポジトリの作成を押下
- リポジトリ名には任意の名前を入力します
もうリポジトリができました!
リポジトリの利用方法が表示されています。ここにあるコマンドはこの後使いますのでメモしておきましょう!(後から見ることもできます)
docker環境の準備
続いてdockerイメージを自作するための環境を作成しましょう
EC2を利用しても良いのですが、AWS BatchがEC2クラスタを構築してくれているのでこちらを使わせてもらいましょう
EC2を利用する場合でも下記コマンドで一発でdocker環境が手に入ります
dockerイメージの構築
dockerイメージを作るためのベースとなるイメージをpullしましょう
Dockerfileを記述しカスタマイズ、docker buildを行っても良いですが、今回は既存の物を使わせてもらいましょう
私はAWSに対して処理を自動化したかったので以下のイメージを使いました
イメージがpullできたら
とコマンドを入力します
先ほどpullしたイメージがリストされています
このイメージのIMAGE_IDを使ってコンテナを起動しますのでメモしておきましょう!
コンテナのシェルが表示されましたか?
あとはこのコンテナで必要なものをインストールしたり、任意のプログラム/スクリプトをデプロイします
準備が完了したらCtrl+Dを押下してコンテナを抜けましょう
次に、このコンテナからカスタマイズしたdockerイメージを作成します
と入力すると、先ほどカスタマイズしたコンテナが見えます
CONTAINER IDを使ってカスタマイズしたイメージを作成します次のコマンドを入力しましょう
-m="May our dream come true!"のところはコミットメッセージであり、skyarch/test/awsbatchbase:latestはタグ名なので任意のもので構いません
docker imagesを実行すると今作ったイメージが表示されています
さていよいよこのイメージをECRにアップロードしていきます
まずは、ECRにログインします。ECRをセットアップした際に表示されていたコマンドを入力しましょう
成功すると、
と表示されECRに接続することができます
ECRにアップロードするためのタグをイメージにつけましょう
そしていよいよpushです!
成功したらAWS Batchで指定できます。Commandにはデプロイしてあるプログラムやスクリプトを実行するように指定してあげます
さてジョブを発行してみると・・・?
大成功です!シェルスクリプトが実行できました。そしてシェルスクリプトなので環境変数なりでジョブごとに処理の範囲を決めてあげることで簡単に並列実行できますね!(n件の処理をm個に分割など)
さて、次はAWS Batchをタスクスケジューラとして使いましょう!
CloudWatch Eventとの連携
次はAWS BatchをCloudWatch Eventと連携させてジョブを定期実行させます
まず、下記のようなLambda関数を作りましょう!
1 2 3 4 5 6 7 8 9 10 11 12 13 14 | batch = boto3.client( 'batch' ) def submit_job(event): result = batch.submit_job( jobName = event[ 'JobName' ], jobQueue = event[ 'JobQueue' ], jobDefinition = event[ 'JobDefinition' ] ) return result def lambda_handler(event, context): result = submit_job(event) print (result) return None |
続いてCloudWatch Eventをトリガーとして追加します
CloudWatch Event設定1
LambdaのDesigner→トリガーの追加→CloudWatch Eventを選択
CloudWatch Event設定2
ページ下部から作成したCloudWatch Eventを編集します
CloudWatch Event設定3
CloudWatch Event設定4
スケジュールを設定します(時刻はUTCです)
cron式と言いつつ、"日"のフィールドに"*"を指定するとエラーになるので"?"を指定します
CloudWatch Event設定5
ユーザデータを指定します
先ほどLambda関数を作成しましたが、Lambdaのeventにデータを入れる設定をします
- ターゲットにLambda関数を選択
- 機能のセレクトボックスから先ほど作成したLambda関数を選択
- 入力の設定を展開し、定数(JSONテキスト)を選択
- 入力欄に下記内容を入力
UIが頻繁に変わることに加え、ユーザデータの指定の場所がとても分かりづらいです!
これで、cron式で指定した日時になるとジョブが実行されて幸せになれます!!
まとめ
AWS Batchを使うことでスケーラブルでマネージ不要なHPC環境を低コストに実現できる!
AWS BatchとCloudWatch Eventを使うことでジョブを任意の日時に自動実行させることができ、マネージ不要のタスクスケジューラとして使える!
ここまで読んでくださりありがとうございました!
記事は以上になります。
このたびはご覧戴き、ありがとうございました。
・引用元および参考にさせていただいたサイト様
【公式】AWS Batchの開始方法
【公式】Docker
【公式】Docker hub
(初心者向け)Dockerの使い方
AWS BatchでPythonスクリプトを定期的に実行する
(CloudWatch Eventのトリガー使用方法およびLambdaのキックスクリプトをそのまま使用させていただいております)
投稿者プロフィール
最新の投稿
- AWS2021年12月2日AWS Graviton3 プロセッサを搭載した EC2 C7g インスタンスが発表されました。
- セキュリティ2021年7月14日ゼロデイ攻撃とは
- セキュリティ2021年7月14日マルウェアとは
- WAF2021年7月13日クロスサイトスクリプティングとは?