AWS

LinuxインスタンスにEBSをアタッチする

スポンサーリンク
CloudFormationでLinuxインスタンスにEBSをアタッチする AWS
スポンサーリンク
スポンサーリンク

LinuxインスタンスにEBSをアタッチする構成

LinuxインスタンスにEBS(Elastic Block Store)をアタッチする構成を確認します。

本ページでは、LinuxインスタンスにEBSをアタッチし、ストレージとして使用できるようにするまでの手順を確認します。
アタッチ以降の手順は、AWS公式サイト「Linux で Amazon EBS ボリュームを使用できるようにする」で紹介されている内容に沿って進めます。

具体的には、以下の3パターンを確認します。

  1. Nitro Systemで構築されたインスタンではない場合
  2. Nitro Systemで構築されたインスタンスの場合
  3. SSMドキュメントからシェルスクリプトを実行する方法

またWindowsインスタンスにEBSをアタッチする手順については、以下のページをご確認ください。

構築する環境

Amazon.co.jp: AWS認定資格試験テキスト AWS認定ソリューションアーキテクト - アソシエイト 改訂第2版 : NRIネットコム株式会社, 佐々木 拓郎, 林 晋一郎, 金澤 圭: 本
Amazon.co.jp: AWS認定資格試験テキスト AWS認定ソリューションアーキテクト - アソシエイト 改訂第2版 : NRIネットコム株式会社, 佐々木 拓郎, 林 晋一郎, 金澤 圭: 本
Diagram of Attaching EBS to Linux instance.

3台のEC2インスタンスを作成します。
1台目のインスタンスのタイプをNitro Systemで構築されていないT2.nanoとし、2・3台目をNitro Systemで構築されているT4g.nanoとします。

環境構築用のCloudFormationテンプレートファイル

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

awstut-fa/008 at main · awstut-an-r/awstut-fa
Contribute to awstut-an-r/awstut-fa development by creating an account on GitHub.

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

今回の環境を構成するための、各テンプレートファイルのポイントを取り上げます。

SSM Parameter Storeから最新のAMI IDを取得する

EBSをアタッチするEC2を確認します。
ポイントは作成するインスタンスのアーキテクチャに応じたAMIを設定する必要があるという点です。

Parameters:
  ImageId1:
    Type: AWS::SSM::Parameter::Value<AWS::EC2::Image::Id>
    
  ImageId2:
    Type: AWS::SSM::Parameter::Value<AWS::EC2::Image::Id>
    
  InstanceType1:
    Type: String
    
  InstanceType2:
    Type: String
    

Resources:
  Instance1:
    Type: AWS::EC2::Instance
    Properties:
      IamInstanceProfile: !Ref InstanceProfile
      ImageId: !Ref ImageId1
      InstanceType: !Ref InstanceType1
      NetworkInterfaces:
        - DeviceIndex: 0
          SubnetId: !Ref PrivateSubnet
          GroupSet:
            - !Ref InstanceSecurityGroup

  Instance2:
    Type: AWS::EC2::Instance
    Properties:
      IamInstanceProfile: !Ref InstanceProfile
      ImageId: !Ref ImageId2
      InstanceType: !Ref InstanceType2
      NetworkInterfaces:
        - DeviceIndex: 0
          SubnetId: !Ref PrivateSubnet
          GroupSet:
            - !Ref InstanceSecurityGroup
Code language: YAML (yaml)

今回の構成でポイントとなる設定はInstanceTypeおよびImageIdプロパティです。
先述の通り、今回は2インスタンスに対して、以下の通りインスタンスタイプを指定します。

  • インスタンス①:T2.nano
  • インスタンス②:T4g.nano

組み込み関数Fn::Refを使用して、Parametersセクションの値を参照し、2インスタンスのInstanceTypeプロパティを設定します。

2インスタンスのOSは共通してAmazon Linux 2を動作させますが、注意が必要です。
それは上記のインスタンスタイプはアーキテクチャが異なるため、同じAMIを指定することはできないという点です。

T2はx86_64ベースのインスタンスです。

特徴:
高クロックのインテル Xeon プロセッサ

