Amazon FSx for Lustre SCRACH_2 ファイルシステムの作成・削除を CloudFormation で簡単に実行できるテンプレート紹介

2022.02.16

この記事は公開されてから1年以上経過しています。情報が古い可能性がありますので、ご注意ください。

Amazon FSx for Lustre を利用して高速なストレージを一時的に使って何かしらの処理をしたいということがあり、以前に CloudForamtion テンプレートを作成しました。テンプレート作成以降に FSx for Lustre アップデートがあり、CloudFormation のドキュメントを確認し直しました。新しいサンプルテンプレートを作成しましたので改めて紹介します。

主なテンプレートの更新内容

  • FSx for Lustre のバージョン2.12を明示的に指定(2022/2/15 最新)
    • 未指定だとデフォルト値のバージョン2.10で作成されるための対策
  • CloudFormation のスタックのパラメータ利用して、FSx for Lustre の作成・削除を簡単に切り替えられるようにしました
    • CreateLustreToggleパラメータのtrue/falseで作成、削除をコントロール
    • 上記に合わせて1つテンプレートに必要なリソース作成をまとめました
  • mountコマンドで必要な値を埋め込んだサンプルコマンドの表示を追加
    • 例: sudo mount -t lustre -o noatime,flock [Lustre].fsx.ap-northeast-1.amazonaws.com@tcp:/[Lustre] /mnt/lustre

使用用途と目的

データは FSx for Lustre に保存するのではなくS3バケットに保存・管理し、EC2からS3バケットへのアクセスを仲介するために一時的な FSx for Lustre を作成することを目的としています。

  • EC2インタスンスで使える高速な読み書きできるストレージが欲しい
  • S3バケットにあるデータへ EC2インタスンスから直接アクセスしたい
  • 必要なときだけ FSx for Lustre を起動したい
    • FSx for Lustre に停止操作はなくランニングコストを抑えるには削除する必要があります

前回と同じく一時的な FSx for Lustre の利用を目的しているため安価で高速なスクラッチ(SCRATCH_2)を採用しました。

Q: スクラッチと永続的デプロイオプションの違いは何ですか?

よくある質問 - Amazon FSx for Lustre | AWS

作ってみた

CloudFormation から簡単に FSx for Lustre 作成・削除できるテンプレートを作成しました。

注意事項は FSx for Lustre に書き込んだデータをS3へエクスポートする前に FSx for Lustre を削除すると、データも消えてしまいます。lfs hsm_archiveコマンドでS3へエクスポート(データの退避)することを忘れないでください。

過去のアップデートで自動エクスポート機能が追加されていたのですが

現在、自動エクスポート機能が使えるのはPersistent 2(永続化ストレージ)のみです。今回はスクラッチで作成しますので残念ながらサポートされていませんでした。

Support for data repository associations, automatic export, and multiple repositories is only available on Persistent 2 file systems.

引用: Automatically export updates to your S3 bucket - FSx for Lustre

前提

  • FSx for Lustre を配置するVPCと、サブネットを1個構築済みであること
  • FSx for Lustre とリンクするS3バケットが1個構築済みであること

S3バケットは既存のものがない、または新規作成したい場合は以下のテンプレートもご参考ください。FSx for Lustre に新規作成しリンクすることを目的に作成した例です。

本記事では上記のリンクで紹介しているテンプレートから作成したS3バケットを FSx for Lustre にリンクさせています。

テンプレート

GitHub にもアップしてあります。 bigmuramura/cfn-lustre-s3

  • SCRATCH_2ファイルシステムを選択
  • ストレージ容量は下限値の1.2TB 指定
    • S3のデータを読み書きのために一時的に保存しておくキャッシュ容量に該当します
    • 一時保管領域として容量不足の場合は指定サイズを変更してください

lustre.yml

---
AWSTemplateFormatVersion: "2010-09-09"
Description: Create Lustre*1

Metadata:
  AWS::CloudFormation::Interface:
    ParameterGroups:
      - Label:
          default: Common Settings
        Parameters:
          - ProjectName
          - Environment
          - VPCID
      - Label:
          default: Lustre Settings
        Parameters:
          - LustreSubnetID1
          - LustreAllowedCidrBlock
          - ImportS3BucketName

