AWS ParallelClusterでHPCクラスタをお手軽に構築してみる

アイキャッチ HPC

AWS上にHPC(High Performance Computing)環境を構築するツールCfnClusterの後継として、AWS ParallelClusterが2018/11/13にリリースされました。

個人的に、前々職でHPC関係の仕事を長くやっていたこともあって興味があり、取り急ぎ触ってみましたのでご紹介します。

AWS ParallelClusterとは

MPIなどを利用した並列計算を行うための環境を、コマンド1つでAWS上に構築できるツールです。 また、計算ノードは実行時に自動的に生成され、完了したら自動的に削除されるので、効率よく実行することができます。

これまではCfnClusterという名前で開発されていました。ブログによるとAWS Parallel Clusterでは以下が追加されたとのことです。

  • AWS Batch integration
  • Multiple EBS volumes
  • Better scaling performance – faster, with updates AutoScaling all at once
  • Support for “bring your own AMI” Custom AMI
  • Private cluster using proxy

ちなみに前身のCfnClusterについては下記の記事で紹介されています。
始めてみよう CfnClusterでHPCクラスター

Getting Started

とりあえず動かしてみます。なお、自分のローカル環境はMacBook Pro, macOS High Siera 10.13.6 です。

準備

以下が必要です。

  • IAMユーザ
    • AdministratorAccessポリシーをアタッチ
    • アクセスキーを発行
  • キーペア
  • VPC
  • サブネット

インストール

pipでインストールします。 *1

$ sudo pip install aws-parallelcluster

初期設定

pcluster configureコマンドで初期設定を行います。 *2

$ pcluster configure
Cluster Template [default]:
AWS Access Key ID []:
AWS Secret Access Key ID []:
You chose not to configure aws credentials in parallelcluster config file.
Please make sure you export a valid AWS_PROFILE or you have them exported in the AWS_ACCESS_KEY_ID and AWS_SECRET_ACCESS_KEY environment variables.
Acceptable Values for AWS Region ID:
    ap-south-1
    eu-west-3
    eu-west-2
    eu-west-1
    ap-northeast-2
    ap-northeast-1
    sa-east-1
    ca-central-1
    ap-southeast-1
    ap-southeast-2
    eu-central-1
    us-east-1
    us-east-2
    us-west-1
    us-west-2
AWS Region ID []: ap-northeast-1
VPC Name [public]:
Acceptable Values for Key Name:
    foo-keypair-1
Key Name []: foo-keypair-1
Acceptable Values for VPC ID:
    vpc-aaaaaaaa
VPC ID []: vpc-aaaaaaaa
Acceptable Values for Master Subnet ID:
    subnet-aaaaaaaa
    subnet-bbbbbbbb
    subnet-cccccccc
Master Subnet ID []: subnet-aaaaaaaa

正常に完了すると設定ファイルが作られます。

[aws]
aws_region_name = ap-northeast-1

[cluster default]
vpc_settings = public
key_name = foo-keypair-1

[vpc public]
master_subnet_id = subnet-aaaaaaaa
vpc_id = vpc-aaaaaaaa

[global]
update_check = true
sanity_check = true
cluster_template = default

[aliases]
ssh = ssh {CFN_USER}@{MASTER_IP} {ARGS}

クラスタ作成

pcluster createコマンドでクラスタを作成します。10分前後かかります。

$ pcluster create mycluster
Beginning cluster creation for cluster: mycluster
Creating stack named: parallelcluster-mycluster
Status: parallelcluster-mycluster - CREATE_COMPLETE
MasterPublicIP: xx.xxx.x.xxx
ClusterUser: ec2-user
MasterPrivateIP: xxx.xx.xx.xxx

完了するとEC2にMasterインスタンスが作られます。

ジョブ実行

Masterインスタンスにログインしてジョブを投入します。pcluster sshコマンドでログインできます(秘密鍵のパスは-iオプションで指定)。