Amazon EC2 インスタンスタイプ

一方、T4gはArmベースのインスタンスです。

特徴:
64 ビットの Arm Neoverse コアを搭載したカスタムビルドの AWS Graviton2 プロセッサ
専用ハードウェアと軽量ハイパーバイザーを組み合わせた AWS Nitro System で駆動

Amazon EC2 インスタンスタイプ

SSM Parameter Storeを使用することによって、アーキテクチャに合わせた最新のAMI IDを取得することが可能です。

AWS Systems Manager Parameter Store はすでに最新の Windows AMI を取得できます。今回、最新の Linux AMI も取得できるよう機能が拡張されました。各 Amazon Linux AMI は、固有の 公開パラメータストア名前空間 を持ちます。AMIの名前空間をクエリすることで、指定したリージョンのイメージIDを得ることができます。

AWS Systems Manager Parameter Store を使用して最新の Amazon Linux AMI IDを取得する

またCloudFormationにおいて、ParametersセクションのTypeプロパティに「AWS::SSM::Parameter::Value<AWS::EC2::Image::Id>」を指定することによって、SSM Parameter Storeに格納された値を取得することができるようになります。

You can use the existing Parameters section of your CloudFormation template to define Systems Manager parameters, along with other parameters. Systems Manager parameters are a unique type that is different from existing parameters because they refer to actual values in the Parameter Store. The value for this type of parameter would be the Systems Manager (SSM) parameter key instead of a string or other value. CloudFormation will fetch values stored against these keys in Systems Manager in your account and use them for the current stack operation.

Integrating AWS CloudFormation with AWS Systems Manager Parameter Store

今回は以下の条件でSSM Parameter Storeから値を参照することで、各アーキテクチャの最新AMI IDを取得します。

  • インスタンス①:/aws/service/ami-amazon-linux-latest/amzn2-ami-hvm-x86_64-gp2
  • インスタンス②:/aws/service/ami-amazon-linux-latest/amzn2-ami-hvm-arm64-gp2

なお2021年10月現在、上記の条件でSSM Parameter Storeにアクセスした場合に取得できるAMI IDは以下の通りです。

  • インスタンス①
    • AMI ID:ami-0701e21c502689c31
    • 仮想化タイプ:hvm
  • インスタンス②
    • AMI ID:ami-0427ff21031d224a8
    • 仮想化タイプ:hvm

仮想化タイプは後述のルートデバイス名に関係がある情報です。

EBSをインスタンスにアタッチする

EC2インスタンスにEBSをアタッチする方法を確認します。

Resources:
  EBS1:
    Type: AWS::EC2::Volume
    Properties:
      AvailabilityZone: !Sub "${AWS::Region}${AvailabilityZone}" 
      Size: !Ref VolumeSize
      VolumeType: !Ref VolumeType
      
  EBSAttachment1:
    Type: AWS::EC2::VolumeAttachment
    Properties:
      Device: !Sub "/dev/sd${DeviceNameSuffix}"
      InstanceId: !Ref Instance1
      VolumeId: !Ref EBS1
Code language: YAML (yaml)

まずEBSリソースを定義します。
AvailabilityZoneプロパティでEBSを配置するAZを指定します。EBSはアタッチ先のEC2インスタンスと同じAZに配置する必要があります。

同じアベイラビリティーゾーンに 1 つ以上のインスタンスに、利用可能な EBS ボリュームをボリュームとしてアタッチできます。

インスタンスへの Amazon EBS ボリュームのアタッチ

上記に従い、組み込み関数Fn::Subを使用して、インスタンスと同じAZに配置されるように指定します。

VolumeTypeプロパティでEBSのボリュームタイプを指定します。指定可能なボリュームタイプは以下の5種類です。

  • 汎用SSD
  • Provisioned IOPS SSD
  • スループット最適化 HDD
  • Cold HDD
  • マグネティック(旧世代)

今回は汎用SSDを選択します。
汎用SSDは2タイプあります。1つ目はgp2です。
性能(IOPS)に関して、2つの指標(ベースライン、バースト)があり、確保した容量に応じて、ベースラインが高まる仕組みが特徴です。

