AWS ParallelCluster に EFS を複数マウントする設定方法の紹介

EFS を複数マウントできる。そう、AWS ParallelCluster 3.2.0 ならね。v3.1.4 以前は複数個マウントに対応していないのでご注意ください。
2022.08.15

AWS ParallelCluster 3.2.0 より最大20個の EFS をマウントできるようになりました。既存の EFS を2個マウントしたクラスターのコンフィグファイルを元に設定方法を紹介します。

設定方法早見

MountDir:のブロックを必要個数分作成すれば OK です。本文にはコンフィグファイル全体を載せてあります。

SharedStorage:
  - MountDir: /mnt/efs-01
    Name: efs-single-az
    StorageType: Efs
    EfsSettings:
      FileSystemId: fs-0f1158ade79354809
  - MountDir: /mnt/efs-02
    Name: efs-multi-az
    StorageType: Efs
    EfsSettings:
      FileSystemId: fs-0be1e56255995a58d

クラスター作成時のみ EFS マウント設定をすることができます。あとから更新(新規追加、削除)できないタイプのアップデートポリシーの設定項目でした。

クラスターを作成してみる

既存の EFS を2個マウントしたクラスターのコンフィグを作成します。

検証環境

項目
ParallelCluster 3.2.0
OS Ubuntu 20.04
CPU Intel
Head Node t3.micro
Compute Node t3.micro

EFS の準備

ストレージクラス違いで2つ EFS を用意しました。

  • efs-01(One Zone)
  • efs-02(Standard)

EFS のセキュリテイグループ

EFS のセキュリテイグループはヘッドノード、コンピュートノードからアクセスできる設定にしてください。ソースはヘッドノードと、コンピュートノードのセキュリテイグループからのアクセスのみを許可する設定が望ましいです。私はクラスターが複数あると都度インバウンドの設定変更が手間なため、VPC の CIDR をソースとし、同 VPC 内であればアクセスを許可するとしたインバウンドルールにしています。

Creating security groups - Amazon Elastic File System

クラスターのコンフィグ作成

EFS を複数個マウントする場合はMountDir:のブロック単位で増やすだけです。気をつけるポイントは以下になります。

  • MountDir:のマウント先のパスを重複させない
  • Name:を重複させない
  • FileSystemId:の EFS の ID を間違えない
Region: ap-northeast-1
Image:
  Os: ubuntu2004
Tags:
  - Key: Name
    Value: MountEFSCluster
# ----------------------------------------------------------------
# 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
    S3Access:
      - BucketName: hpc-dev-postinstall-files
        EnableWriteAccess: false
# ----------------------------------------------------------------
# Compute Node Settings
# ----------------------------------------------------------------
Scheduling:
  Scheduler: slurm
  SlurmSettings:
    ScaledownIdletime: 5
  SlurmQueues:
    # ------ Debug 1 without Postinstall ------
    - Name: debug-1
      ComputeResources:
        - Name: debug-without-postinstall
          InstanceType: t3.micro
          MinCount: 0
          MaxCount: 10
          DisableSimultaneousMultithreading: false
      ComputeSettings:
        LocalStorage:
          RootVolume:
            Size: 35
            Encrypted: true
            VolumeType: gp3
            Iops: 3000
            Throughput: 125
      CapacityType: SPOT
      Networking:
        SubnetIds:
          - subnet-035be95eeaa091603
        PlacementGroup:
          Enabled: false
      Iam:
        AdditionalIamPolicies:
          - Policy: arn:aws:iam::aws:policy/AmazonSSMManagedInstanceCore
        S3Access:
          - BucketName: hpc-dev-postinstall-files
            EnableWriteAccess: false
    # ------ Debug 2 with Postinstall ------
    - Name: debug-2
      ComputeResources:
        - Name: debug-run-postinstall
          InstanceType: t3.micro
          MinCount: 0
          MaxCount: 10
          DisableSimultaneousMultithreading: false
      ComputeSettings:
        LocalStorage:
          RootVolume:
            Size: 35
            Encrypted: true
            VolumeType: gp3
            Iops: 3000
            Throughput: 125
      CapacityType: SPOT
      Networking:
        SubnetIds:
          - subnet-035be95eeaa091603
        PlacementGroup:
          Enabled: false
      CustomActions:
        OnNodeConfigured:
          Script: s3://hpc-dev-postinstall-files/sample-ubuntu-docker/postinstall.sh
      Iam:
        AdditionalIamPolicies:
          - Policy: arn:aws:iam::aws:policy/AmazonSSMManagedInstanceCore
        S3Access:
          - BucketName: hpc-dev-postinstall-files
            EnableWriteAccess: false
    # ------ Compute 1 ------
    - Name: c6ilarge
      ComputeResources:
        - Name: c6ilarge
          InstanceType: c6i.large
          MinCount: 0
          MaxCount: 10
          DisableSimultaneousMultithreading: true
      ComputeSettings:
        LocalStorage:
          RootVolume:
            Size: 35
            Encrypted: true
            VolumeType: gp3
            Iops: 3000
            Throughput: 125
      CapacityType: SPOT
      Networking:
        SubnetIds:
          - subnet-035be95eeaa091603
        PlacementGroup:
          Enabled: true
      CustomActions:
        OnNodeConfigured:
          Script: s3://hpc-dev-postinstall-files/sample-ubuntu-docker/postinstall.sh
      Iam:
        AdditionalIamPolicies:
          - Policy: arn:aws:iam::aws:policy/AmazonSSMManagedInstanceCore
        S3Access:
          - BucketName: hpc-dev-postinstall-files
            EnableWriteAccess: false
