【LVM】EC2にEBSを複数繋げて1つのボリュームとして扱う裏技

挨拶

お疲れ様です、寺井です。

タイトルにある通り今回はボリュームを複数繋げて1つのボリュームとして扱えるようにするお話です。

「え、そんなん無理やろ・・・」
私もそう思ってましたが、出来ます!!

まず、なぜそんな事をする必要があるのかというと、実は先日こんな相談がありました。

背景

~~~~~~~~~~~~
オンプレの環境でハードディスクに20TiBぐらいのデータを保存してるけど、そろそろディスクの容量が枯渇しそうなので、クラウドに移行したい。
24時間常時稼働しているシステムで、かなりの量のI/Oが発生するため、パフォーマンスは確保したい。
あ、でもコストは可能な限り抑えたいです。
~~~~~~~~~~~~

まとめるとこんな感じ

  • 1台のEC2で20TiB以上のボリュームを使いたい
    (※io2 Block Expressを除きEBSの最大ボリュームサイズは16TiB)
  • 高いスループットを実現するためにボリュームはEBSを使いたい
  • コストはできるだけ抑えたい
    (※io2 Block Expressは高いから無理)

かなりコアな要求ですね・・・。
そこで登場するのがLVMです。

LVMについて

LVM 【Logical Volume Manager】 論理ボリュームマネージャ
LVMとは、UNIX系OSで利用できる機能の一つで、複数の外部記憶装置(ストレージ)やその内部のパーティションをまとめ、単一の記憶領域として利用する機能。
引用元 - LVM(論理ボリュームマネージャ)とは - 意味をわかりやすく - IT用語辞典 e-Words

めっちゃ便利!この機能を活用すれば、
複数のEBSをEC2に接続して、LVMで論理的に結合することにより、パフォーマンスが高くコスト効率も良いEBSで、16TiB以上のストレージ量を確保できそうです。

完成イメージ

まずは完成品のイメージから

それぞれのEBSで物理ボリューム(Physical Volume)を作成

1つにグループ(Volume Group)にまとめる

論理ボリューム(Logical Volume)を作成

マウントポイントに繋げる

こんな感じで実装していきます。

実装

今回はあくまでも検証のため、8GiBのEBS(gp3)2つを追加でアタッチしてLVMで結合し、15GiBの論理ボリュームを作成します。

EC2&EBSの起動

インスタンス概要
OS Amazon Linux 2
インスタンスタイプ t2.micro
ボリュームタイプ gp3

EBSボリュームについて

ボリュームタイプはgp3
[Add new volume]でボリュームを2つ追加する

LVM設定の実施

EC2に接続してコンソール上で設定を行う
(今回はTera Termを使用しています)

ボリューム毎にパーティションを作成する

ルート権限に切り替え

$ sudo su

現在接続されているボリュームの確認
ルートボリュームとは別に「xvdb」と「xvdc」の2つのボリュームが接続されている
接続されているだけでパーティション等の設定も無い状態

$ lsblk
NAME    MAJ:MIN RM SIZE RO TYPE MOUNTPOINT
xvda    202:0    0   8G  0 disk
└xvda1  202:1    0   8G  0 part /
xvdb    202:16   0   8G  0 disk
xvdc    202:32   0   8G  0 disk

「gdisk」コマンドでパーティションに関する設定に入る
(※今回は「/dev/xvdb」というボリュームになっていますが、環境によって異なりますので適宜読み替えてください。)

$ gdisk /dev/xvdb
GPT パーティションの設定内容
GPT fdisk (gdisk) version 0.8.10

Partition table scan:
  MBR: not present
  BSD: not present
  APM: not present
  GPT: not present

Creating new GPT entries.

Command (? for help): n
Partition number (1-128, default 1):
First sector (34-16777182, default = 2048) or {+-}size{KMGTP}:
Last sector (2048-16777182, default = 16777182) or {+-}size{KMGTP}:
Current type is 'Linux filesystem'
Hex code or GUID (L to show codes, Enter = 8300): 8e00
Changed type of partition to 'Linux LVM'

Command (? for help): w

Final checks complete. About to write GPT data. THIS WILL OVERWRITE EXISTING
PARTITIONS!!

Do you want to proceed? (Y/N): Y
OK; writing new GUID partition table (GPT) to /dev/xvdb.
The operation has completed successfully.
help表示

「?」を入力すると各コマンド毎のhelpが表示される

Command (? for help): ?
b       back up GPT data to a file
c       change a partition's name
d       delete a partition
i       show detailed information on a partition
l       list known partition types
n       add a new partition
o       create a new empty GUID partition table (GPT)
p       print the partition table
q       quit without saving changes
r       recovery and transformation options (experts only)
s       sort partitions
t       change a partition's type code
v       verify disk
w       write table to disk and exit
x       extra functionality (experts only)
?       print this menu
新しいパーティションを作成
Command (? for help): n

以下の3つに関してはデフォルト設定で進めるため、何も入力せずに「Enter」

Partition number (1-128, default 1):
First sector (34-16777182, default = 2048) or {+-}size{KMGTP}:
Last sector (2048-16777182, default = 16777182) or {+-}size{KMGTP}:
Current type is 'Linux filesystem'
Hex codeの確認
Hex code or GUID (L to show codes, Enter = 8300): L
...
8e00 Linux LVM
...
Hex codeの入力

