AWS ParallelCluster に Mountpoint for Amazon S3 を利用して、S3 バケットをマウントしたクラスター環境を構築手順を紹介します。
ヘッドノード、コンピュートノードから直接 S3 バケットのデータを取得できます。大容量のデータを読み取ることの多い機械学習、ゲノム解析(リファレンスゲノムなど)のワークロードで ParallelCluster を利用する場合は本構成もご検討ください。
Inventory icons created by Freepik - Flaticon
S3 バケットに保存してあるファイルをパス指定(例: /mnt/s3
)で直接ファイルアクセスできるようになった点が大きな変更点です。
Mountpoint for Amazon S3 でマウントした S3 バケットに対しての書き込み処理は注意が必要です。多くのケースは図の様に EBS や、EFS などのブロックストレージに一度書き出すことになります。最終的なデータ保存先として S3 へコピーや、移動するときの書き込み処理はあまり心配ありません。
2023/10/8追記Ubuntu 22.04 を利用する場合は以下のブログもご参照ください。
設定の流れ
事前準備作業が地味に多いです。S3 バケットと IAM ポリシー、マウントスクリプトは一度作成すれば、他クラスター間で使いまわしできます。用途別に S3 バケットを分けたい場合は同じ手順を踏む必要はあります。
- マウント用の S3 バケット、IAM ポリシーを事前に作成する
- カスタムブートストラップアクションで実行する S3 マウントスクリプトを作成し、S3 に保存
- クラスターのコンフィグに IAM ポリシーの付与と、カスタムブートストラップアクション設定を追加
- クラスターをデプロイ(
pclsuter create-cluster
の実行) - ヘッドノードに手動で S3 自動マウント用の設定追加
検証環境
OS は Ubuntu 20.04 LTS の AWS ParallelCluster 3.6.1 環境で検証しています。mount-s3 コマンドのバージョンは1.0.0
です。
S3 をマウントするための準備
ParallelCluster に S3 バケットをマウントするために以下のリソースを事前に作成します。
- マウント対象となる S3 バケット
- ヘッドノード、コンピュートノードに必要な IAM ポリシー
CloudFormation テンプレート
必要なリソースは以下の CloudFormation テンプレートから作成できます。
mountpoint-for-s3.yaml
AWSTemplateFormatVersion: "2010-09-09"
Description: S3 Bucket and IAM Policy for Mountpoint for S3
Parameters:
ProjectName:
Description: Project Name
Type: String
Default: unnamed
Environment:
Description: Environment
Type: String
Default: dev
AllowedValues:
- prod
- dev
S3BucketName:
Description: Bucket name
Type: String
Metadata:
AWS::CloudFormation::Interface:
ParameterGroups:
- Label:
default: Common Settings
Parameters:
- ProjectName
- Environment
Resources:
# ------------------------------------------------------------------------------------ #
# S3
# ------------------------------------------------------------------------------------ #
S3Bucket:
Type: AWS::S3::Bucket
Properties:
BucketName: !Sub ${ProjectName}-${Environment}-${S3BucketName}-${AWS::AccountId}
OwnershipControls:
Rules:
- ObjectOwnership: "BucketOwnerEnforced"
PublicAccessBlockConfiguration:
BlockPublicAcls: True
BlockPublicPolicy: True
IgnorePublicAcls: True
RestrictPublicBuckets: True
VersioningConfiguration:
Status: Enabled
BucketEncryption:
ServerSideEncryptionConfiguration:
- ServerSideEncryptionByDefault:
SSEAlgorithm: "AES256"
BucketKeyEnabled: false
LifecycleConfiguration:
Rules:
- Id: AbortIncompleteMultipartUpload
AbortIncompleteMultipartUpload:
DaysAfterInitiation: 7
Status: "Enabled"
- Id: NoncurrentVersionExpiration
NoncurrentVersionExpiration:
NoncurrentDays: 14
Status: Enabled
- Id: IntelligentTiering
Transitions:
- TransitionInDays: 7
StorageClass: INTELLIGENT_TIERING
Status: Enabled
# ------------------------------------------------------------------------------------ #
# IAM Policy
# ------------------------------------------------------------------------------------ #
S3AccessPolicy:
Type: "AWS::IAM::ManagedPolicy"
Properties:
ManagedPolicyName: !Sub ${ProjectName}-${Environment}-AllowMountpointForS3
Path: "/"
PolicyDocument:
Version: "2012-10-17"
Statement:
- Effect: "Allow"
Action:
- "s3:ListBucket"
Resource:
- !Sub arn:aws:s3:::${ProjectName}-${Environment}-${S3BucketName}-${AWS::AccountId}
- Effect: "Allow"
Action:
- "s3:GetObject"
- "s3:PutObject"
- "s3:AbortMultipartUpload"
- "s3:DeleteObject"
Resource:
- !Sub arn:aws:s3:::${ProjectName}-${Environment}-${S3BucketName}-${AWS::AccountId}/*
Outputs:
ExportIAMPolicy:
Value: !Ref "S3AccessPolicy"
Export:
Name: !Sub "${AWS::StackName}-S3AccessPolicy"
ExportS3Bucket:
Value: !Ref "S3Bucket"
Export:
Name: !Sub "${AWS::StackName}-S3BucketARN"
パラメータ入力
任意の名前を入力してください。
参考までに上記のパラメータで生成したときのリソース名は以下になります。
S3 バケットの設定内容の説明
暗号化、バージョニング有効化などの基本的な設定に加えて HPC ワークロードを考慮して以下の設定を追加しています。
- S3 Inteligent-Tiering ストレージクラスへ 7 日後にデータ移動
- ストレージコスト自動最適化の意図
- S3 から削除したファイルは 14 日後に完全に削除
- お好みで保持日数の変更してください
- Amazon S3 ライフサイクルで世代管理を実現する「バージョン数の保持」を試してみた | DevelopersIO
- マルチパートアップロードの残骸 7 日後に削除
- Mountpoint for Amazon S3 でマルチパートアップロードが利用されているため、不要なファイルの定期削除
S3 バケット名はユニークな名前にするために AWS アカウント ID を末尾に自動的に付与しています。命名規則はお好みで変更してください。
抜粋
S3Bucket:
Type: AWS::S3::Bucket
Properties:
BucketName: !Sub ${ProjectName}-${Environment}-${S3BucketName}-${AWS::AccountId}
IAM ポリシーの設定内容の説明
CloudFormation で作成したマウント対象の S3 バケットへのみ最低限必要な権限をもたせる IAM ポリシーが CloudFormation テンプレートから作成されます。ParallelCluster からマウントした S3 バケットに対してファイルの読み書きができるようにs3:DeleteObject
の権限を持たせています。
{
"Version": "2012-10-17",
"Statement": [
{
"Action": [
"s3:ListBucket"
],
"Resource": [
"arn:aws:s3:::[CloudFromation で作成した S3 バケット名が自動入力されています]"
],
"Effect": "Allow"
},
{
"Action": [
"s3:GetObject",
"s3:PutObject",
"s3:AbortMultipartUpload",
"s3:DeleteObject"
],
"Resource": [
"arn:aws:s3:::[CloudFormation で作成した S3 バケット名が自動入力されています]/*"
],
"Effect": "Allow"
}
]
}
カスタムブートストラップアクションの準備
コンピュートノード起動時に S3 バケットをマウントするスクリプト作成し、カスタムブートストラップ用の S3 バケットに保存します。ここでは S3 バケットをマウントするのに必要なスクリプトを紹介します。
mount-s3.deb
パッケージをダウンロードしてインストール- S3 バケットのマウント先のパスを
/mnt/s3
ディレクトリを作成 mount-s3
コマンドで/mnt/s3
へ S3 バケットをマウント
CloudFormation で作成した S3 バケット名に置き換えてスクリプトをご利用ください。
mount.sh
#! /bin/bash
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
sudo mkdir /mnt/s3
sudo mount-s3 --allow-delete --allow-other [要手動入力: CloudFormation で作成した S3バケット名] /mnt/s3/
カスタムブートストラップ用の S3 バケットの作成は省略します。適当な S3 バケットを作成してスクリプトを保存してください。
クラスターコンフィグ作成
S3 バケットをマウントするのに必要な追加設定について説明します。
マウントする S3 バケットへのアクセス権追加
ヘッドノードと、キュー毎のコンピュートノードに IAM ポリシーを追加します。IAM ポリシー名は CloudFormation テンプレートで作成されています。リソース名を確認し ARN を入力してください。
個々の環境によってアカウント ID、CloudFormation に入力したパラメータの値によって IAM ポリシー名が異なります。ご自身の環境に合わせて修正してください。
# ヘッドノード
Iam:
AdditionalIamPolicies:
- Policy: arn:aws:iam::aws:policy/AmazonSSMManagedInstanceCore
- Policy: arn:aws:iam::123456789012:policy/hpc-dev-AllowMountpointForS3
--- 略 ---
# コンピュートノード(キューの数分だけ設定が必要)
Iam:
AdditionalIamPolicies:
- Policy: arn:aws:iam::aws:policy/AmazonSSMManagedInstanceCore
- Policy: arn:aws:iam::123456789012:policy/hpc-dev-AllowMountpointForS3
コンピュートノード起動時に S3 バケットをマウントするスクリプト実行
カスタムブートストラップ用の S3 バケットに保存したスクリプトのパスを入力します。
個々の環境によってスクリプト保存先の S3 バケット名、パス、スクリプト名が異なります。ご自身の環境に合わせて修正してください。
# コンピュートノード(キューの数分だけ設定が必要)
CustomActions:
OnNodeConfigured:
Script: s3://hpc-dev-postinstall-files/mount-moutpoint-for-s3/mount.sh
ヘッドノードへのカスタムブートストラップによるマウント設定は不要です。ヘッドノードの設定を自動化する上手い方法が思いつかなかったため、ヘッドノード起動後にログインして手動でマウント設定します。
既存の実行スクリプトが指定されている場合
ParallelCluster 3.6.0 のアップデートで、複数のスクリプトを列挙して実行できるようになりました。v3.6.0 以降であれば、既存のスクリプトがある場合はSequence:
を追加し実行スクリプトを列挙すれば既存のスクリプトをいじることなく新たな処理を追加できます。
OnNodeConfigured:
# Script URLs. The scripts are run in the same order as listed in the configuration, after all the bootstrap scripts are run
Sequence:
- Script1: s3://bucket-name/on-node-configured1.sh
Args:
- arg1
- Script2: s3://bucket-name/on-node-configured2.sh
Args:
- arg1
Custom bootstrap actions - AWS ParallelCluster
カスタムブートストラップ用の S3 バケットへのアクセス権追加
カスタムブートストラップ用の S3 バケットに保存したスクリプトにアクセスできる権限が別途必要になります。
# コンピュートノード(キューの数分だけ設定が必要)
S3Access:
- BucketName: hpc-dev-postinstall-files
EnableWriteAccess: false
コンフィグ全文
検証用のクラスターを構築したコンフィグです。設定内容の参考にご覧ください。
sample.yaml
Region: ap-northeast-1
Image:
Os: ubuntu2004
Tags:
- Key: Name
Value: MountS3Cluster
# ----------------------------------------------------------------
# Head Node Settings
# ----------------------------------------------------------------
HeadNode:
InstanceType: t3.micro
Networking:
ElasticIp: false
SubnetId: subnet-035be95eeaa091603
Ssh:
KeyName: sandbox-key
LocalStorage:
RootVolume:
Size: 35
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-dev-postinstall-files
EnableWriteAccess: false
# ----------------------------------------------------------------
# Compute Node Settings
# ----------------------------------------------------------------
Scheduling:
Scheduler: slurm
SlurmSettings:
ScaledownIdletime: 5
SlurmQueues:
# ------ Compute 1 ------
- Name: queue1
ComputeResources:
- Name: queue1
Instances:
- InstanceType: c6i.large
- InstanceType: m6i.large
MinCount: 0
MaxCount: 10
DisableSimultaneousMultithreading: true
ComputeSettings:
LocalStorage:
RootVolume:
Size: 35
Encrypted: true
VolumeType: gp3
Iops: 3000
Throughput: 125
CapacityType: SPOT
AllocationStrategy: lowest-price
Networking:
SubnetIds:
- subnet-035be95eeaa091603
PlacementGroup:
Enabled: false
CustomActions:
OnNodeConfigured:
Script: s3://hpc-dev-postinstall-files/mount-moutpoint-for-s3/mount.sh
Iam:
AdditionalIamPolicies:
- Policy: arn:aws:iam::aws:policy/AmazonSSMManagedInstanceCore
- Policy: arn:aws:iam::123456789012:policy/hpc-dev-AllowMountpointForS3
S3Access:
- BucketName: hpc-dev-postinstall-files
EnableWriteAccess: false
# ----------------------------------------------------------------
# Shared Storage Settings
# ----------------------------------------------------------------
SharedStorage:
- MountDir: /mnt/efs-1zone
Name: efs-1zone
StorageType: Efs
EfsSettings:
FileSystemId: fs-0f1158ade79354809
# ----------------------------------------------------------------
# Other Settings
# ----------------------------------------------------------------
Monitoring:
Logs:
CloudWatch:
Enabled: true
RetentionInDays: 180
DeletionPolicy: "Delete"
Dashboards:
CloudWatch:
Enabled: false
クラスターデプロイ後の設定
pcluster create-cluster
コマンドでクラスターをデプロイ後に必要な設定です。
ヘッドノードに S3 バケットを自動マウント設定追加
コンピュートノードはカスタムブートストラップアクションにより、コンピュートノードが起動時にマウント処理が走ります。ヘッドノードは手動で自動マウント設定を入れます。
マウント先のディレクトリを作成します。
sudo mkdir /mnt/s3
S3 バケットは専用のmount-s3
コマンドでマウントするのですが fstab のマウント処理はサポートしていません。そのため、ヘッドノード起動時になにかしらの方法でmount-s3
コマンドを実行する必要があります。
crontab を利用して起動時に任意のコマンドを一度実行する例です。一行書き加えれば良いだけで手軽なので今ところ私は採用しています。
crontab language=-e
@reboot sudo mount-s3 --allow-delete --allow-other [要手動入力: CloudFormation で作成した S3バケット名] /mnt/s3
以上でクラスターの設定は完了です。
まとめ
カスタムブートストラップアクションで S3 をマウントするスクリプトを実行することが肝です。そのための事前準備が多少必要でした。
- マウント用の S3 バケット、IAM ポリシーを事前に作成する
- カスタムブートストラップアクションで実行する S3 マウントスクリプトを作成し、S3 に保存
- クラスターのコンフィグに IAM ポリシーの付与と、カスタムブートストラップアクション設定を追加
- クラスターをデプロイ(
pclsuter create-cluster
の実行) - ヘッドノードに手動で S3 自動マウント用の設定追加
おわりに
ParallelCluster の設定手順のみの紹介となりました。アプリケーションの動作検証など時間あるときに試して結果を共有したいと思います。 なにがともあれ、クラスターに S3 バケットを直接マウントできることでファイルの読み込みに関しては大きく運用フローを改善できそうな大きなアップデートでした。