これらのボリュームでは、レイテンシーは 1 桁台のミリ秒であり、長時間 3,000 IOPS にバーストできます。最小 100 IOPS (33.33 GiB 以下) から最大 16,000 IOPS (5,334 GiB 以上) まで、ベースラインパフォーマンスは、ボリュームサイズ 3 IOPS/GiB で線形にスケールします。

汎用 SSD ボリューム (gp2)

2つ目はgp3です。
ボリュームの容量に関係なく、一定の性能が提供されます。

このボリュームは、ストレージの料金に含まれ、3,000 IOPS と 125 MiB/秒 の一貫したベースラインレートを提供します。

汎用 SSD ボリューム (gp3)

パフォーマンスという観点ですと、確保予定の容量が1024GiB未満なのであれば、常時3000IOPSが見込めるgp3の方が効果的です。
一方、汎用SSDでそれ以上のパフォーマンスを求める場合は、gp2を選択し、より多くの容量を確保することで、最大16000IOPSまで向上が期待できます。
今回はgp3を選択するように指定します。

Sizeプロパティで確保する容量を指定します。
汎用SSDの場合、1〜16384(GiB)で指定可能です。
今回は最小の1GiB確保します。

続いてEC2インスタンスにEBSをアタッチするためのリソースを定義します。

Resources:
  EBSAttachment1:
    Type: AWS::EC2::VolumeAttachment
    Properties:
      Device: !Sub "/dev/sd${DeviceNameSuffix}"
      InstanceId: !Ref Instance1
      VolumeId: !Ref EBS1
Code language: YAML (yaml)

InstanceIdおよびVolumeIdプロパティでインスタンスとアタッチするEBSを指定します。

DeviceプロパティでEBSに割り当てるデバイス名を指定します。
Linux AMIにおけるデバイス名は、仮想化タイプによって取り得る値が定まります。
先述の通り、今回の2インスタンスのAMIはどちらもhvmタイプです。
hvmのルート用、あるいは推奨されるデバイス名は以下の通りです。

ルート用に予約済み:/dev/sda1 or /dev/xvda
EBS ボリュームとして推奨:/dev/sd[f-p]

Linux インスタンス上のデバイス名

よって今回は2つのEBSに対して、デバイス名に「/dev/sdf」を指定します。

SSM Session Managerを使用してアクセスすればキーペアの設定は不要

Linuxインスタンスにアクセスする方法は、キーペアを使用したSSHが一般的ですが、今回はSSM Session Managerを使用します。
今回の構成では、インスタンスはプライベートサブネットに設置されているため、SSM用VPCエンドポイントを通じて、SSMにアクセスする形となります。詳細は以下のページをご確認ください。

SSMドキュメントを使ってEBSを使用可能にする

後ほどEBSを使用可能にするコマンドをご紹介しますが、コマンドを手動で実行するだけでなく、SSMドキュメントを通して実行することもできます。

Resources:
  RunShellScriptAssociation:
    Type: AWS::SSM::Association
    Properties:
      AssociationName: !Sub "${Prefix}-run-shellscript-association"
      Name: AWS-RunShellScript
      Parameters:
        commands:
          - !Sub |
            for d in $(lsblk -n -r -p | grep disk | awk '{ print $1 }' )
            do
              if  [ "$(sudo file -s -b $d)" == data ]; then
                sudo mkfs -t xfs $d
                sudo mkdir ${MountPoint}
                sudo mount $d ${MountPoint}
              fi
            done
      Targets:
        - Key: InstanceIds
          Values:
            - !Ref Instance
      WaitForSuccessTimeoutSeconds: !Ref WaitForSuccessTimeoutSeconds
Code language: YAML (yaml)

SSMドキュメントAWS-RunShellScriptを使用することで、Linuxインスタンス(Amazon Linux 2)に対して、指定したコマンドを実行することができます。
詳細は後ほど確認します。