$ pcluster ssh mycluster -i /path/to/keypair.pem
Last login: Wed Nov 14 01:59:42 2018 from xxxxxxx.xxxxxx.xxxx.xx.xx

       __|  __|_  )
       _|  (     /   Amazon Linux AMI
      ___|\___|___|

https://aws.amazon.com/amazon-linux-ami/2018.03-release-notes/
[ec2-user@ip-172-31-41-176 ~]$

インスタンスにはMPI (Open MPI) やジョブ管理システム (SGE) がセットアップされています。 まずqhostコマンドでジョブを実行するホストを見てみますが、何もありません。

[ec2-user@ip-172-31-41-176 ~]$ qhost
HOSTNAME                ARCH         NCPU NSOC NCOR NTHR  LOAD  MEMTOT  MEMUSE  SWAPTO  SWAPUS
----------------------------------------------------------------------------------------------
global                  -               -    -    -    -     -       -       -       -       -

qsubコマンドでジョブを投入します。ここでは並列数を8にしています *3。 warningが出ることがありますがとりあえず気にしなくて良いようです。

[ec2-user@ip-172-31-41-176 ~]$ echo /usr/lib64/openmpi/bin/mpirun hostname | qsub -pe mpi 8
Unable to run job: warning: ec2-user's job is not allowed to run in any queue
Your job 1 ("STDIN") has been submitted
Exiting.
[ec2-user@ip-172-31-41-176 ~]$ qstat
job-ID  prior   name       user         state submit/start at     queue                          slots ja-task-ID
-----------------------------------------------------------------------------------------------------------------
      1 0.55500 STDIN      ec2-user     qw    11/14/2018 03:14:27                                    8

しばらくすると、ジョブ実行インスタンスが自動的に生成され、qhostの出力は以下のようになります。生成されたインスタンスは、ジョブ完了後しばらくすると自動的に削除されます。

[ec2-user@ip-172-31-41-176 ~]$ qhost
HOSTNAME                ARCH         NCPU NSOC NCOR NTHR  LOAD  MEMTOT  MEMUSE  SWAPTO  SWAPUS
----------------------------------------------------------------------------------------------
global                  -               -    -    -    -     -       -       -       -       -
ip-172-31-32-34         lx-amd64        1    1    1    1  0.03  985.8M  142.4M     0.0     0.0
ip-172-31-38-123        lx-amd64        1    1    1    1  0.11  985.8M  140.8M     0.0     0.0
ip-172-31-38-189        lx-amd64        1    1    1    1  0.07  985.8M  141.7M     0.0     0.0
ip-172-31-41-27         lx-amd64        1    1    1    1  0.12  985.8M  168.8M     0.0     0.0
ip-172-31-43-160        lx-amd64        1    1    1    1  0.02  985.8M  140.1M     0.0     0.0
ip-172-31-44-237        lx-amd64        1    1    1    1  0.07  985.8M  140.7M     0.0     0.0
ip-172-31-46-27         lx-amd64        1    1    1    1  0.05  985.8M  141.1M     0.0     0.0
ip-172-31-47-126        lx-amd64        1    1    1    1  0.09  985.8M  141.4M     0.0     0.0

ジョブ実行時の標準出力はqsubを実行したディレクトリに生成されます。

[ec2-user@ip-172-31-41-176 ~]$ ls
STDIN.e1  STDIN.o1
[ec2-user@ip-172-31-41-176 ~]$ cat STDIN.o1
ip-172-31-32-34
ip-172-31-38-189
ip-172-31-44-237
ip-172-31-46-27
ip-172-31-41-27
ip-172-31-43-160
ip-172-31-38-123
ip-172-31-47-126

AWS Batchをスケジューラとして使う

AWS ParallelClusterでは、 SGEの代わりにAWS Batchをスケジューラとして利用できるようになりました。 とりあえず試してみました。

クラスタ作成

まず、設定ファイルを編集して以下の行を追加します。デフォルトのものと比べてscheduler = awsbatchが追加されています。

[cluster awsbatch]
scheduler = awsbatch
key_name = foo-keypair-1
vpc_settings = public

追加したら、pcluster createコマンドでクラスタを作成します。この時--cluster-templateオプションで先ほど追加したものを指定します。

$ pcluster create awsbatch --cluster-template awsbatch
Beginning cluster creation for cluster: awsbatch
Creating stack named: parallelcluster-awsbatch
Status: parallelcluster-awsbatch - CREATE_COMPLETE
MasterPublicIP: xx.xxx.xx.xx
BatchComputeEnvironmentArn: arn:aws:batch:ap-northeast-1:123456789012:compute-environment/parallelcluster-awsbatch
BatchJobQueueArn: arn:aws:batch:ap-northeast-1:123456789012:job-queue/parallelcluster-awsbatch
ClusterUser: ec2-user
MasterPrivateIP: xxx.xx.xx.xxx
ResourcesS3Bucket: parallelcluster-awsbatch-abcdefghijklmnop
BatchJobDefinitionArn: arn:aws:batch:ap-northeast-1:123456789012:job-definition/parallelcluster-awsbatch:1

完了すると、新しいMasterインスタンスがEC2に作成されます。

ジョブ実行

Masterインスタンスにログインしてジョブを投入します。まずはログインします。

$ pcluster ssh awsbatch -i /path/to/keypair.pem
Last login: Wed Nov 14 04:33:55 2018

       __|  __|_  )
       _|  (     /   Amazon Linux AMI
      ___|\___|___|

https://aws.amazon.com/amazon-linux-ami/2018.03-release-notes/
[ec2-user@ip-172-31-43-231 ~]$

AWS Batchを利用する場合は、qsub, qhostなどの代わりに awsbsub, awsbhostなどのコマンドを使用します。 以下はecho hello worldするだけの簡単なジョブを実行する例です。

[ec2-user@ip-172-31-43-231 ~]$ awsbsub echo hello world
Job 6fac000e-e899-4b84-be7b-ab468d337dd1 (echo) has been submitted.
[ec2-user@ip-172-31-43-231 ~]$ awsbstat
jobId                                 jobName    status    startedAt    stoppedAt    exitCode
------------------------------------  ---------  --------  -----------  -----------  ----------
6fac000e-e899-4b84-be7b-ab468d337dd1  echo       RUNNABLE  -            -            -

しばらくすると、ジョブ実行用のインスタンスが自動的に生成され、ジョブが実行されます。

[ec2-user@ip-172-31-43-231 ~]$ awsbhosts
ec2InstanceId        instanceType    privateIpAddress    publicIpAddress      runningJobs
-------------------  --------------  ------------------  -----------------  -------------
i-0c49a1839497fe8a0  c4.large        172.31.44.61        13.114.156.242                 1
[ec2-user@ip-172-31-43-231 ~]$ awsbstat
jobId                                 jobName    status    startedAt            stoppedAt    exitCode
------------------------------------  ---------  --------  -------------------  -----------  ----------
6fac000e-e899-4b84-be7b-ab468d337dd1  echo       RUNNING   2018-11-14 04:44:22  -           

実行結果のログは awsbout コマンドで確認します。

# 成功したジョブの一覧が取れる
[ec2-user@ip-172-31-43-231 ~]$ awsbstat -s SUCCEEDED
jobId                                 jobName    status     startedAt            stoppedAt              exitCode
------------------------------------  ---------  ---------  -------------------  -------------------  ----------
6fac000e-e899-4b84-be7b-ab468d337dd1  echo       SUCCEEDED  2018-11-14 04:44:22  2018-11-14 04:44:53           0

# ログを見てみる
[ec2-user@ip-172-31-43-231 ~]$ awsbout 6fac000e-e899-4b84-be7b-ab468d337dd1
2018-11-14 04:44:22: Starting Job 6fac000e-e899-4b84-be7b-ab468d337dd1
2018-11-14 04:44:22: hello world

なお、本当はマルチノードの並列ジョブを実行したかったのですが、awsbsubコマンドでの実行方法が分からず、実行できていません。 どうも元々はオプションで指定できたものが削除されていたりするようで、このあたりはまだ未完成なのかもしれません。

まとめ

AWS ParallelCusterを触ってみました。HPCの環境構築は手動でやると非常に手間がかかるもので、前々職および前職では色々と苦い思いをしてきたのですが、 コマンド1つでできてしまうことにちょっと感動しています(今時当たり前と言えば当たり前なんですが)。HPC関係のみなさんはぜひ一度触ってみていただければと思います。

参考文献

脚注

  1. リリース翌日にバグフィックスが行われ、記事執筆時の最新はv2.0.1です。
  2. 以降、IDなどは架空のものです。なお、ここではアクセスキーは環境変数AWS_PROFILEと ~/.aws/credentials で設定したものを使っています。
  3. デフォルトの設定ではインスタンスタイプがt2.micro(=vCPUが1個), Auto Scalingグループの最大キャパシティが10なようで、10並列を越えると実行できなくなるようです。 より大規模な計算には設定変更が必要です。