AWS Batchにいろんな条件のOpenFOAMのジョブを投入する

記事タイトルとURLをコピーする

Click here to read in English.

先日、EC2インスタンスの料金の秒単位による請求が始まりました。これは、複数の処理をAWS上で同時実行したいユーザにとって朗報と言えます。 これまで、EC2インスタンスの料金は時間(Hour)単位で請求されていました。インスタンスが10分稼働した場合でも、50分稼働した場合でも、1時間分の料金が請求されていました。したがって、例えば

(1) 1台のEC2インスタンスで50分かけて処理する
(2) 5台のEC2インスタンスを使って10分で処理を終わらせる

という2つの条件で同じ処理を実行した場合、(2)は(1)の5倍の料金がかかっていました。これが秒単位の請求になったことで、(1)と同じ料金で(2)ができるようになりました。 AWS BatchでlaunchしたEC2も、この秒単位請求の対象となります。そこでこの記事では 以前JAWS-UG HPCで行われたハンズオン をベースに、複数条件の流体シミュレーションをAWS Batchで同時実行してみます。最後に利用料金も試算してみます
(この記事の公開を、上記ハンズオンの作成者であるporcaro33さんに快諾いただきました。御礼申し上げます。)

環境の概要

まずネットワーク構成ですが 元のハンズオンと同一の構成 になります。 手順通りにCloudFormationのテンプレートから環境を構築すると、Ubuntu BastionというEC2インスタンスが立ち上がります。 必要なファイルが全てダウンロードされた状態で立ち上がるため、必要項目を編集したり、Docker Containerをbuildしたりします。 Pythonスクリプトが用意されており、これを実行するとAWS BatchにJobが投入され、オートスケールするEC2インスタンスによってJobが実行されます。

流体シミュレーションを行うソフトウェアとして OpenFOAM を使用します。 チュートリアルの1つであるpitzDailyの流入境界条件を変えて、計720通りのシミュレーションを実行します。 流入速度のx成分, y成分, z成分を、一定の範囲内で変化させます。 以下に、主要な計算結果をparaFoamで可視化した例を示します(流入速度のz成分は以下の全条件で0に設定しています)。

速度ベクトルの大きさをコンターで、StreamTracerを白線で表示

速度ベクトルの大きさのコンターのみ表示

StreamTracerの白線のみ表示

手順

はじめにCloudFormationのテンプレートをダウンロードしておきます。

CloudFormationによる環境構築

AWSマネジメントコンソールにログインし、リージョンを"US West(Oregon)"に設定します。まずはEC2へのSSH接続で使用するキーペアを作成する必要があるため、"EC2"をクリックします。
"Key Pairs", "Create Key Pair"の順にクリックし、作成するキーペアの名前を入力して"Create"をクリックします。秘密鍵(.pemファイル)のダウンロードウィンドウが開くので、なくさずに かつ 漏洩させずに保管しておきます
次に環境構築をするため、マネジメントコンソールのトップ画面で"CloudFormation"をクリックします。CloudFormationをはじめて使う場合、以下のような画面が開くので"Create New Stack"を選択します
「ファイルを選択」のボタンをクリックし、先ほどダウンロードしたCloudFormationのテンプレートを選択します。その後"Next"をクリックします
次の画面で各設定項目を入力します

項目名 詳細
Stack name CloudFormationのstackの名称です。迷ったら openfoam-batch-stack とでもしておきましょう
BucketName 流体シミュレーションの結果ファイルを保存するS3バケットの名称です。新規で作成されるので、全世界で一意である必要があります。 [AWS Account ID]-openfoam-batch-bucket などがおすすめです
ECRName Dockerコンテナを管理するECR(EC2 Container Registry)の名称です。迷ったら openfoam-batch とでもしておきましょう
InstanceTypeParameter Ubuntu Bastionのインスタンスタイプです。今回の手順通りの内容であればt2.microで十分動作します
KeyPairName Ubuntu BastionへのSSH接続で使用するキーペアの名称です。先ほど作成したキーペアの名前(拡張子なし)を入力します

ページ下部までスクロールし、IAMリソースが作成されることを理解してチェックを入れ、"Create"をクリックします
これでCloudFormationによる環境自動構築が始まります。自動的にUbuntu Bastionがlaunchされ、 こちら のGitHubのリポジトリがcloneされます。マネジメントコンソールではCloudFormationのStack一覧が表示されるので、StatusがCREATE_COMPLETEになるのを待ちます。

AWS Batchの設定とジョブの投入

Ubuntu BastionにSSH接続します。接続先IPアドレスは、CloudFormationのOutputsに記載されています
AWS CLIとDockerがインストールされていることを確認します

$ aws --version
aws-cli/1.11.170 Python/2.7.12 Linux/4.4.0-1020-aws botocore/1.7.28
$ docker --version
Docker version 17.09.0-ce, build afdb6d4

各種ファイルがGitHubからcloneされていることを確認します