環境構築

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

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

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

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

  • インスタンス①のID:i-064e80196c9a8065c
  • インスタンス②のID:i-09cfd456e6c89ea01
  • インスタンス③のID:i-0bbda6e4d4e4bcdc3
  • インスタンス①にアタッチするEBSのID:vol-06904bb289e054d68
  • インスタンス②にアタッチするEBSのID:vol-0972ea603af9f8b34
  • インスタンス③にアタッチするEBSのID:vol-09d7b2304f910940e

EBSのアタッチ状況を確認する1

AWS Management Consoleから各インスタンスの状況を確認します。
代表して、インスタンス1と2を取り上げます。

EBS is attached to the Block Device Mapping of the instance 1.
EBS is attached to the Block Device Mapping of the instance 2.

両インスタンスのBlock devicesの項目を見ると、2つずつEBSがアタッチされていることが確認できます。
「dev/xvda」の方はルートデバイスです。先述の通り、このデバイス名はルート用として予約されています。
もう一方の「/dev/sdf」が今回作成したEBSです。

EBSのアタッチ状況を確認する2:Nitro System上ではないインスタンスの場合

次に実際にインスタンスにアクセスして、EBSのアタッチ状況を確認します。
まずInstance1にアクセスします。
インスタンスへのアクセスはSSM Session Managerを使用します。

$ aws ssm start-session \
--target i-00f95cd8419e73461

Starting session with SessionId: root-0e49c3789cbebe2c9
sh-4.2$
Code language: Bash (bash)

lsblkコマンドでブロックデバイスの状況を確認することができます。

sh-4.2$ lsblk
NAME    MAJ:MIN RM SIZE RO TYPE MOUNTPOINT
xvda    202:0    0   8G  0 disk 
└─xvda1 202:1    0   8G  0 part /
xvdf    202:80   0   1G  0 disk 
Code language: Bash (bash)

「xvda」と「xvdf」という2つのブロックデバイスが認識されていることがわかります。
先ほど確認した通り、前者はルートデバイスです。
後者は今回アタッチしたEBSです。デバイス名がCloudFormationテンプレートで指定したもの(/dev/sdf)から変更されています。これはEBSの仕様によるものです。

カーネルのブロックデバイスドライバによっては、指定した名前とは異なる名前でデバイスがアタッチされる可能性があります。たとえば、デバイス名 (/dev/sdh) を指定した場合、デバイスの名前が /dev/xvdh や /dev/hdh に変更される場合があります。ほとんどの場合、末尾の文字は変更されません。

デバイス名に関する考慮事項

以上より、EBSアタッチ時に指定したデバイス名と、インスタンス側で認識しているデバイス名が異なる場合があることがわかりました。

EBSのアタッチ状況を確認する3:Nitro System上のインスタンスの場合

次にInstance2にアクセスしてEBSのアタッチ状況を確認します。

$ aws ssm start-session \
--target i-03f376aac4fcc98ab

Starting session with SessionId: root-07ebbd9797a52a2de

sh-4.2$
Code language: Bash (bash)
sh-4.2$ lsblk
NAME          MAJ:MIN RM SIZE RO TYPE MOUNTPOINT
nvme0n1       259:0    0   8G  0 disk 
├─nvme0n1p1   259:1    0   8G  0 part /
└─nvme0n1p128 259:2    0  10M  0 part /boot/efi
nvme1n1       259:3    0   1G  0 disk
Code language: Bash (bash)

「nvme0n1」と「nvme1n1」という2つのブロックデバイスが認識されていることがわかります。これはNitro System上のインスタンスにおける仕様によるものです。

EBS ボリュームは、Nitro System上に構築されたインスタンスで NVMe ブロックデバイスとして公開されます。デバイス名は、/dev/nvme0n1、/dev/nvme1n1 などです。ブロックデバイスマッピングで指定したデバイス名は、NVMe デバイス名 (/dev/nvme[0-26]n1) を使用して名称変更されます。

Amazon EBS および Linux インスタンス上の NVMe

Instance2に指定したインスタンスタイプはT4gですが、これはNitro System上で動作するタイプです。

