AWS ParallelCluster では、クラスターのコンフィグファイルからカスタムブートストラップスクリプトに引数を渡すことができます。要はクラスター毎に使い回し可能なスクリプトととなる可能性を秘めています。
本記事では、Mountpoint for Amazon S3 を ParallelCluster に組み込む処理を例に、この機能を検証した結果を共有します。
# 例
CustomActions:
OnNodeConfigured:
Sequence:
- Script: s3://example-bucket/mount.sh # 汎用的に使いわせるようにスクリプトを用意
Args:
- hoge # 引数をクラスターのコンフィグから渡したい
AWS ParallelCluster + Mountpoint 構成
AWS HPC レシピのサンプルコードを確認したところ、Mountpoint for Amazon S3 のカスタムブートストラップスクリプトが紹介されていました。 汎用的に使い回せる書き方をされており良かったので、実装を方法をよりシンプルにアレンジして試してみました。
ParallelCluster で Mountpoint for Amazon S3 を利用する構成は過去に私も紹介しています。CloudFromation で必要な IAM ポリシーを生成できて便利ですので、詳しい設定方法は以下のブログをご覧ください。
カスタムブートストラップスクリプトの書き方
必要なパッケージをインストールするスクリプトと、S3 バケットをマウントするスクリプトの 2 つを作成し、任意の S3 バケットに保存します。
インストールスクリプト
Mountpoint for Amazon S3 のコマンドであるmount-s3
をインストールするスクリプト(install.sh
)を作成しました。
#! /bin/bash
sudo apt-get update
sudo apt-get install libfuse2 -y
wget -P /tmp https://s3.amazonaws.com/mountpoint-s3-release/latest/x86_64/mount-s3.deb
sudo apt-get install /tmp/mount-s3.deb -y
Ubuntu 22.04 の場合はlibfuse2
を追加インストールする必要があります。詳細は以下の記事をご覧ください。
マウントスクリプト
S3 バケット名、マウントするディレクトリ、mount-s3
コマンドのオプションを引数として受け取り、実行するスクリプト(mount.sh
)です。書き方は一般的な Bash スクリプトと同じでした。
#! /bin/bash
BUCKET_NAME=$1
TARGET_DIRECTORY=$2
OPTIONS=$3
echo "#--- Start of Mount Process ---#"
echo ${BUCKET_NAME}
echo ${TARGET_DIRECTORY}
echo ${OPTIONS}
sudo mkdir -p ${TARGET_DIRECTORY}
sudo mount-s3 ${OPTIONS} ${BUCKET_NAME} ${TARGET_DIRECTORY}
echo "#--- End of Mount Process---#"
クラスターコンフィグの書き方
設定箇所にコメントを書きました。OnNodeConfigured:
セクションが本検証のポイントです。
CustomActions:
OnNodeConfigured:
Sequence: # スクリプトを複数個実行する場合は Sequence: セクション配下に指定が必要
- Script: s3://hpc-custom-boostrap-files/mountpoint-for-ubuntu22/install.sh # 作成したインストールスクリプトの保存パス
- Script: s3://hpc-custom-boostrap-files/mountpoint-for-ubuntu22/mount.sh # 作成したマウントスクリプトの保存パス
Args: # 作成したスクリプトに合わせて引数 3 つ渡す
- hpc-dev-mountpoint-sample-1 # マウントするS3バケット名
- /mnt/s3/sample-1 # マウントポイントのディレクトリパス
- "--allow-delete --allow-other --debug" # mount-s3コマンドのオプション
Iam:
AdditionalIamPolicies:
- Policy: arn:aws:iam::aws:policy/AmazonSSMManagedInstanceCore
- Policy: arn:aws:iam::0123456789012:policy/hpc-dev-AllowMountpointForS3 # Mountpoint for Amazon S3 用の権限必須
S3Access:
- BucketName: hpc-custom-boostrap-files # カスタムブートストラップスクリプトを保存してある S3 バケットへのアクセス権を付与
EnableWriteAccess: false
クラスターコンフィグ全文
今回の検証に使用したクラスターのコンフィグは以下になります。こちらのコンフィグから ParallelCluster 3.9 のクラスター環境を構築しました。
Region: ap-northeast-1
Image:
Os: ubuntu2204
Tags:
- Key: Name
Value: TokoroScalpo390
# ----------------------------------------------------------------
# Head Node Settings
# ----------------------------------------------------------------
HeadNode:
InstanceType: t3.micro
Networking:
ElasticIp: false
SubnetId: subnet-0c82bb28e119e2aa8
Ssh:
KeyName: org-sandbox-keypair
LocalStorage:
RootVolume:
Size: 40
Encrypted: true
VolumeType: gp3
Iops: 3000
Throughput: 125
Iam:
AdditionalIamPolicies:
- Policy: arn:aws:iam::aws:policy/AmazonSSMManagedInstanceCore
- Policy: arn:aws:iam::012345679012:policy/hpc-dev-AllowMountpointForS3
S3Access:
- BucketName: hpc-custom-boostrap-files
EnableWriteAccess: false
# ----------------------------------------------------------------
# Compute Node Settings
# ----------------------------------------------------------------
Scheduling:
Scheduler: slurm
SlurmSettings:
ScaledownIdletime: 5
SlurmQueues:
# ------ Test 1 ------
- Name: test1
ComputeResources:
- Name: test1
Instances:
- InstanceType: t3.micro
- InstanceType: t3a.micro
MinCount: 0
MaxCount: 20
DisableSimultaneousMultithreading: true
ComputeSettings:
LocalStorage:
RootVolume:
Size: 40
Encrypted: true
VolumeType: gp3
Iops: 3000
Throughput: 125
CapacityType: SPOT
AllocationStrategy: capacity-optimized
Networking:
SubnetIds:
- subnet-0c82bb28e119e2aa8
- subnet-0296a0c8515ed3bdc
- subnet-0089ff187d1f54258
PlacementGroup:
Enabled: false
Iam:
AdditionalIamPolicies:
- Policy: arn:aws:iam::aws:policy/AmazonSSMManagedInstanceCore
S3Access:
- BucketName: hpc-custom-boostrap-files
EnableWriteAccess: false
# ------ Compute 1 ------
- Name: queue1
ComputeResources:
- Name: queue1
Instances:
- InstanceType: m7i.2xlarge
- InstanceType: m7a.xlarge
MinCount: 0
MaxCount: 10
DisableSimultaneousMultithreading: true
ComputeSettings:
LocalStorage:
RootVolume:
Size: 40
Encrypted: true
VolumeType: gp3
Iops: 3000
Throughput: 125
CapacityType: SPOT
AllocationStrategy: capacity-optimized
Networking:
SubnetIds:
- subnet-0c82bb28e119e2aa8
- subnet-0296a0c8515ed3bdc
- subnet-0089ff187d1f54258
PlacementGroup:
Enabled: false
CustomActions:
OnNodeConfigured:
Sequence:
- Script: s3://hpc-custom-boostrap-files/mountpoint-for-ubuntu22/install.sh
- Script: s3://hpc-custom-boostrap-files/mountpoint-for-ubuntu22/mount.sh
Args:
- hpc-dev-mountpoint-sample-1
- /mnt/s3/sample-1
- "--allow-delete --allow-other --debug"
Iam:
AdditionalIamPolicies:
- Policy: arn:aws:iam::aws:policy/AmazonSSMManagedInstanceCore
- Policy: arn:aws:iam::012345679012:policy/hpc-dev-AllowMountpointForS3
S3Access:
- BucketName: hpc-custom-boostrap-files
EnableWriteAccess: false
# ----------------------------------------------------------------
# Shared Storage Settings
# ----------------------------------------------------------------
SharedStorage:
- MountDir: /mnt/hpc-dev-efs-for-parallelcluster
Name: efs1
StorageType: Efs
EfsSettings:
FileSystemId: fs-0846dc947572a66a1
# ----------------------------------------------------------------
# Other Settings
# ----------------------------------------------------------------
Monitoring:
Logs:
CloudWatch:
Enabled: true
RetentionInDays: 180
DeletionPolicy: "Delete"
Dashboards:
CloudWatch:
Enabled: true
S3 バケットがマウントされるか動作確認
Mountpoint for Amazon S3 でコンピュートノードにマウントする S3 バケットには、テストファイルを保存してあります。コンピュートノードからこのファイルを確認できるか検証します。
コンピュートノードを起動
ジョブをサブミットしてコンピュートノードを起動させました。セッションマネージャで接続しマウント状況を確認します。
/mnt/s3
配下にsample-1
ディレクトリが作成されています。
ubuntu@queue1-dy-queue1-1:/mnt/s3$ ll
total 8
drwxr-xr-x 3 root root 4096 Apr 6 05:31 ./
drwxr-xr-x 4 root root 4096 Apr 6 05:31 ../
drwxr-xr-x 2 root root 0 Apr 6 05:31 sample-1/
sample-1
ディレクトリを確認すると、S3 バケットに保存してあるテキストファイルを確認できました。
ubuntu@queue1-dy-queue1-1:/mnt/s3/sample-1$ ll
total 4
drwxr-xr-x 2 root root 0 Apr 6 05:31 ./
drwxr-xr-x 3 root root 4096 Apr 6 05:31 ../
-rw-r--r-- 1 root root 0 Apr 6 04:15 YouCanLookThisFileFromS3.txt
今回作成したカスタムブートストラップスクリプトにより正常に S3 バケットをコンピュートノードにマウントを確認できました。
トラブルシュート
カスタムブートストラップスクリプトを編集後にスクリプトの記述ミスなどの理由によりコンピュートノードが起動失敗を繰り返すことをよくやります。今回も 1 時間ほど時間を溶かしました。
スクリプトがどこまで進んだのか、エラーはなにかは CloudWatch Logs に保存されるログを確認するのがオススメです。理由はコンピュートノードはテンポラリなため、起動に失敗するとターミネートされログインしてログ確認ができないからです。
オススメの確認先
.bootstrap_error_msg
と.syslog
のログイベントが切り分けに役立ちます。実際のログイベントにはプリフィックスとして、起動したコンピュートノードのプライベート IP とインスタンス ID がつきます。
ブートストラップエラーログ
カスタムブートストラップスクリプトにエラーがあると、.boostrap_error_msg
というログイベントが作成されます。
ip-10-0-1-117.i-0e4b44ca6b5b26d86.bootstrap_error_msg
メッセージ内容を確認するとstderr
の項目でスクリプトの実行エラー文を確認できます。ここを手がかりに切り分けをはじめられます。
{
"datetime": "2024-04-06T04:34:27.017+00:00",
"version": 0,
"scheduler": "slurm",
"cluster-name": "TokoroScalop390",
"node-role": "ComputeFleet",
"component": "custom-action",
"level": "ERROR",
"instance-id": "i-0e4b44ca6b5b26d86",
"compute": {
"name": "queue1-dy-queue1-2",
"instance-id": "i-0e4b44ca6b5b26d86",
"instance-type": "m7a.xlarge",
"availability-zone": "ap-northeast-1a",
"address": "10.0.1.117",
"hostname": "ip-10-0-1-117.ap-northeast-1.compute.internal",
"queue-name": "queue1",
"compute-resource": "queue1",
"node-type": "dynamic"
},
"event-type": "custom-action-error",
"message": "Failed to execute OnNodeConfigured script 2, return code: 2.",
"detail": {
"action": "OnNodeConfigured",
"step": 2,
"stage": "executing",
"error": {
"exit_code": 2,
"stderr": "error: unexpected argument 'hpc-dev-mountpoint-sample-1' found\n\nUsage: mount-s3 [OPTIONS] <BUCKET_NAME> <DIRECTORY>\n\nFor more information, try '--help'.\n"
}
}
}
シスログ
こちらはシスログをウォッチできるためコンピュートノード起動中にモニタリングしておくと順調か、ダメそうなのかニアリアルタイムに確認できます。
ip-10-0-1-38.i-0ab9efe2c6023ed5f.syslog
おわりに
コンピュートノードへの S3 バケットマウントは、カスタムブートストラップスクリプトを工夫することで汎用的な作りにできました。複数のクラスター間でマウントスクリプトを使いまわしやすくなりました。しばらく運用してみて使用感を確認してみます。
本記事ではコンピュートノードへの S3 バケットマウントを実現しましたが、ヘッドノードへのマウントが前々からの課題です。 AWS HPC レシピにサービス化して実現するサンプルコードが載っていたので、次はそちらを検証し、ヘッドノードへのマウント方法を共有できればと思います。