SAA

CFNでEFS入門

スポンサーリンク
CloudFormationでEFS入門 SAA
スポンサーリンク
スポンサーリンク

CloudFormationでEFS入門

AWS SAAの出題範囲の1つである、高性能なアーキテクチャの設計に関する内容です。

EFSはAWSが提供するストレージサービスの1種です。

Amazon Elastic File System (Amazon EFS) は、ストレージをプロビジョニングまたは管理することなくファイルデータを共有できる、シンプルでサーバーレスのセットアンドフォーゲットのエラスティックファイルシステムを提供します。 (中略) アプリケーションを中断することなくオンデマンドでペタバイトまで拡張できるように構築されています。

Amazon EFS の特徴

今回は入門編ということで、CloudFormationでEFSを構築し、2つのEC2インスタンスからアクセスすることを目標とします。

構築する環境

Diagram of introduction to EFS.

VPC内に2つのサブネットを作成します。
いずれもインターネットにアクセス不可なプライベートサブネットとします。

EFSを作成し、各サブネットに関連付けます。

また各サブネットにEC2インスタンスを1つずつ配置します。
EFSにアクセスするために使用します。
インスタンスは最新版のAmazon Linux 2とします。

SSMエンドポイントを作成します。
本エンドポイントは2つの用途で使用します。
1点目はSSM Session Managerを使用して、EC2インスタンスにリモートアクセスするためです。
2点目はSSMドキュメントを使用して、インスタンスの初期化処理を実行するためです。

S3エンドポイントも作成します。
S3バケット上に構築されるyumリポジトリにアクセスするために使用します。

CloudFormationテンプレートファイル

上記の構成をCloudFormationで構築します。
以下のURLにCloudFormationテンプレートを配置しています。

awstut-saa/02/007 at main · awstut-an-r/awstut-saa
Contribute to awstut-an-r/awstut-saa development by creating an account on GitHub.

テンプレートファイルのポイント解説

EFS用セキュリティグループ

Resources: InstanceSecurityGroup: Type: AWS::EC2::SecurityGroup Properties: GroupName: !Sub "${Prefix}-InstanceSecurityGroup" GroupDescription: Deny All. VpcId: !Ref VPC EFSSecurityGroup: Type: AWS::EC2::SecurityGroup Properties: GroupName: !Sub "${Prefix}-EFSSecurityGroup" GroupDescription: Allow NFS from InstanceSecurityGroup. VpcId: !Ref VPC SecurityGroupIngress: - IpProtocol: tcp FromPort: !Ref NFSPort ToPort: !Ref NFSPort SourceSecurityGroupId: !Ref InstanceSecurityGroup
Code language: YAML (yaml)

インスタンスとEFS間の通信はNFSで行われます。

Amazon EFS ファイルシステムは、Network File System バージョン 4.0 および 4.1 (NFSv4) プロトコルを使用して、仮想プライベートクラウド (VPC) にマウントできます。

Amazon EFS: 仕組み

インスタンスがEFSとNFS通信するためには、後述のEFSマウントターゲットに、以下を満たしたセキュリティグループを関連づける必要があります。

マウントターゲットに関連付けるセキュリティグループは、ファイルシステムをマウントするすべての EC2 インスタンスから、NFS ポート上の TCP プロトコルへのインバウンドアクセスを許可する必要があります。

セキュリティグループの作成

上記に従い、インスタンスからのNFS通信(2049/tcp)を許可するようにセキュリティグループを作成します。

EFSの2つのモード

EFS本体の設定を確認します。

Resources: EFS: Type: AWS::EFS::FileSystem Properties: Encrypted: true PerformanceMode: generalPurpose ThroughputMode: bursting
Code language: YAML (yaml)

EFSでは2つのパラメータを設定する必要があります。

1つ目はパフォーマンスモードです。
汎用モードと最大 I/Oモードが選択可能ですが、前者がデフォルトのモードで、多くの用途に対応できます。

大部分の Amazon EFS ファイルシステムには、汎用パフォーマンスモードをお勧めします。汎用は、ウェブ配信環境、コンテンツ管理システム、ホームディレクトリ、一般的なファイルサービスなど、レイテンシーに敏感なユースケースに最適です。

Amazon EFS パフォーマンス

2つ目はスループットモードです。
バーストスループットとプロビジョニングされたスループットが選択可能です。
今回は前者を選択します。
バーストスループットはEBSの汎用SSDのように、クレジットに応じたバーストが可能なモードです。

ファイルベースのワークロードは通常高低差が激しく、短期間で高レベルのスループットが発生し、残りの時間は低レベルのスループットになります。これに対応するために、Amazon EFS は一定期間内のスループットレベルのバーストが許可されるように設計されています。

Amazon EFS パフォーマンス

上記に従い、PerformanceModeプロパティに「generalPurpose」を、ThroughputModeプロパティに「bursting」を指定します。

EFSはAZをまたがって配置できる

インスタンスがEFSにアクセスできるようにEFSマウントポイントを定義します。