Parameters:
  ProjectName:
    Description: Project Name
    Type: String
    Default: unnamed
  Environment:
    Description: Environment
    Type: String
    Default: dev
    AllowedValues:
      - prod
      - dev
  VPCID:
    Type: AWS::EC2::VPC::Id
  LustreSubnetID1:
    Type: AWS::EC2::Subnet::Id
  LustreAllowedCidrBlock:
    Type: String
    Default: "10.0.0.0/16"
    AllowedPattern: '^(([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\.){3}([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])(\/([0-9]|[1-2][0-9]|3[0-2]))$'
  ImportS3BucketName:
    Type: String
    Default: "s3://hoge"
  CreateLustreToggle:
    Description: Create Lustre toggle.
    Type: String
    Default: true
    AllowedValues: [true, false]

Conditions:
  CreateLustreCondition: !Equals [true, !Ref CreateLustreToggle]

Resources:
  # ------------------------------------------------------------------------------------ #
  # FSx for Lustre
  # ------------------------------------------------------------------------------------ #
  FSxFileSystem:
    Type: "AWS::FSx::FileSystem"
    Condition: CreateLustreCondition
    Properties:
      FileSystemType: "LUSTRE"
      FileSystemTypeVersion: "2.12"
      StorageCapacity: 1200
      SubnetIds:
        - !Ref "LustreSubnetID1"
      SecurityGroupIds:
        - !Ref "SecurityGroup1"
      LustreConfiguration:
        AutoImportPolicy: "NEW_CHANGED_DELETED"
        ImportPath: !Ref "ImportS3BucketName"
        ExportPath: !Sub "${ImportS3BucketName}/export"
        ImportedFileChunkSize: 1024
        WeeklyMaintenanceStartTime: "6:20:00"
        DeploymentType: "SCRATCH_2"
        DataCompressionType: "LZ4"
      StorageType: "SSD"
      Tags:
        - Key: "Name"
          Value: !Sub ${ProjectName}-${Environment}-lustre

  # ------------------------------------------------------------------------------------ #
  # Security Group
  # ------------------------------------------------------------------------------------ #
  # FSx for Lustre
  SecurityGroup1:
    Type: AWS::EC2::SecurityGroup
    Properties:
      GroupName: !Sub ${ProjectName}-${Environment}-lustre-sg
      GroupDescription: FSx for Lustre Security Group
      SecurityGroupIngress:
        - IpProtocol: tcp
          FromPort: 2049
          ToPort: 2049
          CidrIp: !Ref LustreAllowedCidrBlock
          Description: "Access from EC2 to mount Lustre"
        - IpProtocol: tcp
          FromPort: 988
          ToPort: 988
          CidrIp: !Ref LustreAllowedCidrBlock
          Description: "Access from EC2 to mount Lustre"
        - IpProtocol: tcp
          FromPort: 1021
          ToPort: 1023
          CidrIp: !Ref LustreAllowedCidrBlock
          Description: "Access from EC2 to mount Lustre"
      VpcId: !Ref VPCID
      Tags:
        - Key: Name
          Value: !Sub ${ProjectName}-${Environment}-lustre-sg
  # Need to give myself permission to do this.
  SecurityGroup1Ingress1:
    Type: AWS::EC2::SecurityGroupIngress
    Properties:
      GroupId: !Ref SecurityGroup1
      IpProtocol: tcp
      FromPort: 988
      ToPort: 988
      SourceSecurityGroupId: !GetAtt SecurityGroup1.GroupId
      Description: "Access from Lustre LNET network"
  SecurityGroup1Ingress2:
    Type: AWS::EC2::SecurityGroupIngress
    Properties:
      GroupId: !Ref SecurityGroup1
      IpProtocol: tcp
      FromPort: 1021
      ToPort: 1023
      SourceSecurityGroupId: !GetAtt SecurityGroup1.GroupId
      Description: "Access from Lustre LNET network"