# ----------------------------------------------------------------
# Shared Storage Settings
# ----------------------------------------------------------------
SharedStorage:
  - MountDir: /mnt/efs-01
    Name: efs-single-az
    StorageType: Efs
    EfsSettings:
      FileSystemId: fs-0f1158ade79354809
  - MountDir: /mnt/efs-02
    Name: efs-multi-az
    StorageType: Efs
    EfsSettings:
      FileSystemId: fs-0be1e56255995a58d
# ----------------------------------------------------------------
#  Other Settings
# ----------------------------------------------------------------
Monitoring:
  Logs:
    CloudWatch:
      Enabled: true
      RetentionInDays: 30
      DeletionPolicy: "Delete"
  Dashboards:
    CloudWatch:
      Enabled: false

アップデートポリシー

EFS をマウントするならクラスター作成時に指定するしかありません。また、EFS 追加や、マウント解除も同様にできません。といったアップデートポリシーでした。注意事項として頭の片隅に留めておいてください。

SharedStorage section - AWS ParallelCluster

クラスター作成後

コンフィグファイルからクラスターを作成しました。EFS のマウント状況を確認します。

ヘッドノードへ接続

/mnt配下にMountDir:で指定したとおりマウントされています。

$ df -hT
Filesystem                                              Type      Size  Used Avail Use% Mounted on
/dev/root                                               ext4       34G   18G   17G  52% /
devtmpfs                                                devtmpfs  465M     0  465M   0% /dev
tmpfs                                                   tmpfs     472M     0  472M   0% /dev/shm
tmpfs                                                   tmpfs      95M  944K   94M   1% /run
tmpfs                                                   tmpfs     5.0M     0  5.0M   0% /run/lock
tmpfs                                                   tmpfs     472M     0  472M   0% /sys/fs/cgroup
/dev/nvme0n1p15                                         vfat      105M  5.2M  100M   5% /boot/efi
/dev/loop0                                              squashfs   26M   26M     0 100% /snap/amazon-ssm-agent/5656
/dev/loop6                                              squashfs   68M   68M     0 100% /snap/lxd/22753
/dev/loop4                                              squashfs   62M   62M     0 100% /snap/core20/1581
/dev/loop5                                              squashfs   47M   47M     0 100% /snap/snapd/16292
/dev/loop3                                              squashfs   56M   56M     0 100% /snap/core18/2409
/dev/loop1                                              squashfs   56M   56M     0 100% /snap/core18/2538
fs-0f1158ade79354809.efs.ap-northeast-1.amazonaws.com:/ nfs4      8.0E     0  8.0E   0% /mnt/efs-01
fs-0be1e56255995a58d.efs.ap-northeast-1.amazonaws.com:/ nfs4      8.0E     0  8.0E   0% /mnt/efs-02
/dev/loop7                                              squashfs   62M   62M     0 100% /snap/core20/1593
tmpfs                                                   tmpfs      95M     0   95M   0% /run/user/0
$ tree /mnt
/mnt
├── efs-01
└── efs-02

ヘッドノードから書き込みテストします。

$ echo "test write 1" > /mnt/efs-01/test1.txt
$ echo "test write 2" > /mnt/efs-02/test2.txt
$ tree /mnt
/mnt
├── efs-01
│   └── test1.txt
└── efs-02
    └── test2.txt

読み込みも問題ありません。

$ cat /mnt/efs-01/test1.txt
test write 1
$ cat /mnt/efs-02/test2.txt
test write 2

コンピュートノードからの接続テスト

コンピュートノードから EFS へファイルを書き込むためのスクリプトを作成しsbatchでジョブとしてサブミットしました。

test.sh

#!/bin/bash
#SBATCH -p debug-1
#SBATCH -n 1
echo $HOSTNAME > /mnt/efs-01/compute-1.txt
echo $HOSTNAME > /mnt/efs-02/compute-2.txt

コンピュートノードが起動するとジョブが実行されファイルが書き込まれました。

$ tree /mnt
/mnt
├── efs-01
│   ├── compute-1.txt
│   └── test1.txt
└── efs-02
    ├── compute-2.txt
    └── test2.txt

コンピュートノードのホスト名が書き込まれたファイルをヘッドノードから開くことができました。

$ cat /mnt/efs-01/compute-1.txt
debug-1-dy-debug-without-postinstall-2
$ cat /mnt/efs-02/compute-2.txt
debug-1-dy-debug-without-postinstall-2

EFS マウント済みのクラスターを作成すればアクセス権限などはあれこれせずに共有ストレージとして利用できる状態で起動することが確認できました。

おわりに

ユースケースとしては用途別に EFS を分けたり、バーストクレジットの有効活用するために複数個 EFS を用意して書き込み先を変更したジョブ投げるとかでしょうか。 とくに EFS 内でバックアップ取るディレクトリ、取らないディレクトリの指定があると AWS Backup では実現できなく DataSync を使うことになります。EFS 自体で分けるとシンプルにバックアップが取れるため良い使い方ではないかと思いました。

参考