前回の記事では、HPC用途に特化したコンテナSingularityをAmazon EC2で動かしました。EC2インスタンスにSingularityをインストールし、OpenFOAMのコンテナをつくったり(build)実行したり(exec)してみました。ただし前回使用した環境はEC2インスタンスを1台立てただけであったため、大量のジョブを投入したり、複数のコアを使用するジョブを実行するには不向きでした。
AWS上にEC2ベースでクラスタを立ち上げられるツールとしてCfnClusterがあります。これを使うと、ジョブスケジューラを含んだMasterノードと、 Auto Scalingにより増減するComputeノードから成るクラスタ環境を容易に構築できます。
この記事では、CfnClusterを使用してSingularityが動作するクラスタ環境を構築し、OpenFOAMでParameter Sweepをするジョブを投入してみます。またジョブの実行結果をGUIで可視化します。最後に、この環境を使用するのに要したAWS利用料を確認します。
構成図
今回構築する環境の構成は以下の図の通りです。ただし、CfnClusterにより構築される管理用のリソース(DynamoDBなど)は省略しています。
この記事で構築する環境は、3種類の役割を持ったサーバで構成されます。PrePost, Master, Computeの3種類です。
PrePost(OS: Ubuntu)
このEC2インスタンスには、CfnClusterがインストールされています。ここで [$ cfncluster] コマンドを実行することにより、クラスタの作成、削除、管理ができます。また手順の後半ではここにGUIをインストールして、クラスタで実行されたジョブの実行結果を可視化します。
Master(OS: Amazon Linux)
このEC2インスタンスは、CfnClusterによって起動し管理されます。ジョブスケジューラがインストールされており、[$ qsub] などのコマンドを実行することでジョブの投入・確認・削除や、Computeノードの状態確認ができます。
Compute(OS: Amazon Linux)
このEC2インスタンス群はAuto Scaling Groupに所属しており、Masterでのジョブ投入状況によって増減します。今回の手順通りに環境を構築すると、0台から10台の範囲で増減します。OpenFOAMによる流体解析はこのインスタンス群で実行されます。
CfnClusterの機能により、MasterとComputeの間ではNFSによりディスクが共有されます。OpenFOAMのジョブは、Singularity Hubからダウンロードしたコンテナを使って実行しますが、コンテナはこの共有されたディスクに保存されます。
投入するジョブについて
こちらのAWS Batchに関する記事と同様、OpenFOAMのチュートリアルの1つであるpitzDailyの流入境界条件を変えて、計720通りのシミュレーションを実行します。流入速度のx成分, y成分, z成分を、一定の範囲内で変化させます。せっかくSingularityを使うのでMPIを使用するジョブを流したいところですが、それはfuture workとします。
やってみる
EC2へのSSH接続用Key Pairの作成
AWSマネジメントコンソールにログインし、お好みのリージョンを選択します。まずはEC2へのSSH接続で使用するキーペアを作成する必要があるため、"EC2"をクリックします。"Key Pairs", "Create Key Pair"の順にクリックし、作成するキーペアの名前を入力して"Create"をクリックします。秘密鍵(.pemファイル)のダウンロードウィンドウが開くので、なくさずに かつ 漏洩させずに保管しておきます。
PrePostインスタンスの構築
VPC, Subnet, PrePostインスタンスなどを構築するため、CloudFormationを使用します。まず、使用するテンプレートをこちらからダウンロードしておきます。次に、マネジメントコンソールのトップ画面で"CloudFormation"をクリックします。CloudFormationをはじめて使う場合、以下のような画面が開くので"Create New Stack"を選択します。
「ファイルを選択」のボタンをクリックし、先ほどダウンロードしたCloudFormationのテンプレートを選択します。その後"Next"をクリックします
次の画面で各設定項目を入力します
IAMリソースが作成されることを理解してチェックを入れ、"Create"をクリックします。
これでCloudFormationによる環境自動構築が始まります。自動的にPrePostがlaunchされ、CfnClusterがインストールされます。
CfnClusterによるクラスタの構築
ここから、構築されたPrePostにSSH接続し、CfnClusterを実行してクラスタ(MasterおよびComputeノード)を構築します。CloudFormation stackのOutputs欄に、[PrePostIp] という項目でPrePostのグローバルIPが表示されています。
このIPに対して、以下の認証情報でSSH接続します。
SSH接続できたら、以下のコマンドを実行して、CfnClusterの設定ファイルを開きます。
このファイルの内容が表示されるはずです。修正すべきか所が、{Region}, {AccessKey}のように{ }つきで表示されています。それぞれ、CloudFormation stackのOutputs欄に表示されている内容に修正します。
この設定ファイルでは、2種類のクラスターテンプレートを定義しています。1つめのt2_singularityは、全てのノードがt2.microで起動します。クラスタでジョブを意図したとおりに実行できるかを、少量のジョブを投入しながら確認するときなどにおすすめです。2つめのc4_singularityは、全てのノードがc4.xlargeで起動し、同一のPlacement Groupに所属します。こちらは大量にジョブを実行する際におすすめです。どちらのクラスタにもSingularityが自動的にインストールされます。Computeノードは0台から10台の間で自動的に増減し、spotインスタンスで起動します。
今回はc4_singularityの設定でクラスタを起動します。以下のコマンドを実行すると、クラスタが自動で構築されます。
ちなみに、設定ファイルのcluster_template = t2_singularityの部分でデフォルトをt2_singularityにしているため、-tオプションなしだとt2_singularityの設定で構築されます。構築が完了すると、以下のようにMasterのIPアドレスが標準出力されます。
Masterでのジョブの投入
表示されたMasterのグローバルIPに対して、以下の認証情報でSSH接続します。
SSH接続できたら、以下のコマンドを実行します。
submit_batch.pyは、OpenFOAMのコンテナをダウンロードした後、pitzDailyの流入境界条件を少しづつ変えながら720のジョブを投入します。最後に$ qstatを実行し、投入されたジョブの一覧を表示します。ジョブが投入されてからComputeノードがlaunchされるため、ジョブの完了まで少々時間がかかります(CfnClusterの設定ファイルでinitial_queue_sizeを増やしておくと、常時その台数のComputeノードが起動するため、即ジョブが実行されるようになります)。
可視化までやってみたい方は、この待ち時間の間に計算結果の可視化の項の最初のコマンドを実行しておくのがおすすめです。ジョブが完了してから$ lsをすると、計算結果を格納した各ジョブごとのディレクトリがあることが分かります。
計算結果の可視化
せっかく計算ができたので、PrePostにOpenFOAMとGUIをインストールして、結果を可視化してみます。計算結果のファイルは、保存されているディスクMasterの/home)をPrePostにNFSマウントして読み込みます。以下の手順ではX2GoとUbuntu MATEを使用しますが、他にお好みのGUIがあればそれをご使用ください。
PrePostにSSH接続して、以下のコマンドを実行します。
wgetで入手しているinstall_openfoam_gui.shには、OpenFOAM, X2Go ServerとUbuntu MATEのインストールコマンドが記載されています。インストール完了まで時間がかかるので、しばらく待ちます。
インストールが完了したら、X2GoクライアントでPrePostに接続します。X2Goクライアントの使い方は、CFD Directのこちらのページが参考になります。接続できたら、NFSマウントに必要なツールをインストールし、マウントポイントを作成します。ターミナルを立ち上げて以下のコマンドを実行します。
NFSマウントのための通信ができるよう、AWSのマネジメントコンソールからSecurity Groupの設定を変更します。cfncluster-cluster01-ComputeSecurityGroup-xxxxxxxxxxxxxのような名前のSecurity Groupがあるので、PrePostをこれに加えます。
以下の{MasterPrivateIp}を置き換えてPrePostで実行すると、NFSマウントができます。
マウントが出来たら、OpenFOAM実行用ディレクトリ$FOAM_RUNを作成し、計算結果ファイルをそこにコピーして可視化します。コマンドとしては、例えばJob ID 1の実行結果を可視化する場合、以下の内容になります。
ParaViewが起動すれば成功です。表示内容をもろもろ設定すると、以下のように計算結果が表示されます。
環境の削除
構築した環境をもう使わないのであれば、削除してAWS利用料がかからないようにします。その手順を以下に示します。
まず、変更したPrePostのSecurity Groupを元に戻します。これをやっておかないと、クラスタの削除が途中で止まってしまいます。
次にPrePostで以下のコマンドを実行し、クラスタを削除します。
最後に、CloudFormationのstackを削除し、PrePost(EC2), Subnet, VPCなどを削除します。
AWS利用料金の確認
私は上記の手順を、Singaporeリージョン(ap-southeast-1)で一通り実行しました。私が検証で使用したAWSアカウントでは、同リージョンには他のリソースが一切なく、上記手順のために要したAWS利用料金を把握しやすいためです。AWSマネジメントコンソールで確認したところ、0.57米ドルで実行できたようです
まとめ
本記事ではCfnClusterで構築したクラスタでSingularityを動作させました。これにより、コンテナの利便性、ジョブ量に応じた計算ノードの自動増減、MPIの利用の3つの要素を並立することができます。サンプルのジョブとしてOpenFOAMのチュートリアルの1つであるpitzDailyを720ケース実行しました。今回のサンプルジョブはMPIは使用していないので、機会があればMPIを使ったジョブが実行できるか試してみたいです。