Linux LVMのコードである「8e00」を入力する

Hex code or GUID (L to show codes, Enter = 8300): 8e00
Changed type of partition to 'Linux LVM'
設定内容の保存

「w」でパーティションテーブルの変更を保存して終了する
「Y」で確定

Command (? for help): w

Final checks complete. About to write GPT data. THIS WILL OVERWRITE EXISTING
PARTITIONS!!

Do you want to proceed? (Y/N): Y
OK; writing new GUID partition table (GPT) to /dev/xvdb.
The operation has completed successfully.

以上の内容をもう一方のディスク「xvdc」でも実行

追加のボリューム毎に対応するパーティションが作成された

$ lsblk
NAME    MAJ:MIN RM SIZE RO TYPE MOUNTPOINT
xvda    202:0    0   8G  0 disk
└xvda1  202:1    0   8G  0 part /
xvdb    202:16   0   8G  0 disk
└xvdb1  202:17   0   8G  0 part
xvdc    202:32   0   8G  0 disk
└xvdc1  202:33   0   8G  0 part

パーティション毎に物理ボリュームを作成

$ pvcreate /dev/xvdb1
  Physical volume "/dev/xvdb1" successfully created.

もう一方のパーティション「xvdc1」でも実行

ボリュームグループの作成

「vgcreate」でボリュームグループを新規追加する

$ vgcreate VolumeGroup /dev/xvdb1
  Volume group "VolumeGroup" successfully created

確認してみると"VolumeGroup"に8GiBの容量が割り当てられている

$ vgs
  VG          #PV #LV #SN Attr   VSize  VFree
  VolumeGroup   1   0   0 wz--n- <8.00g <8.00g

ボリュームグループに追加

今度は「vgextend」で既存のボリュームグループに追加する

$ vgextend VolumeGroup /dev/xvdc1
  Volume group "VolumeGroup" successfully extended

確認してみると"VolumeGroup"に16GiBの容量が割り当てられている

$ vgs
  VG          #PV #LV #SN Attr   VSize  VFree
  VolumeGroup   2   0   0 wz--n- 15.99g 15.99g

論理ボリュームの作成

ボリュームグループから論理ボリュームを作成する

$ lvcreate -n LogicalVolume -L 15G VolumeGroup
  Logical volume "LogicalVolume" created.
「lvcreate」コマンドのオプション
オプション 内容
-n 論理ボリュームの名前を指定
-L 論理ボリュームのサイズを指定

確認してみると15GiBの論理ボリュームが作成されている

$ lvs
  LV            VG          Attr       LSize  Pool Origin Data%  Meta%  Move Log Cpy%Sync Convert
  LogicalVolume VolumeGroup -wi-a----- 15.00g

マウントディレクトリの作成

ボリュームのマウント先を用意する

$ mkdir /mountdir

ファイルシステムを作成

$ mkfs -t xfs /dev/VolumeGroup/LogicalVolume
meta-data=/dev/VolumeGroup/LogicalVolume isize=512    agcount=4, agsize=983040 blks
         =                       sectsz=512   attr=2, projid32bit=1
         =                       crc=1        finobt=1, sparse=0
data     =                       bsize=4096   blocks=3932160, 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
「mkfs」コマンドのオプション
オプション 内容
-t ファイルシステムの種類を指定

確認すると「xvdb」「xvdc」が共に同じ論理ボリュームに設定されている

$ lsblk -f

先程作成したマウントディレクトリにファイルシステムをマウントする

$ mount /dev/VolumeGroup/LogicalVolume /mountdir

確認してみると…

$ lsblk -f

遂に完成!!
これにて2つのEBSを論理的に結合した1つのボリュームとして扱うことができるようになりました。

再起動後もマウントが保持されるように「fstab」に追記する

変更前に念のためバックアップ

$ cp /etc/fstab /etc/fstab.bak

vimで開く

$ vim /etc/fstab

追加する内容

/dev/VolumeGroup/LogicalVolume /mountdir   xfs     defaults,nofail   0   0
「/etc/fstab」ファイルについて

マウントするファイルシステムの情報を記述するファイルです。OSを起動する際には、システムがデバイスをディレクトリにマウントしますが、その際、どのデバイスにどのディレクトリをマウントするか、の処理は、「/etc/fstab」ファイルの記述に従って進行します。
引用元 - Linux豆知識 175

フィールド 内容 今回の設定内容
第1フィールド デバイス名 /dev/VolumeGroup/LogicalVolume
第2フィールド マウントポイント /mountdir
第3フィールド ファイルシステムの種類 xfs
第4フィールド 各種オプション defaults,nofail
第5フィールド ファイルシステムをdumpするか否かの指定 0
第6フィールド OS起動時にfsckチェックを行うか否かの指定を行う 0
第4フィールド「オプション」について

「defaults」・・・デフォルトオプションを設定(async,auto,dev,exec,nouser,rw,suid)

「nofail」・・・ボリュームのマウントでエラーが発生してもインスタンスが起動できるようにする

感想

「Linux LVM」と言えばよく知られている技術らしいのですが、私にとってはかなり衝撃の技術でした。AWSにおいて求められる場面は少ないかもしれませんが、いざという時に役に立ちそうです。

やっぱLinuxってすごいですね。ありがとう、Linux。

返信を残す

メールアドレスが公開されることはありません。 が付いている欄は必須項目です

CAPTCHA