Resources: MountTarget1: Type: AWS::EFS::MountTarget Properties: FileSystemId: !Ref EFS SubnetId: !Ref PrivateSubnet1 SecurityGroups: - !Ref EFSSecurityGroup MountTarget2: Type: AWS::EFS::MountTarget Properties: FileSystemId: !Ref EFS SubnetId: !Ref PrivateSubnet2 SecurityGroups: - !Ref EFSSecurityGroup
Code language: YAML (yaml)

マウントターゲットはサブネット単位で作成する必要があります。
今回は2つのサブネットにインスタンスを配置しますので、サブネットごとにマウントターゲットを作成します。

またマウントポイントにはセキュリティグループを関連づけます。
先述のマウントポイント用セキュリティグループを指定します。

SSM Documentを使ってインスタンスをセットアップする

インスタンスからEFSにアクセスするための初期化処理を定義します。

Resources: RunShellScriptAssociation: Type: AWS::SSM::Association Properties: AssociationName: !Sub ${Prefix}-shellscript-association Name: AWS-RunShellScript OutputLocation: S3Location: OutputS3BucketName: !Ref LogBucketName OutputS3KeyPrefix: !Sub "${Prefix}/shellscript-association-log" Parameters: commands: - "sudo yum update -y" - "sudo yum install -y amazon-efs-utils" - "sudo mkdir /mnt/efs" - "sleep 90" - !Sub "sudo mount -t efs ${FileSystemId}:/ /mnt/efs" Targets: - Key: InstanceIds Values: - !Ref Instance1 - !Ref Instance2 WaitForSuccessTimeoutSeconds: 300
Code language: YAML (yaml)

インスタンスがEFSにアクセスするためには、AWSが提供しているAmazon EFSクライアントを使用することがベストプラクティスです。

Amazon EFS クライアント (amazon-efs-utils) は、Amazon EFS ツールのオープンソースのコレクションです。 (中略) Amazon EFS クライアントには、マウントヘルパーおよび Amazon EFS ファイルシステムの転送時のデータ暗号化の実行を簡単にするツールが用意されています。

Overview

同クライアントをインスタンスの初期化処理の一環としてインストールします。
インスタンスを自動的にセットアップする方法はいくつかありますが、今回はSSMドキュメントAWS-RunShellScriptを使用して、シェルスクリプトを実行する形でセットアップを行います。

詳細は以下のページをご確認ください。

セットアップ内容は以下の通りです。

  1. yumでインストール済みのパッケージをアップデートする
  2. Amazon EFS クライアントをインストールする
  3. EFS用のマウントポイントを作成する
  4. 90秒待機する
  5. EFSをマウントする

処理の中で待機を挟む理由ですが、マウントターゲット直後に発生する恐れがあるマウントエラーを回避するためです。

It can take up to 90 seconds after creating a mount target for the Domain Name Service (DNS) records to propagate fully in an AWS Region. If you’re programmatically creating and mounting file systems, for example with an AWS CloudFormation template, we recommend that you implement a wait condition.

File System Mount Fails Immediately After File System Creation

以上の内容を2つのインスタンスに対して実行するように設定します。

プライベートサブネット内でyumを実行する

先述のセットアップ処理の中で、yumによるアップデート・インストールに関する内容が含まれていました。
しかし2インスタンスはプライベートサブネット内に配置されているため、インターネットにアクセスできず、このままではyumに失敗します。
そこで今回は、S3用VPCエンドポイントを作成し、S3上に構築されたAmazon Linux用リポジトリにアクセスすることで、プライベートサブネット内からyumを実行します。

詳細につきましては以下のページをご確認ください。

環境構築

CloudFormationを使用して、本環境を構築し、実際の挙動を確認します。

CloudFormationスタックを作成し、スタック内のリソースを確認する

CloudFormationスタックを作成します。
スタックの作成および各スタックの確認方法については、以下のページをご確認ください。

各スタックのリソースを確認した結果、今回作成された主要リソースの情報は以下の通りです。

  • Instance1:i-091b12e8726df75c1
  • Instance2:i-0664bcef7e9712b79
  • EFS:fs-07e706669a91cd761

AWS Management Consoleからもリソースの作成状況を確認します。
まずEFSを確認します。

Detail of EFS 1.
Detail of EFS 2.

正常にEFSが作成されていることがわかります。

EFSが2つAZ上に作成されたサブネットと関連づいていることもわかります。
両サブネットにマウントターゲットが作成されたということを示しています。

次にSSMドキュメントの実行結果を確認します。

Result of SSM Document.

2台のインスタンスに対して正常に実行されたことがわかります。

実行時のログをS3バケットに保存するように設定しました。
保存されたログは以下の通りです。

