AWS ParallelCluster を使った HPC クラスターの運用において、データの共有方法と保存コストは大きな課題です。本記事では Mountpoint for Amazon S3 を活用し、ヘッドノードとコンピュートに S3 バケットの自動マウントを実現する方法を紹介します。これにより、クラスター間でのデータ共有と、コスト効率の高いデータの長期保存が可能になります。
構成概要
本記事で紹介する構成の概要を以下の図に示します。ヘッドノードとコンピュートノードに S3 バケットがマウントされます。ヘッドノードでは systemd サービスによって自動マウントが行われ、コンピュートノードでは起動時に mount-s3 コマンドが実行されます。
本記事の目的と解決する課題
以前、AWS ParallelCluster の Ubuntu 22.04 に対応した Moutpoint for Amazon S3 の利用方法を紹介しました。クラスターの運用をする中でいくつかの課題が見えてきたためブラッシュアップしました。
本記事では、以下の 2 点を改善した Mountpoint for Amazon S3 の活用方法を紹介します。
- カスタムブートストラップスクリプトと systemd を使ってヘッドノードに S3 バケットを自動マウントする
- クラスターのコンフィグからマウント設定を引数で渡し、マウント用スクリプトの再利用性を高める
これにより、S3 バケットのマウント作業を自動化し、運用の手間を削減できます。また、マウント設定をクラスターコンフィグで一元管理できるため、スクリプトの管理コストを抑えます。
それでは、具体的な手順を見ていきましょう。
実装手順
クラスター構築に必要な要素は大きく分けて 3 つあります。
- カスタムブートストラップスクリプト
- IAM ポリシー
- クラスターのコンフィグ
それぞれについて詳しく見ていきましょう。
カスタムブートストラップスクリプトの作成
カスタムブートストラップスクリプトは、ヘッドノードとコンピュートノードの起動時に実行されるスクリプトです。今回は以下の 3 つのスクリプトを用意しました。
- 共通 Mountpoint for Amazon S3 インストールスクリプト
- ヘッドノードとコンピュートノードの両方で実行され、Mountpoint for Amazon S3 をインストールします。
- コンピュートノード用 S3 バケットマウントスクリプト
- コンピュートノードの起動時に実行され、mount-s3 コマンドを使って S3 バケットをマウントします。
- マウントに必要な情報はクラスターのコンフィグから引数で渡します。
- ヘッドノード用 S3 バケットマウントスクリプト
- ヘッドノードの初回起動時に実行され、systemd サービスを作成して S3 バケットを自動マウントします。
- マウントに必要な情報はクラスターのコンフィグから引数で渡します。
共通 Mountpoint for Amazon S3 インストールスクリプト
ヘッドノード、コンピュートノードの初回起動時に Mountpoint for Amazon S3 をインストールします。
項目名 | 値 |
---|---|
ファイル名 | install.sh |
保存先 | 任意の S3 バケット |
#! /bin/bash
# Install mount-s3 command for Ubuntu 22.04
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
コンピュートノード用 S3 バケットマウントスクリプト
コンピュートノードの起動時にmount-s3
コマンドを実行し S3 バケットをマウントします。
コンピュートノードは、ジョブの実行に合わせて動的に起動・終了するため、起動のたびに mount-s3
コマンドでマウントを行う設定としています。
項目名 | 値 |
---|---|
ファイル名 | mount.sh |
保存先 | 任意の S3 バケット |
#! /bin/bash
BUCKET_NAME=$1
TARGET_DIRECTORY=$2
OPTIONS=$3
# Allow other users to access mount
# Needed if --allow-root or --allow-other option is set
if ! grep -q "^user_allow_other" /etc/fuse.conf
then
echo "user_allow_other" | sudo tee -a /etc/fuse.conf
fi
sudo mkdir -p ${TARGET_DIRECTORY}
sudo chmod 777 ${TARGET_DIRECTORY}
sudo mount-s3 ${OPTIONS} ${BUCKET_NAME} ${TARGET_DIRECTORY}
ヘッドノードノード用 S3 バケットマウントスクリプト
ヘッドノードノードの初回起動時に systemd で Moutpoint 用のサービスを作成します。以降はサービスの起動により S3 バケットを自動マウントします。コンピュートノードのスクリプトと同様にマウント対象の S3 バケットや、マウントパスはクラスターのコンフィグから引数で渡します。
項目名 | 値 |
---|---|
ファイル名 | mount-headnode.sh |
保存先 | 任意の S3 バケット |
#! /bin/bash
BUCKET_NAME=$1
TARGET_DIRECTORY=$2
OPTIONS=$3
# Generate a distinct identifier to allow multiple mountpoint-s3 services
SERVICE_ID=$(echo -n "${BUCKET_NAME}:${TARGET_DIRECTORY}" | md5sum | awk '{print $1}')
SERVICE_ID=${SERVICE_ID:0:8}
SERVICE_NAME="mountpoint-s3-${SERVICE_ID}"
# Allow other users to access mount
# Needed if --allow-root or --allow-other option is set
if ! grep -q "^user_allow_other" /etc/fuse.conf
then
echo "user_allow_other" | sudo tee -a /etc/fuse.conf
fi
# Create mount TARGET_DIRECTORY
sudo mkdir -p ${TARGET_DIRECTORY}
sudo chmod 777 ${TARGET_DIRECTORY}
# Create service file
tee > "${SERVICE_NAME}.service" <<EOF
[Unit]
Description=Mount s3://${BUCKET_NAME} at ${TARGET_DIRECTORY}
Wants=network-online.target
After=default.target
AssertPathIsTARGET_DIRECTORY=${TARGET_DIRECTORY}
[Service]
Type=forking
User=ubuntu
Group=ubuntu
ExecStart=/usr/bin/mount-s3 ${OPTIONS} ${BUCKET_NAME} ${TARGET_DIRECTORY}
ExecStop=/usr/bin/fusermount -u ${TARGET_DIRECTORY}
[Install]
WantedBy=default.target
EOF
# Install and start the service
sudo mv "${SERVICE_NAME}.service" /etc/systemd/system/
sudo systemctl daemon-reload
sudo systemctl enable "${SERVICE_NAME}"
sudo systemctl start "${SERVICE_NAME}"
IAM ポリシーの作成
S3 バケットをマウントするには、ヘッドノードとコンピュートノードにアクセス権限を付与する必要があります。今回は以下の IAM ポリシーを作成し、ヘッドノードとコンピュートノードの IAM ロールにアタッチします。
マウントした S3 バケット用にアクセスするための権限
マウント対象となる S3 バケットに対してヘッドノード、コンピュートノードからアクセスするために必要な権限を付与します。ヘッドノード、コンピュートノードからマウントした S3 バケットに対してファイルの読み書きができるように s3:DeleteObject
の権限を持たせています。
項目名 | 値 |
---|---|
ポリシー名 | hpc-dev-AllowMountpointForS3 |
アタッチ先 | ヘッドノード、コンピュートノードの IAM ロール(クラスターのコンフィグで指定) |
{
"Version": "2012-10-17",
"Statement": [
{
"Action": [
"s3:ListBucket"
],
"Resource": [
"arn:aws:s3:::hpc-dev-mountpoint-sample-1",
"arn:aws:s3:::hpc-dev-mountpoint-sample-2"
],
"Effect": "Allow"
},
{
"Action": [
"s3:GetObject",
"s3:PutObject",
"s3:AbortMultipartUpload",
"s3:DeleteObject"
],
"Resource": [
"arn:aws:s3:::hpc-dev-mountpoint-sample-1/*",
"arn:aws:s3:::hpc-dev-mountpoint-sample-2/*"
],
"Effect": "Allow"
}
]
}
以下のブログで、S3 バケットを作成と同時に上記の IAM ポリシーを作成する CloudFormation テンプレートを紹介しています。
クラスターのサンプルコンフィグ
クラスターのコンフィグを紹介します。ここではヘッドノードとコンピュートノードの設定を中心に解説します。
コンフィグファイル全文
先にコンフィグファイル全文を掲載します。
Region: ap-northeast-1
Image:
Os: ubuntu2204
Tags:
- Key: Name
Value: mountS3-v391
# ----------------------------------------------------------------
# Head Node Settings
# ----------------------------------------------------------------
HeadNode:
InstanceType: m7i-flex.large
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::123456789012:policy/hpc-dev-AllowMountpointForS3
S3Access:
- BucketName: hpc-custom-boostrap-files
EnableWriteAccess: 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-for-headnode.sh
Args:
- hpc-dev-mountpoint-sample-1
- /mnt/s3-readonly
- "--allow-delete --allow-other"
- Script: s3://hpc-custom-boostrap-files/mountpoint-for-ubuntu22/mount-for-headnode.sh
Args:
- hpc-dev-mountpoint-sample-2
- /mnt/s3
- "--allow-delete --allow-other"
# ----------------------------------------------------------------
# Compute Node Settings
# ----------------------------------------------------------------
Scheduling:
Scheduler: slurm
SlurmSettings:
ScaledownIdletime: 5
SlurmQueues:
# ------ Compute 1 ------
- Name: p1
ComputeResources:
- Name: m6idmetal
Instances:
- InstanceType: m6id.metal
MinCount: 0
MaxCount: 30
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
- Policy: arn:aws:iam::123456789012:policy/hpc-dev-AllowMountpointForS3
S3Access:
- BucketName: hpc-custom-boostrap-files
EnableWriteAccess: 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-readonly
- "--read-only --allow-other"
- Script: s3://hpc-custom-boostrap-files/mountpoint-for-ubuntu22/mount.sh
Args:
- hpc-dev-mountpoint-sample-2
- /mnt/s3
- "--allow-delete --allow-other"
# ----------------------------------------------------------------
# Shared Storage Settings
# ----------------------------------------------------------------
SharedStorage:
- MountDir: /mnt/efs-elastic
Name: efs1
StorageType: Efs
EfsSettings:
FileSystemId: fs-0846dc947572a66a1
- MountDir: /mnt/efs-bursting
Name: efs2
StorageType: Efs
EfsSettings:
FileSystemId: fs-046b02d3ba107c2b2
# ----------------------------------------------------------------
# Other Settings
# ----------------------------------------------------------------
Monitoring:
Logs:
CloudWatch:
Enabled: true
RetentionInDays: 180
DeletionPolicy: "Delete"
Dashboards:
CloudWatch:
Enabled: true
ヘッドノードの設定解説
AdditionalIamPolicies:
セクションで、マウントした S3 バケットへの必要なアクセス権限を付与した IAM ポリシーを指定します。
また、カスタムブートストラップスクリプトが保存されている S3 バケットへの権限が必要なため、S3Access:
セクションでスクリプト保存先の S3 バケットへ対して読み取り権限を付与しています。
Iam:
AdditionalIamPolicies:
- Policy: arn:aws:iam::aws:policy/AmazonSSMManagedInstanceCore
- Policy: arn:aws:iam::123456789012:policy/hpc-dev-AllowMountpointForS3
S3Access:
- BucketName: hpc-custom-boostrap-files
EnableWriteAccess: false
CustomActions:
セクションでは、ヘッドノードの起動時に実行するカスタムブートストラップスクリプトを指定します。
まず、install.sh
スクリプトで Mountpoint for Amazon S3 をインストールします。
次に、mount-for-headnode.sh
スクリプトを 2 回呼び出し、異なる S3 バケットを異なるマウントポイントにマウントしています。このスクリプトは、systemd サービスを作成し、ヘッドノードの起動時に自動的に S3 バケットをマウントします。
スクリプトの引数には、以下の 3 つを指定しています。
- マウント対象の S3 バケット名
- マウントするディレクトリのパス
mount-s3
コマンドのオプション指定
これにより、S3 バケット hpc-dev-mountpoint-sample-1
を /mnt/s3-readonly
にマウントし、hpc-dev-mountpoint-sample-2
を/mnt/s3
に同じスクリプトを利用してマウントを実現します。マウントオプションで --allow-delete
と --allow-other
を指定し、他のユーザーからのアクセスを許可しつつ、ファイルの削除を可能にしています。/mnt/s3-readonly
という名前なのに削除を許可している理由は、コンピュートノードとマウントするディレクトリ名を統一しているためです。ヘッドノードからは読み書きできた方が便利だったため、書き込めるようにしています。
CustomActions:
OnNodeConfigured:
Sequence:
- Script: s3://hpc-custom-boostrap-files/mountpoint-for-ubuntu22/install.sh
- Script: s3://hpc-custom-boostrap-files/mountpoint-for-ubuntu22/mount-for-headnode.sh
Args:
- hpc-dev-mountpoint-sample-1
- /mnt/s3-readonly
- "--allow-delete --allow-other"
- Script: s3://hpc-custom-boostrap-files/mountpoint-for-ubuntu22/mount-for-headnode.sh
Args:
- hpc-dev-mountpoint-sample-2
- /mnt/s3
- "--allow-delete --allow-other"
コンピュートノードの設定解説
コンピュートノードの設定は、ヘッドノードと同様にIam:
セクションで IAM ポリシーと S3 バケットへのアクセス権を付与しています。
Iam:
AdditionalIamPolicies:
- Policy: arn:aws:iam::aws:policy/AmazonSSMManagedInstanceCore
- Policy: arn:aws:iam::123456789012:policy/hpc-dev-AllowMountpointForS3
S3Access:
- BucketName: hpc-custom-boostrap-files
EnableWriteAccess: false
CustomActions:
セクションでは、コンピュートノードの起動時に実行するカスタムブートストラップスクリプトを指定します。
まず、install.sh
スクリプトで Mountpoint for Amazon S3 をインストールします。
次に、mount.sh
スクリプトを 2 回呼び出し、異なる S3 バケットを異なるマウントポイントにマウントしています。このスクリプトは、mount-s3
コマンドを使って S3 バケットをマウントします。
スクリプトの引数には、以下の 3 つを指定しています。
- マウント対象の S3 バケット名
- マウントするディレクトリのパス
mount-s3
コマンドのオプション指定
hpc-dev-mountpoint-sample-1
のマウントオプションでは、--read-only
を指定し、読み取り専用でマウントしています。一方、hpc-dev-mountpoint-sample-2
では、--allow-delete
を指定し、ファイルの削除を可能にしています。どちらのマウントポイントでも--allow-other
オプションを指定し、他のユーザーからのアクセスを許可しています。
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-readonly
- "--read-only --allow-other"
- Script: s3://hpc-custom-boostrap-files/mountpoint-for-ubuntu22/mount.sh
Args:
- hpc-dev-mountpoint-sample-2
- /mnt/s3
- "--allow-delete --allow-other"
動作検証
前述のサンプルコンフィグより構築したクラスターで Mountpoint for Amazon S3 が正常に動作することを確認します。ヘッドノードとコンピュートノードそれぞれで、S3 バケットがマウントされていることを検証します。
ヘッドノードのマウント状況確認
ヘッドノードにログインし、以下のコマンドを実行して Mountpoint for Amazon S3 のサービスが正常に起動していることを確認します。
$ systemctl list-units | grep mountpoint-s3
mountpoint-s3-585e79a6.service loaded active running Mount s3://hpc-dev-mountpoint-sample-2 at /mnt/s3
mountpoint-s3-91ef1212.service loaded active running Mount s3://hpc-dev-mountpoint-sample-1 at /mnt/s3-readonly
以下のコマンドの出力から、2 つの S3 バケットが指定したディレクトリにマウントされていることが確認できます。
$ ls /mnt/s3
YouCanLookThisFileFromS3.txt
$ ls /mnt/s3-readonly/
YouCanLookThisFileFromS3.txt images reads
ヘッドノードの EC2 インスタンスを停止し、再度開始した場合でも、systemd サービスによって S3 バケットが自動的にマウントされることを確認します。
以下は、インスタンス開始後のサービスの状態とマウント状況です。
$ systemctl list-units | grep mountpoint-s3
mountpoint-s3-585e79a6.service loaded active running Mount s3://hpc-dev-mountpoint-sample-2 at /mnt/s3
mountpoint-s3-91ef1212.service loaded active running Mount s3://hpc-dev-mountpoint-sample-1 at /mnt/s3-readonly
systemd サービスが自動的に起動し、S3 バケットがマウントされていることがわかります。
$ mount | grep mountpoint-s3
mountpoint-s3 on /mnt/s3-readonly type fuse (rw,nosuid,nodev,noatime,user_id=1000,group_id=1000,default_permissions,allow_other)
mountpoint-s3 on /mnt/s3 type fuse (rw,nosuid,nodev,noatime,user_id=1000,group_id=1000,default_permissions,allow_other)
コンピュートノードのマウント状況確認
コンピュートノードで S3 バケットがマウントされていることを確認するために、適当なテストジョブをサブミットしコンピュートノードを起動させます。
起動してきたコンピュートノードにログインし、以下のコマンドの出力から 2 つの S3 バケットが指定したディレクトリにマウントされていることが確認できます。
$ ls /mnt/s3
YouCanLookThisFileFromS3.txt
$ ls /mnt/s3-readonly/
YouCanLookThisFileFromS3.txt images reads
/mnt/s3-readonly
は read-only オプションが指定されており、読み取り専用(ro
)でマウントされています。一方、/mnt/s3
では allow-delete オプションが指定されており、ファイルの読み書き(rw
)が可能になっています。
$ mount | grep mountpoint-s3
mountpoint-s3 on /mnt/s3-readonly type fuse (ro,nosuid,nodev,noatime,user_id=0,group_id=0,default_permissions,allow_other)
mountpoint-s3 on /mnt/s3 type fuse (rw,nosuid,nodev,noatime,user_id=0,group_id=0,default_permissions,allow_other)
まとめ
本記事では、AWS ParallelCluster の Ubuntu 22.04 環境で Mountpoint for Amazon S3 を活用し、ヘッドノードとコンピュートノードに S3 バケットを自動マウントする方法を紹介しました。カスタムブートストラップスクリプトと systemd を使うことで、クラスター起動時に S3 バケットを自動的にマウントできます。また、クラスターのコンフィグでマウント設定を一元管理することで、マウントスクリプトの管理コストを削減できます。
おわりに
Mountpoint for Amazon S3 を活用することで、AWS ParallelCluster でのデータ共有と永続化が容易になります。今後は、ゲノム解析のワークロードで Mountpoint for Amazon S3 を活用し、利便性と効率性を高める検証を進めていきます。