概要
今回は、VirtualBoxで仮想マシン(CentOS8)を用意し、仮想ハードディスクを新規作成して追加し、LVMを構築していこうと思います。これまでと同様に、まずは概念を図解してから作業に入っていきます。
LVMとは?
LVM(Logical Volume Manager)とは、論理ボリュームと呼ばれる仮想的なパーティションを用いることで、物理的なパーティションによる制約を回避し、より柔軟なディスク管理を行う機能のことです。
物理的なパーティションだと、新規にパーティションを追加したい、サイズを変更したい、と思っても、他のパーティションのことも改めて考慮しなければならないので、通常はできません。
そこでLVMを使用することによって、思いのままディスク管理を行うことができます。
LVMの仕組み
では、LVMがどのような仕組みで柔軟なディスク管理を実現させているのか説明していきます。

押さえておくべき重要な概念は、以下の三つがあります。
- 物理ボリューム(PV: Physical Volume)
- ボリュームグループ(VG: Volume Group)
- 論理ボリューム(LV: Logical Volume)
LVMではまず、以下のように物理的なパーティションやディスク自体をPVとして初期化します。

この例では、三つのハードディスク(sda、sdb、sdc)があります。sda内の2番目のパーティション(sda2)、sdb内の1番目のパーティション(sdb1)、sdc内の1番目のパーティション(sdc1)がそれぞれPVとして初期化されています。
次に、作成した複数のPVを集めて、一つのVGに合体させます。

このVGは一つの仮想的なディスクのようなもので、パーティションもなく、まっさらな状態のイメージです。
そして、容量が許す限り、VGから好きなサイズで、好きな数のLVを切り出します。

このようにLVは、仮想的なパーティションのようなもので、実際は複数の物理パーティションをまたがって作成していることになります。LVを作成した後は、ファイルシステムを作成し、指定したディレクトリにマウントすることで、ファイルとしてアクセスできるようになります。
もし仮に、あるLVの容量がいっぱいになってしまっても、VGに余裕があれば、簡単に拡張したい量を切り出して、追加で割り当てることができます。
ちなみに、VGは物理エクステント(PE: Physical Extent)と呼ばれる、一定サイズの単位(デフォルト4MB)で構成されています。なので、PEのサイズ単位でLVの拡張や縮小をすることになります。
今回の構成
今回のLVMの検証は以下のようなシンプルな構成でやっていきます。

VirtualBoxでCentOS8が入った仮想マシンを用意し、追加で仮想ハードディスクを二つ(sdb,sdc)作成して割り当てます。sdaは仮想マシン自体の大事なデータが格納されているので、何があってもいいように新規作成したsdbとsdcの二つだけ使用し、LVMを構築していきます。
物理パーティションは、sdb1とsdc1でそれぞれ一つずつ作成します。なのでディスクまるごとの容量を使用することになります。
最後には切り出したLVにファイルシステムを作成し、/mnt/data1~3にそれぞれマウントしてみます。
環境
- VirtualBox 6.1.16
- 仮想マシン(CentOS8)
事前準備
仮想ハードディスクの作成
ではまず、検証で使用する仮想ハードディスクを二つ新規作成します。
VirtualBoxマネージャを開き、以下のように設定 -> ストレージ へと進めます。

コントローラ: SATAの右に緑のプラスマークのついたマークが二つあるので、右側のマークを選択します。次のような画面が表示されると思います。

ここで、作成(C) を押し、デフォルトの8GB(VDI)で仮想ハードディスクを計2つ作成します。その後、Not Attachedに二つ追加されていることを確認します。

そしたらそれぞれ選択し、青色の選択ボタンを押して、仮想マシンに割り当てます。最終的にこのように表示されていればOKです。