Outputs:
  ExportLustreID:
    Condition: CreateLustreCondition
    Value: !Ref FSxFileSystem
    Export:
      Name: !Sub "${AWS::StackName}-LustreID1"
  ExportLustreMountName:
    Condition: CreateLustreCondition
    Value: !GetAtt "FSxFileSystem.LustreMountName"
    Export:
      Name: !Sub "${AWS::StackName}-LustreMountName1"
  ExportLustreDNSName:
    Condition: CreateLustreCondition
    Value: !GetAtt "FSxFileSystem.DNSName"
    Export:
      Name: !Sub "${AWS::StackName}-LustreDNSName1"
  ExporetLustreMountCmd:
    Condition: CreateLustreCondition
    Description: "Sample command to mount to /mnt/lustre directory"
    Value: !Sub "sudo mount -t lustre -o noatime,flock ${FSxFileSystem.DNSName}@tcp:/${FSxFileSystem.LustreMountName} /mnt/lustre"

デプロイ

VPC、サブネットなど選択できるものは選択し、リソースに付与する名前は任意に入力してください。

LustreAllowedCidrBlockは FSx for Lustre のセキュリティグループで許可するCIDRブロックの範囲を入力します。本来はマウントするEC2のセキュリティグループからのみ許可する設定をした方が好ましいのですが、汎用的なテンプレートの都合、ざっくりとした設定になっています。必要に応じてテンプレートを修正して利用していただければと思います。

ImportS3BucketNameはリンクさせる S3バケット名を指定します。バケット名の頭にはs3://が必要です。

CreateLustreToggletrueだと FSx for Lustre のリソースを作成し、falseだと作成しない(削除)の切り替え用に使います。まずはtrueで FSx for Lustre を作成してみます。

マウント確認

Amazon Linux2 の EC2インタスンスに FSx for Lustre をマウントします。

Installing the Lustre client - FSx for Lustre

/mnt/lustreディレクトリを新規作成して FSx for Lustre をマウントします。

sudo amazon-linux-extras install -y lustre2.10
sudo mkdir -p /mnt/lustre

Cloudformation のスタックのアウトプットの必要な値を埋め込まれたコマンドをコピペしてマウント完了です。

赤枠部分のコマンドをコピペするだけです。マウント後ec2-userに所有権を変更しました。

sudo mount -t lustre -o noatime,flock fs-05f406dd820ed4406.fsx.ap-northeast-1.amazonaws.com@tcp:/7z3ftbmv /mnt/lustre
sudo chown ec2-user. /mnt/lustre

マウントされていることを確認できます。

$ df -h
ファイルシス              サイズ  使用  残り 使用% マウント位置
devtmpfs                    462M     0  462M    0% /dev
tmpfs                       471M     0  471M    0% /dev/shm
tmpfs                       471M  396K  470M    1% /run
tmpfs                       471M     0  471M    0% /sys/fs/cgroup
/dev/nvme0n1p1              8.0G  1.6G  6.5G   19% /
tmpfs                        95M     0   95M    0% /run/user/1000
10.0.33.137@tcp:/7z3ftbmv   1.1T  7.7M  1.1T    1% /mnt/lustre

fstab に書かないの?

/etc/fstabの記述は以下のドキュメントに載っております。

Mounting your Amazon FSx file system automatically - FSx for Lustre

/etc/fstabに書いてマウントしてももちろん大丈夫です。しかし、今回の FSx for Lustre は利用するときだけ存在することを前提としているため、作成・削除するたびに Lustre の名前が変わります。作成の都度、必要なコマンドを自動生成するようにしました。

Lustre を使ってみる

S3上のデータの読み込みと、書き込みを簡単に試します。Lustre 特有のコマンド操作が登場します。

読み込み

$ ll /mnt/lustre
合計 0

FSx for Lustre にリンクしたS3バケットは現在空です。

マネジメントコンソールからS3にファイルアップロードしました。

EC2インタスンスからFSx for Lustre を介して参照できます。S3上のデータは自動的に同期(インポート)されます。