Loaded plugins: extras_suggestions, langpacks, priorities, update-motd No packages marked for update Loaded plugins: extras_suggestions, langpacks, priorities, update-motd Resolving Dependencies --> Running transaction check ---> Package amazon-efs-utils.noarch 0:1.33.1-1.amzn2 will be installed --> Processing Dependency: stunnel >= 4.56 for package: amazon-efs-utils-1.33.1-1.amzn2.noarch --> Running transaction check ---> Package stunnel.aarch64 0:4.56-6.amzn2.0.3 will be installed --> Finished Dependency Resolution Dependencies Resolved ================================================================================ Package Arch Version Repository Size ================================================================================ Installing: amazon-efs-utils noarch 1.33.1-1.amzn2 amzn2-core 51 k Installing for dependencies: stunnel aarch64 4.56-6.amzn2.0.3 amzn2-core 148 k Transaction Summary ================================================================================ Install 1 Package (+1 Dependent package) Total download size: 199 k Installed size: 626 k Downloading packages: -------------------------------------------------------------------------------- Total 1.6 MB/s | 199 kB 00:00 Running transaction check Running transaction test Transaction test succeeded Running transaction Installing : stunnel-4.56-6.amzn2.0.3.aarch64 1/2 Installing : amazon-efs-utils-1.33.1-1.amzn2.noarch 2/2 Verifying : amazon-efs-utils-1.33.1-1.amzn2.noarch 1/2 Verifying : stunnel-4.56-6.amzn2.0.3.aarch64 2/2 Installed: amazon-efs-utils.noarch 0:1.33.1-1.amzn2 Dependency Installed: stunnel.aarch64 0:4.56-6.amzn2.0.3 Complete!
Code language: plaintext (plaintext)

amazon-efs-utilsおよびこれに依存関係のあるパッケージがインストールされたことがわかります。

動作確認

準備が整いましたので、EC2インスタンスにアクセスします。

Instance1

まずInstance1にSSM Session Manager経由でアクセスします。

% aws ssm start-session --target i-091b12e8726df75c1 Starting session with SessionId: root-0a204dce1675cd00c sh-4.2$
Code language: Bash (bash)

SSM Session Managerの詳細につきましては、以下のページをご確認ください。

次にAWS EFS クライアントがインストールされていることを確認します。

sh-4.2$ yum list installed | grep efs amazon-efs-utils.noarch 1.33.1-1.amzn2 @amzn2-core
Code language: Bash (bash)

正常にインストールされたことがわかります。

ではdfコマンドでディスク状況を確認します。

sh-4.2$ df -hT Filesystem Type Size Used Avail Use% Mounted on devtmpfs devtmpfs 178M 0 178M 0% /dev tmpfs tmpfs 215M 0 215M 0% /dev/shm tmpfs tmpfs 215M 412K 214M 1% /run tmpfs tmpfs 215M 0 215M 0% /sys/fs/cgroup /dev/nvme0n1p1 xfs 8.0G 1.5G 6.5G 19% / /dev/nvme0n1p128 vfat 10M 3.8M 6.3M 38% /boot/efi tmpfs tmpfs 43M 0 43M 0% /run/user/0 fs-07e706669a91cd761.efs.ap-northeast-1.amazonaws.com:/ nfs4 8.0E 0 8.0E 0% /mnt/efs
Code language: Bash (bash)

一番下の行がEFSです。
セットアップ処理で指定した通り、/mnt/efsにマウントされていることがわかります。
Sizeの項目が「8.0E」ですので、スケール前ですが、既に8エクサバイト確保されていることがわかります。

次にEFSに書き込みを実行し、ファイル共有について確認します。

sh-4.2$ cd /mnt/efs sh-4.2$ sudo touch test.txt sh-4.2$ ls test.txt
Code language: Bash (bash)

EFSに対して正常に書き込むことができました。

Instance2

続いてInstance2にアクセスします。

% aws ssm start-session --target i-0664bcef7e9712b79 Starting session with SessionId: root-0ede646d6dca48f56 sh-4.2$
Code language: Bash (bash)

同様にディスク状況を確認します。

sh-4.2$ df -hT Filesystem Type Size Used Avail Use% Mounted on devtmpfs devtmpfs 178M 0 178M 0% /dev tmpfs tmpfs 215M 0 215M 0% /dev/shm tmpfs tmpfs 215M 412K 214M 1% /run tmpfs tmpfs 215M 0 215M 0% /sys/fs/cgroup /dev/nvme0n1p1 xfs 8.0G 1.5G 6.5G 19% / /dev/nvme0n1p128 vfat 10M 3.8M 6.3M 38% /boot/efi tmpfs tmpfs 43M 0 43M 0% /run/user/0 fs-07e706669a91cd761.efs.ap-northeast-1.amazonaws.com:/ nfs4 8.0E 0 8.0E 0% /mnt/efs
Code language: Bash (bash)

こちらでもEFSが/mnt/efsをマウントポイントしてマウントされていることがわかります。

最後に同ディレクトリを確認します。

sh-4.2$ ls /mnt/efs test.txt
Code language: Bash (bash)

Instance1で設置したファイルを、Instance2から確認することができました。

まとめ

EFS入門ということで、CloudFormationでEFSを作成しました。
EFSを使用することで、EC2インスタンス間でデータ共有できることを確認しました。

タイトルとURLをコピーしました