$ cd /home/ubuntu/openfoam-docker
$ ll
total 64
drwxr-xr-x 3 root   root   4096 Oct 16 05:18 ./
drwxr-xr-x 5 ubuntu ubuntu 4096 Oct 16 05:32 ../
-rwxr-xr-x 1 root   root   8203 Oct 16 05:18 aws_batch_base.yml*
-rwxr-xr-x 1 root   root    831 Oct 16 05:18 bastion_setup.sh*
-rwxr-xr-x 1 root   root   1022 Oct 16 05:18 commands.sh*
-rwxr-xr-x 1 root   root    608 Oct 16 05:18 computing_env.json*
-rwxr-xr-x 1 root   root   1185 Oct 16 05:18 Dockerfile*
drwxr-xr-x 8 root   root   4096 Oct 16 05:18 .git/
-rwxr-xr-x 1 root   root    499 Oct 16 05:18 job_definition.json*
-rwxr-xr-x 1 root   root    187 Oct 16 05:18 job_queue.json*
-rwxr-xr-x 1 root   root    601 Oct 16 05:18 openfoam_run.sh*
-rwxr-xr-x 1 root   root   1328 Oct 16 05:18 README.md*
-rwxr-xr-x 1 root   root   1357 Oct 16 05:18 submit_batch.py*
-rwxr-xr-x 1 root   root   1290 Oct 16 05:18 U_template*

openfoam_run.sh を開き、S3のバケット名を編集します

$ sudo vi openfoam_run.sh

Dockerのコンテナをbuildします

$ sudo docker build -t openfoam-batch:latest .

ここから、buildしたコンテナをECRに保存していきます。まずは以下のコマンドでログインコマンドを取得します

$ aws --region us-west-2 ecr get-login --no-include-email

長いログインコマンドが返ってくるので、先頭にsudoをつけて実行します。"Login Succeeded"と表示されれば成功です
コンテナにタグ付けし、ECRにプッシュします

$ sudo docker tag openfoam-batch:latest [YourAwsAccountID].dkr.ecr.us-west-2.amazonaws.com/openfoam-batch:latest
$ sudo docker push [YourAwsAccountID].dkr.ecr.us-west-2.amazonaws.com/openfoam-batch:latest

ここからAWS Batchの設定を行い、ジョブを投入します。job_definition.json, computing_env.json, job_queue.jsonの3ファイルに、AWS Batchの設定が記述されています
まずはjob_definition.jsonを編集します

$ sudo vi job_definition.json

次にcomputing_env.jsonを編集します

$ sudo vi computing_env.json

job_queue.jsonは編集の必要はありません
以下のAWS CLIの3つのコマンドで、Job Definition, Compute Environment, Job Queueをそれぞれ作成します

$ aws --region us-west-2 batch register-job-definition --cli-input-json file://job_definition.json
$ aws --region us-west-2 batch create-compute-environment --cli-input-json file://computing_env.json
$ aws --region us-west-2 batch create-job-queue --cli-input-json file://job_queue.json

最後にジョブ投入スクリプト submit_batch.py を実行します。"Submitted JOB_00001 as ..."のようなコメントが返ってくれば成功です

$ python submit_batch.py
Submitted JOB_00001 as [Job ID]
Submitted JOB_00002 as [Job ID]
Submitted JOB_00003 as [Job ID]

マネジメントコンソールでAWS Batchのダッシュボードを見ると、ジョブの状態が変わっていくのが確認できます また、EC2が自動でlaunchされ処理が終わるとterminateされる様子も、マネジメントコンソールのEC2インスタンス一覧で見ることができます

リソースの削除

「今回構築した環境をしばらく使わないが、後日また使いたい」という場合は、Ubuntu Bastionをstopさせておくのがよいでしょう。 もし「もう環境を使わなくなったのできれいさっぱり全てを削除したい」という場合は、以下の手順で行ってください。 まず、マネジメントコンソールのAWS Batchの画面より、Job Queueの無効化(Disable)と削除(Delete)をします 次にCompute Environmentも無効化して削除します Job Definitionも削除(Deregister)します 続いてS3バケット内のすべてのファイルを削除します。これをやっておかないと、後ほどCloudFormationのstackを削除するときに失敗します ECSのリポジトリも削除します 最後に、CloudFormationのstackを削除します。これを行うと、Ubuntu BastionやS3バケットが削除されます

料金

上記の処理を行うのに必要な料金をおおまかに試算してみます。結論としては$1弱くらいで処理できたと見積もられます

今回、ジョブの実行環境は最大200vCPUまでスポットインスタンスでスケールアウトするように設定しています(computing_env.jsonに記載)。私のAWSアカウントで実行したところ、以下の内容でEC2インスタンスが立ち上がりました

インスタンスタイプ (A)インスタンス1台当たりのvCPU (B)Launchされたインスタンス数 (A)×(B)
c4.8xlarge 36 5 180
c4.4xlarge 16 1 16
c4.xlarge 4 1 4
合計 200

まずオンデマンドインスタンスであった場合の料金を試算すると以下のようになります

インスタンスタイプ (B)Launchされたインスタンス数 (C)インスタンス1台当たりの価格/h (オンデマンド) (B)×(C)
c4.8xlarge 5 $1.591 $7.955
c4.4xlarge 1 $0.796 $0.796
c4.xlarge 1 $0.199 $0.199
合計 $8.95

スポットインスタンスの入札価格は、オンデマンド価格の40%に設定している(computing_env.jsonの"bidPercentage"として記載)ので、1時間あたりの価格は最大で
$8.95 × 0.4 = $3.58
となります。今回の処理は、15分程度でインスタンスのterminateまで完了したため、計算環境の利用料は
$3.58 × 15 / 60 = $0.895
と試算されますので、$1弱くらいと見積もられます

まとめ

AWS Batchで、OpenFOAMによる流体シミュレーションを複数条件で同時実行し、利用料金を試算しました。秒単位での請求になったことで、利用料金の増加なしで1時間未満まで処理時間を短縮できるようになりました。スポットインスタンスと組み合わせてお得にシミュレーションジョブを流しましょう