以下のインスタンスが Nitro System に基づいています。
仮想化: A1, C5, C5a, C5ad, C5d, C5n, C6g, C6gd, C6gn, D3, D3en, G4, I3en, Inf1, M5, M5a, M5ad, M5d, M5dn, M5n, M5zn, M6g, M6gd, M6i, p3dn.24xlarge, P4, R5, R5a, R5ad, R5b, R5d, R5dn, R5n, R6g, R6gd, T3, T3a, T4g, ハイメモリ (u-*), X2gd, および z1d

インスタンスタイプ

以上より、「nvme0n1」がルートデバイス、「nvme1n1」がアタッチしたEBSです。

アタッチしたEBSを使用可能な状態にするまでの手順

引き続きInstance2で以降の手順の確認を進めます。

アタッチ以降の手順は、AWS公式サイト「Linux で Amazon EBS ボリュームを使用できるようにする」で取り上げられていますが、まとめると以下の流れになります。

  1. ファイルシステムを作成する
  2. マウントポイントを作成し、ボリュームをマウントする

実際に行います。
まずmkfsコマンでファイルシステムを作成します。

sh-4.2$ sudo mkfs -t xfs /dev/nvme1n1
meta-data=/dev/nvme1n1           isize=512    agcount=4, agsize=65536 blks
         =                       sectsz=512   attr=2, projid32bit=1
         =                       crc=1        finobt=1, sparse=0
data     =                       bsize=4096   blocks=262144, imaxpct=25
         =                       sunit=0      swidth=0 blks
naming   =version 2              bsize=4096   ascii-ci=0 ftype=1
log      =internal log           bsize=4096   blocks=2560, version=2
         =                       sectsz=512   sunit=0 blks, lazy-count=1
realtime =none                   extsz=4096   blocks=0, rtextents=0
Code language: Bash (bash)

作成するファイルシステムはXFSを指定しました。

次にmkdirコマンドでマウントポイントを作成後、mountコマンドでボリュームをマウントします。

sh-4.2$ sudo mkdir /data
sh-4.2$ sudo mount /dev/nvme1n1 /data
Code language: Bash (bash)

改めてlsblkコマンドで状況を確認します。

sh-4.2$ lsblk -f
NAME          FSTYPE LABEL UUID                                 MOUNTPOINT
nvme0n1                                                         
├─nvme0n1p1   xfs    /     9e2f3182-7352-4382-adbd-c67f6be433ed /
└─nvme0n1p128 vfat         2EE0-5AE9                            /boot/efi
nvme1n1       xfs          5c851eca-35be-4d6a-a4e8-e10c1efed050 /data
Code language: Bash (bash)

ファイルシステムやマウントポイントを確認することができます。

試しにファイルを書き込みます。

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

マウントポイントにアクセスし、ファイルを設置することができました。

このようにEBSをアタッチ後、ファイルシステムを作成し、マウントすることによって、通常のストレージと同様に使用可能であることがわかりました。

再起動時に自動的にEBSをマウントする方法

自動的にEBSボリュームをマウントする方法を確認します。
公式サイトでは、/etc/fstabを編集する方法が紹介されています。同ファイルをvim等のエディタで開き、以下の通り編集します。

sh-4.2$ sudo vim /etc/fstab
sh-4.2$ cat /etc/fstab 
#
UUID=9e2f3182-7352-4382-adbd-c67f6be433ed     /           xfs    defaults,noatime  1   1
UUID=2EE0-5AE9        /boot/efi       vfat    defaults,noatime,uid=0,gid=0,umask=0077,shortname=winnt 0 0
UUID=5c851eca-35be-4d6a-a4e8-e10c1efed050     /data       xfs    defaults,nofail   0   2
Code language: Bash (bash)

3行目が該当箇所です。lsblkコマンドで確認したUUIDを指定して、マウントポイント(/data)に自動的にマウントするように記述します。

設定の正常性の確認ですが、以下の手順で確認することができます。

  1. EBSボリュームをアンマウントする
  2. /etc/fstabに従って全ボリュームをマウントする
  3. マウントポイントにアクセスする

エラーなく最後まで辿り着けば成功と言えます。