$ ll /mnt/lustre
合計 1
-rwxr-xr-x 1 root root 17  2月 15 06:08 test.txt

EC2のローカルにtext.txtファイルをコピーして開くことができました。S3にあるデータ(オブジェクト)に対して FSx for Lustre を介してシームレスにアクセスできることができました。

$ cp /mnt/lustre/test.txt .
$ cat test.txt
test auto import

書き込み

FSx for Lustre から S3へデータを退避するときに Lustre 特有コマンドが必要なります。

Exporting files using HSM commands - FSx for Lustre

/mnt/lustreに空ファイル(ec2file.txt)を作成しました。

$ touch /mnt/lustre/ec2file.txt

EC2インタスンスからはファイルの存在を確認できます。

$ ll /mnt/lustre/
合計 9
-rw-rw-r-- 1 ec2-user ec2-user  0  2月 15 06:15 ec2file.txt
-rwxr-xr-x 1 root     root     17  2月 15 06:08 test.txt

S3バケットには反映されません。FSx for Lustre から S3へ自動アップロード(エクスポート)はされません。

lfs hsm_stateコマンドで確認してみます。exists archivedの表示がないファイルはS3には置かれていなくLustre上にのみ存在していることを示しています。

$ lfs hsm_state *
ec2file.txt: (0x00000000)
test.txt: (0x00000009) exists archived, archive_id:1

lfs hsm_archiveコマンドで Lustre から S3 へエクスポートができます。

$ sudo lfs hsm_archive ec2file.txt

exists archived表示に変わりました。

$ lfs hsm_state *
ec2file.txt: (0x00000009) exists archived, archive_id:1
test.txt: (0x00000009) exists archived, archive_id:1

S3バケットへは Lustre 構築時に指定したパスの配下にファイルが書き出されます。ここでは/export配下にファイルが書き込まれます。

抜粋

        ExportPath: !Sub "${ImportS3BucketName}/export"

オートインポート(S3バケットの内容表示)と、エクスポート(S3へデータ退避)の動作はこの様な感じです。

FSx for Lustre の作成・削除切り替え

パラメータのture/falseでLustreを削除できます。

削除

falseに変更してスタックを更新すると、FSx for Lustre を削除して FSx for Lustre の課金を停止します。

  • Lustre 上の必要なファイルはS3へデータ退避だけは忘れないでください
  • FSx for Lustre のファイルシステムのみ削除します
  • FSx for Lustre のセキュリティグループは削除せず残すようにしてあります

再作成

falseからtrueに戻して FSx for Lustre を再作成しました。同様にマウント用のコマンドをコピペしてマウントします。

$ sudo mount -t lustre -o noatime,flock fs-0e176db125330781d.fsx.ap-northeast-1.amazonaws.com@tcp:/czlvtbmv /mnt/lustre
$ sudo chown ec2-user. /mnt/lustre

exportも表示されるようになっていました。

$ ll /mnt/lustre/
合計 33
drwxr-xr-x 2 root root 33280  2月 16 00:40 export
-rwxr-xr-x 1 root root    17  2月 15 06:08 test.txt

手動でエクスポートしたec2file.txtを確認できました。1GB.fileは多少容量ファイルもと思って追加で手動エクスポートしていたものです。

$ ll /mnt/lustre/export/
合計 1
-rw-rw-r-- 1 ec2-user ec2-user 1048576000  2月 15 06:25 1GB.file
-rw-rw-r-- 1 ec2-user ec2-user          0  2月 15 06:15 ec2file.txt

おわりに

一時的な利用を想定した Lustre として SCRATCH_2 を採用しましたが、S3へデータ退避忘れからのデータ誤削除のリスクを考えると自動エクスポート機能をサポートしているPERSISTENT 2の方が安心して利用いただけるかもというお気持ちになりました。ただ、最安価で高速アクセスを実現するなら今のところSCRATCH_2 がコスパ良いです。

とはいえPERSISTENT 2以外は古いデプロイメントタイプとなっており、自動エクスポート機能がサポートされている新しいタイプを選択もご検討ください。

Working with older deployment types - FSx for Lustre