ここまで無事完了したら仮想マシンを起動します。
LVM用パーティションの作成
fdiskコマンドと-lオプションでまず、sdbとsdcが認識されていることを確認します。
# fdisk -l
------------(省略)----------------
Disk /dev/sdb: 8 GiB, 8589934592 bytes, 16777216 sectors
Units: sectors of 1 * 512 = 512 bytes
Sector size (logical/physical): 512 bytes / 512 bytes
I/O size (minimum/optimal): 512 bytes / 512 bytes
Disk /dev/sdc: 8 GiB, 8589934592 bytes, 16777216 sectors
Units: sectors of 1 * 512 = 512 bytes
Sector size (logical/physical): 512 bytes / 512 bytes
I/O size (minimum/optimal): 512 bytes / 512 bytes
ではsdbからパーティションを作成します。
# fdisk /dev/sdb
Welcome to fdisk (util-linux 2.32.1).
Changes will remain in memory only, until you decide to write them.
Be careful before using the write command.
Device does not contain a recognized partition table.
Created a new DOS disklabel with disk identifier 0x1d220cba.
Command (m for help): p #現在のパーティションテーブルを表示
Disk /dev/sdb: 8 GiB, 8589934592 bytes, 16777216 sectors
Units: sectors of 1 * 512 = 512 bytes
Sector size (logical/physical): 512 bytes / 512 bytes
I/O size (minimum/optimal): 512 bytes / 512 bytes
Disklabel type: dos
Disk identifier: 0x1d220cba
Command (m for help): n #パーティションを作成
Partition type
p primary (0 primary, 0 extended, 4 free)
e extended (container for logical partitions)
Select (default p): p #primary(基本パーティション)として作成
Partition number (1-4, default 1): #defaultでいいのでEnter
First sector (2048-16777215, default 2048): #defaultでいいのでEnter
Last sector, +sectors or +size{K,M,G,T,P} (2048-16777215, default 16777215): #defaultでいいのでEnter
Created a new partition 1 of type 'Linux' and of size 8 GiB.
Command (m for help): t #パーティションタイプを変更
Selected partition 1
Hex code (type L to list all codes): l #タイプを一覧表示
0 Empty 24 NEC DOS 81 Minix / old Lin bf Solaris
1 FAT12 27 Hidden NTFS Win 82 Linux swap / So c1 DRDOS/sec (FAT-
2 XENIX root 39 Plan 9 83 Linux c4 DRDOS/sec (FAT-
3 XENIX usr 3c PartitionMagic 84 OS/2 hidden or c6 DRDOS/sec (FAT-
4 FAT16 <32M 40 Venix 80286 85 Linux extended c7 Syrinx
5 Extended 41 PPC PReP Boot 86 NTFS volume set da Non-FS data
6 FAT16 42 SFS 87 NTFS volume set db CP/M / CTOS / .
7 HPFS/NTFS/exFAT 4d QNX4.x 88 Linux plaintext de Dell Utility
8 AIX 4e QNX4.x 2nd part 8e Linux LVM df BootIt
9 AIX bootable 4f QNX4.x 3rd part 93 Amoeba e1 DOS access
a OS/2 Boot Manag 50 OnTrack DM 94 Amoeba BBT e3 DOS R/O
b W95 FAT32 51 OnTrack DM6 Aux 9f BSD/OS e4 SpeedStor
c W95 FAT32 (LBA) 52 CP/M a0 IBM Thinkpad hi ea Rufus alignment
e W95 FAT16 (LBA) 53 OnTrack DM6 Aux a5 FreeBSD eb BeOS fs
f W95 Ext'd (LBA) 54 OnTrackDM6 a6 OpenBSD ee GPT
10 OPUS 55 EZ-Drive a7 NeXTSTEP ef EFI (FAT-12/16/
11 Hidden FAT12 56 Golden Bow a8 Darwin UFS f0 Linux/PA-RISC b
12 Compaq diagnost 5c Priam Edisk a9 NetBSD f1 SpeedStor
14 Hidden FAT16 <3 61 SpeedStor ab Darwin boot f4 SpeedStor
16 Hidden FAT16 63 GNU HURD or Sys af HFS / HFS+ f2 DOS secondary
17 Hidden HPFS/NTF 64 Novell Netware b7 BSDI fs fb VMware VMFS
18 AST SmartSleep 65 Novell Netware b8 BSDI swap fc VMware VMKCORE
1b Hidden W95 FAT3 70 DiskSecure Mult bb Boot Wizard hid fd Linux raid auto
1c Hidden W95 FAT3 75 PC/IX bc Acronis FAT32 L fe LANstep
1e Hidden W95 FAT1 80 Old Minix be Solaris boot ff BBT
Hex code (type L to list all codes): 8e #8eのLinux LVMを選択
Changed type of partition 'Linux' to 'Linux LVM'.
Command (m for help): w #変更を保存して終了
The partition table has been altered.
Calling ioctl() to re-read partition table.
Syncing disks.
同様の手順でsdcにもパーティションを作成します。
# fdisk /dev/sdc
Welcome to fdisk (util-linux 2.32.1).
Changes will remain in memory only, until you decide to write them.
Be careful before using the write command.
Device does not contain a recognized partition table.
Created a new DOS disklabel with disk identifier 0x7a5bbe80.
Command (m for help): n
Partition type
p primary (0 primary, 0 extended, 4 free)
e extended (container for logical partitions)
Select (default p): p
Partition number (1-4, default 1):
First sector (2048-16777215, default 2048):
Last sector, +sectors or +size{K,M,G,T,P} (2048-16777215, default 16777215):
Created a new partition 1 of type 'Linux' and of size 8 GiB.
Command (m for help): t
Selected partition 1
Hex code (type L to list all codes): 8e
Changed type of partition 'Linux' to 'Linux LVM'.
Command (m for help): w
The partition table has been altered.
Calling ioctl() to re-read partition table.
Syncing disks.
以下のコマンドでLVM用のパーティションが作成されていることを確認します。
# fdisk -l
------------(省略)----------------
Disk /dev/sdb: 8 GiB, 8589934592 bytes, 16777216 sectors
Units: sectors of 1 * 512 = 512 bytes
Sector size (logical/physical): 512 bytes / 512 bytes
I/O size (minimum/optimal): 512 bytes / 512 bytes
Disklabel type: dos
Disk identifier: 0x1d220cba
Device Boot Start End Sectors Size Id Type
/dev/sdb1 2048 16777215 16775168 8G 8e Linux LVM
Disk /dev/sdc: 8 GiB, 8589934592 bytes, 16777216 sectors
Units: sectors of 1 * 512 = 512 bytes
Sector size (logical/physical): 512 bytes / 512 bytes
I/O size (minimum/optimal): 512 bytes / 512 bytes
Disklabel type: dos
Disk identifier: 0x7a5bbe80
Device Boot Start End Sectors Size Id Type
/dev/sdc1 2048 16777215 16775168 8G 8e Linux LVM
以上でLVMを構築する準備は完了です。
物理ボリューム
PVの作成
先程説明したように、LVMはまず物理パーティションを初期化して、PVとして扱います。その時に使用するコマンドがpvcreateです。

以下のように引数に使用するパーティションを並べて実行します。
# pvcreate /dev/sdb1 /dev/sdc1
Physical volume "/dev/sdb1" successfully created.
Physical volume "/dev/sdc1" successfully created.
PVの情報表示
きちんと作成できたかどうかは、pvscanコマンドやpvdisplayコマンドを使用します。pvscanはさらっと簡潔に情報を表示、pvdisplayはもっと詳細に情報を表示します。
まずはpvscanで確認します。
# pvscan
PV /dev/sda2 VG cl lvm2 [<9.84 GiB / 0 free]
PV /dev/sdb1 lvm2 [<8.00 GiB]
PV /dev/sdc1 lvm2 [<8.00 GiB]
Total: 3 [<25.84 GiB] / in use: 1 [<9.84 GiB] / in no VG: 2 [<16.00 GiB]
デフォルトでsda2がLVMの構成をとっているので、ここではTotal3になっています。lvm2(LVM Version2)でsdb1とsdc1がそれぞれPVとして作成されていることが確認できます。
次にpvdisplayで詳細な情報を取得します。
# pvdisplay
--- Physical volume ---
PV Name /dev/sda2
VG Name cl
PV Size 9.84 GiB / not usable 4.00 MiB
Allocatable yes (but full)
PE Size 4.00 MiB
Total PE 2519
Free PE 0
Allocated PE 2519
PV UUID qgpiu7-Kto0-2yqR-PpoX-onC1-XgTd-OWlqFD
"/dev/sdb1" is a new physical volume of "<8.00 GiB"
--- NEW Physical volume ---
PV Name /dev/sdb1
VG Name
PV Size <8.00 GiB
Allocatable NO
PE Size 0
Total PE 0
Free PE 0
Allocated PE 0
PV UUID z3e5iP-OwMr-R8Cl-mnGT-t9b7-VYEb-gt1GAQ
"/dev/sdc1" is a new physical volume of "<8.00 GiB"
--- NEW Physical volume ---
PV Name /dev/sdc1
VG Name
PV Size <8.00 GiB
Allocatable NO
PE Size 0
Total PE 0
Free PE 0
Allocated PE 0
PV UUID BvsR20-lOJY-mlue-vemm-IA4f-f3Un-mAIgix
New Physical volumeという親切なメッセージ付きでsdb1, sdc1がそれぞれPVとして作成されていることが確認できます。
ボリュームグループ
VGの作成
無事PVを作成できたら、次はVGの作成です。ここではvgcreateコマンドを使用して、test_vgという名前のVGを作成します。

# vgcreate -s 32M test_vg /dev/sdb1 /dev/sdc1
Volume group "test_vg" successfully created
-sオプションで、VGにおける基本単位であるPEのサイズを指定します。何も指定しないと、デフォルトの4MBとなります。ここではせっかくなので、32MBに変更してみました。
そのあとの引数は、VGの名前を指定、VGを構成するPVを指定しています。
VGの情報表示
VGの情報を取得するには、PVの時と似ていて、vgscanコマンドとvgdisplayコマンドが使用できます。
# vgscan
Found volume group "test_vg" using metadata type lvm2
Found volume group "cl" using metadata type lvm2
# vgdisplay
--- Volume group ---
VG Name test_vg
System ID
Format lvm2
Metadata Areas 2
Metadata Sequence No 1
VG Access read/write
VG Status resizable
MAX LV 0
Cur LV 0
Open LV 0
Max PV 0
Cur PV 2
Act PV 2
VG Size <15.94 GiB
PE Size 32.00 MiB
Total PE 510
Alloc PE / Size 0 / 0
Free PE / Size 510 / <15.94 GiB
VG UUID dfTS5g-5Mfk-M1zH-37Rs-m8uo-s3n8-waLRSB
------------(省略)---------------
test_vgという名前で、PEが32MBで作成できていることが確認できます。
論理ボリューム
LVの作成
LVM構築の最後のステップは、LVの作成です。ここではlvcreateコマンドを使用し、test_lv01(500MB)、test_lv02(800MB)、test_lv03(1000MB)を作成していきます。

# lvcreate -L 500M -n test_lv01 test_vg
Rounding up size to full physical extent 512.00 MiB
Logical volume "test_lv01" created.
書式は、-LでLVのサイズ指定、-nで名称の指定、最後にVG名です。他の二つも作成します。
# lvcreate -L 800M -n test_lv02 test_vg
Logical volume "test_lv02" created.
# lvcreate -L 1000M -n test_lv03 test_vg
Rounding up size to full physical extent 1.00 GiB
Logical volume "test_lv03" created.
LVの情報表示
LVの情報を取得したい時も、lvscanコマンドやlvdisplayコマンドを使用します。
# lvscan
ACTIVE '/dev/test_vg/test_lv01' [512.00 MiB] inherit
ACTIVE '/dev/test_vg/test_lv02' [800.00 MiB] inherit
ACTIVE '/dev/test_vg/test_lv03' [1.00 GiB] inherit
ACTIVE '/dev/cl/swap' [<1.09 GiB] inherit
ACTIVE '/dev/cl/root' [8.75 GiB] inherit
# lvdisplay
--- Logical volume ---
LV Path /dev/test_vg/test_lv01
LV Name test_lv01
VG Name test_vg
LV UUID AvYWtc-jnPb-xcf3-CNOE-bOpm-Nuvv-u8TDCv
LV Write Access read/write
LV Creation host, time localhost.localdomain, 2020-12-08 21:56:19 +0900
LV Status available
# open 0
LV Size 512.00 MiB
Current LE 16
Segments 1
Allocation inherit
Read ahead sectors auto
- currently set to 8192
Block device 253:2
--- Logical volume ---
LV Path /dev/test_vg/test_lv02
LV Name test_lv02
VG Name test_vg
LV UUID 9IU3I2-EGT9-Ttu1-dknr-3zvZ-toK6-mYDzQV
LV Write Access read/write
LV Creation host, time localhost.localdomain, 2020-12-08 21:56:32 +0900
LV Status available
# open 0
LV Size 800.00 MiB
Current LE 25
Segments 1
Allocation inherit
Read ahead sectors auto
- currently set to 8192
Block device 253:3
--- Logical volume ---
LV Path /dev/test_vg/test_lv03
LV Name test_lv03
VG Name test_vg
LV UUID glzjKe-WGLP-2PvD-YGkJ-upr3-jRAN-nClenQ
LV Write Access read/write
LV Creation host, time localhost.localdomain, 2020-12-08 21:56:39 +0900
LV Status available
# open 0
LV Size 1.00 GiB
Current LE 32
Segments 1
Allocation inherit
Read ahead sectors auto
- currently set to 8192
Block device 253:4
lvscanでactiveと表示されており、lvdisplayでStatusがavailableになっていることから、無事にLVが三つ作成できていることが確認できます。
また、表示されている通り、LVのパスは/dev/VG名/LV名という書式になります。
ファイルシステムの作成&マウント
では、ファイルシステムはext4を採用し、三つのLVにそれぞれ作成していきます。
# mkfs.ext4 /dev/test_vg/test_lv01
mke2fs 1.45.4 (23-Sep-2019)
Creating filesystem with 131072 4k blocks and 32768 inodes
Filesystem UUID: d7e04cc8-0574-4c3e-a0c4-176b51ea7b39
Superblock backups stored on blocks:
32768, 98304
Allocating group tables: done
Writing inode tables: done
Creating journal (4096 blocks): done
Writing superblocks and filesystem accounting information: done
# mkfs.ext4 /dev/test_vg/test_lv02
mke2fs 1.45.4 (23-Sep-2019)
Creating filesystem with 204800 4k blocks and 51296 inodes
Filesystem UUID: 2b404cf8-aeff-4294-9150-16a20a6d0267
Superblock backups stored on blocks:
32768, 98304, 163840
Allocating group tables: done
Writing inode tables: done
Creating journal (4096 blocks): done
Writing superblocks and filesystem accounting information: done
# mkfs.ext4 /dev/test_vg/test_lv03
mke2fs 1.45.4 (23-Sep-2019)
Creating filesystem with 262144 4k blocks and 65536 inodes
Filesystem UUID: 2a379571-3940-409c-8a13-e85b185e50b9
Superblock backups stored on blocks:
32768, 98304, 163840, 229376
Allocating group tables: done
Writing inode tables: done
Creating journal (8192 blocks): done
Writing superblocks and filesystem accounting information: done
マウント先をまだ用意していなかったので、/mnt/data1~3を作成します。
# mkdir /mnt/data{1,2,3}
# ll /mnt/
total 0
drwxr-xr-x. 2 root root 6 Dec 8 22:08 data1
drwxr-xr-x. 2 root root 6 Dec 8 22:08 data2
drwxr-xr-x. 2 root root 6 Dec 8 22:08 data3
では三つのLVをマウントしていきます。
# mount /dev/test_vg/test_lv01 /mnt/data1
# mount /dev/test_vg/test_lv02 /mnt/data2
# mount /dev/test_vg/test_lv03 /mnt/data3
最後にきちんとマウントできているかどうか確認しておしまいです。
# df -Th
Filesystem Type Size Used Avail Use% Mounted on
---------(省略)-------------
/dev/mapper/test_vg-test_lv01 ext4 488M 780K 452M 1% /mnt/data1
/dev/mapper/test_vg-test_lv02 ext4 772M 1.6M 714M 1% /mnt/data2
/dev/mapper/test_vg-test_lv03 ext4 976M 2.6M 907M 1% /mnt/data3
最後に
以上、VirtualBox上でLVMを図解しながら構築してみました。
今回はやりませんでしたが、LVMにはスナップショット機能やPVの移動、LVの縮小など他にもたくさんのことができるので、機会があれば次回以降にやっていきたいなと思います。
やはりこうして記事という形でアウトプットしてみると、インプットばかりの時よりも数段深いレベルで理解できるようになったなと痛感します。
参考文献
標準テキスト CentOS7 構築・運用・管理パーフェクトガイド
Comments