sh-4.2$ sudo umount /data
sh-4.2$ sudo mount -a
sh-4.2$ ls /data
test.txt
Code language: Bash (bash)

正常に最後まで進むことができました。
これで再起動後も自動的にEBSボリュームがマウントされるようになりました。

SSMドキュメントを使用してEBSをマウントする

最後にSSMドキュメントAWS-RunShellScriptを使用して、Linuxインスタンス(Amazon Linux 2)において、自動的にEBSを使用できる状態に設定する方法をご紹介します。
改めて以下に実行するシェルスクリプトを記載します。

- !Sub |
  for d in $(lsblk -n -r -p | grep disk | awk '{ print $1 }' )
  do
    if  [ "$(sudo file -s -b $d)" == data ]; then
      sudo mkfs -t ${FileSystem} $d
      sudo mkdir ${MountPoint}
      sudo mount $d ${MountPoint}
      
      uuid=$(sudo blkid $d -o export | grep ^UUID)
      echo -e "$uuid\t/data\t${FileSystem}\tdefaults,nofail\t0\t2" >> /etc/fstab
    fi
  done
Code language: YAML (yaml)

スクリプトの内容は先述の通りですが、一応簡単に解説します。

  1. lsblkコマンドを実行して、TYPEがdiskのデバイス名を取得する。
  2. fileコマンドで各デバイスの情報を確認し、「data」のものをEBSで、かつ未処理のデバイスと見做して処理を進める。
  3. ファイルシステム作成後、EBSをマウントする。
  4. 自動マウント設定のために、UUIDを取得して、/etc/fstabに追記する。

CloudFormationスタック作成時に、自動的に本スクリプトが実行されます。

SSM Document Result.

インスタンス3にアクセスし、スクリプトが正常に動作したかを確認します。

% aws ssm start-session \
--target i-0bbda6e4d4e4bcdc3

Starting session with SessionId: root-03c8972378759f257
sh-4.2$ 

sh-4.2$ lsblk
NAME          MAJ:MIN RM SIZE RO TYPE MOUNTPOINT
nvme0n1       259:0    0   8G  0 disk 
├─nvme0n1p1   259:1    0   8G  0 part /
└─nvme0n1p128 259:2    0  10M  0 part /boot/efi
nvme1n1       259:3    0   1G  0 disk /data
Code language: Bash (bash)

EBSにファイルシステムが作成され、正常にマウントされていることがわかります。

自動マウントに関する設定を確認します。

sh-4.2$ cat /etc/fstab
#
UUID=b2d2af18-472e-4a07-a7f5-313592c907b9     /           xfs    defaults,noatime  1   1
UUID=7882-6D24        /boot/efi       vfat    defaults,noatime,uid=0,gid=0,umask=0077,shortname=winnt 0 0
UUID=a38658f8-ad51-417d-b7a7-4d865bd500b9	/data	xfs	defaults,nofail	0	2

sh-4.2$ sudo umount /data

sh-4.2$ lsblk
NAME          MAJ:MIN RM SIZE RO TYPE MOUNTPOINT
nvme0n1       259:0    0   8G  0 disk 
├─nvme0n1p1   259:1    0   8G  0 part /
└─nvme0n1p128 259:2    0  10M  0 part /boot/efi
nvme1n1       259:3    0   1G  0 disk 

sh-4.2$ sudo mount -a

sh-4.2$ lsblk
NAME          MAJ:MIN RM SIZE RO TYPE MOUNTPOINT
nvme0n1       259:0    0   8G  0 disk 
├─nvme0n1p1   259:1    0   8G  0 part /
└─nvme0n1p128 259:2    0  10M  0 part /boot/efi
nvme1n1       259:3    0   1G  0 disk /data
Code language: Bash (bash)

/etc/fstabにEBS情報が書き込まれ、それに基づいてマウントされることが確認できました。

まとめ

CloudFormationでEC2インスタンスにEBSをアタッチする方法を確認しました。
アタッチしたEBSを使用可能な状態にするまでの手順と、自動的にマウントする手順を確認しました。
SSMドキュメントを使用し、自動的にEBSを使用可能な状態に設定する方法をご紹介しました。

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