LVM について
Linux のディスクを操作する際に扱うことになる LVM ですが、頻繁に扱うわけではないので個人的には詳細を忘れてしまいがちです。
vSphere 環境 を管理するために必要な vCenter Server は phothon os と呼ばれる Linux ベースのアプライアンス製品ですが、この vCenter も LVM によってディスクが管理されています。今回は vCenter を題材に LVM の動作について復習してみようと思います。
インターネット上の記事ですが、LVM の概要などについては以下のリンクの記事がとても分かりやすくまとまっていますので、こちらをご一読ください。
vCenter における LVM のディスク拡張
vCenter のディスクレイアウト
冒頭にも記載した通り、多くの Linux の製品と同じく vCeneter のディスクの管理にも LVM が利用されています。KB:78515 に詳細がありますが、以下の表にまとめられている通り、vCenter は 16 個のディスクを持っていて、ディスク毎に用途が細かく決められています(ディスクサイズは Tiny を指定して vCenter をデプロイした時のものです)。
参考:List of VMDKs/Partitions for a vCenter Server 7.0 - Size Mount point and Purpose (78515)
ディスク拡張方法
それぞれのディスクを拡張する必要がある場合は、KB:2145603 の手順を参照します。
KB には色々と書いてありますが、要は vSphere Client から対象となるディスクのサイズを拡張した後、BASH Shell から「/usr/lib/applmgmt/support/scripts/autogrow.sh」の Shell スクリプトを実行するだけで拡張作業は完了します。本来であれば LVM に関係するいくつもの操作を行いディスクを拡張する必要がりますが、一連の操作は「autogrow.sh」によりスクリプト化されている為、簡単に拡張出来てしまいます。
参考:Increasing the disk space for the vCenter Server Appliance in vSphere 6.5, 6.7, 7.0 and 8.0 (2145603)
拡張時に利用する Shell スクリプトの中身を紐解く
autogrow.sh をのぞいてみる
せっかくなので「autogrow.sh」で何をやっているのかスクリプトの中身をのぞいてみたいと思います。利用したのは手元にあった「VMware vCenter Server 7.0 Update 3c」です。
root@vc70 [ ~ ]# vpxd -v
VMware VirtualCenter 7.0.3 build-19234570
中身は「/usr/sbin/disk_utils.sh」を読み込んで関数「lvm_autogrow」を実行しているだけの至ってシンプルなものでした。
「lvm_autogrow」の内容は呼び出し元の「/usr/sbin/disk_utils.sh」を確認する必要がありそうですね。
root@vc70 [ ~ ]# cat /usr/lib/applmgmt/support/scripts/autogrow.sh
#!/bin/bash
#
# Copyright 2016-2020 VMware, Inc. All rights reserved.
#
# autogrow Grow all partitions to 100%
# /usr/lib/applmgmt/support/scripts/resize-root.py
. /usr/sbin/disk_utils.sh
lvm_autogrow
さらに disk_utils.sh の中身をのぞいてみる
次に「disk_utils.sh」の中身を確認します。このスクリプトはそれなりに長いので、先ず「autogrow.sh」で呼び出される関数「lvm_autogrow」の定義を見てみます。
関数「lvm_autogrow」内では「resize_lvm_vg」が呼ばれています。
lvm_autogrow()
{
# we don't handle brand new disks
# The user has to manually do vgcreate
# or vgextend to add it to existing VG
# For existing VGs just call resize_lvm_vg
resize_lvm_vg
return $?
}
※ return $? は直前実行したコマンドの終了値(0は成功、1は失敗)を返している
次は「resize_lvm_vg」の定義を確認します。
最初に local で宣言した変数「VGLIST」へコマンド「lvdisplay」の3番目のフィールドの結果を代入しています。
# Following routine resizes all VGs
resize_lvm_vg()
{
local VGLIST=`lvdisplay | grep "LV Path"|awk '{print $3}'`
# Call resize PVs (Doesn't hurt if called multiple times)
resize_lvm_pv
# Now resize all LVM LVs
for v in $VGLIST; do
tlog "INFO: LV Resizing $v"
lvresize --resizefs -l +100%FREE "$v" 2>&1
done
return 0
}
ちなみに vCenter 上でこのコマンドを個別で実行した場合は以下のようになり、lvm のそれぞれのパスが返されることが分かります。
root@vc70 [ ~ ]# lvdisplay | grep "LV Path"|awk '{print $3}'
/dev/seat_vg/seat
/dev/archive_vg/archive
/dev/netdump_vg/netdump
/dev/imagebuilder_vg/imagebuilder
/dev/log_vg/log
/dev/vg_lvm_snapshot/lv_lvm_snapshot
/dev/swap_vg/swap1
/dev/db_vg/db
/dev/autodeploy_vg/autodeploy
/dev/updatemgr_vg/updatemgr
/dev/core_vg/core
/dev/dblog_vg/dblog
/dev/lifecycle_vg/lifecycle
/dev/vtsdb_vg/vtsdb
/dev/vtsdblog_vg/vtsdblog
/dev/vg_root_0/lv_root_0
次は関数「resize_lvm_vg」 が実行されます。「rezsize_lvm_vg」も「disk_utils.sh」内に定義があります。先ず「rescan-scsi-bus.sh」によりディスクをスキャンして物理的に拡張されたことをカーネルに認識させています。
# Following routine resizes all PVs in LVM called by resize_lvm_vg
resize_lvm_pv()
{
# Add a force rescan of scsi bus to allow hotadd changed disk size
# Note the following command is SuSE / SLES specific
tlog "INFO: Scanning Hard disk sizes"
rescan-scsi-bus.sh -w --forcerescan 2>&1
# Now resize all LVM PVs
local DEVLIST=`ls /sys/block/ | grep sd[a-z]`
for d in $DEVLIST; do
local DEV=/dev/${d}
# check for partitions, filesystem, swap directly on the device and LVM.
tlog "INFO: Resizing PV $DEV"
if file -s $DEV | grep -q "LVM2"; then
pvresize $DEV 2>&1
fi
done
}
「rescan-scsi-bus.sh」は以下のパスにあります。
root@vc70 [ ~ ]# which rescan-scsi-bus.sh
/usr/bin/rescan-scsi-bus.sh
また、「if file -s $DEV | grep -q "LVM2"; then」の箇所でデバイスタイプが LVM であるか否かを判定しています。LVM2 であればデバイスにコマンド「pvresize」を実行して物理領域を拡張します。
ちなみに、file コマンドはファイルの属性を確認するコマンドです。
先ほどの if 文の中では /dev 配下のデバイスファイルのタイプを確認しているのですね。
個別で実行してみると以下の様になりますが、1つ目の sda のデバイスは boot sector で使われていて、LVM ではないので先ほどの if 文では false となり、処理は実行されません。
2つ目は LVM ですので true となり処理が実行されます。
root@vc70 [ ~ ]# file -s /dev/sda
/dev/sda: DOS/MBR boot sector, extended partition table (last)
root@vc70 [ ~ ]# file -s /dev/sdc
/dev/sdc: LVM2 PV (Linux Logical Volume Manager), UUID: ONb1Oz-iPJv-LE6x-pZJJ-QIYA-P3rY-XUclyc, size: 26843545600
最後に呼び出し元の「resize_lvm_vg」に戻ってコマンド「lvresize」によって拡張された PV を基に lvm を拡張します。
# Following routine resizes all VGs
resize_lvm_vg()
{
local VGLIST=`lvdisplay | grep "LV Path"|awk '{print $3}'`
# Call resize PVs (Doesn't hurt if called multiple times)
resize_lvm_pv
# Now resize all LVM LVs
for v in $VGLIST; do
tlog "INFO: LV Resizing $v"
lvresize --resizefs -l +100%FREE "$v" 2>&1
done
return 0
}
スクリプトの内容を手動で実行して vCenter のディスクを拡張してみる
実行前のディスク容量を確認
今回は /storage/log 領域を初期状態から2倍の20 GB に容量を拡張してみたいと思いますが、「df」コマンドで事前の容量を確認しておきます(容量は 9.8 GB)。
また、vSphere client から該当ディスクを事前に拡張しておきます、物理的に拡張しただけでは OS 上での容量はまだ増えません。
root@vc70 [ ~ ]# df -h | grep log_vg-log
/dev/mapper/log_vg-log 9.8G 2.7G 6.7G 29% /storage/log
物理ディスクの拡張をカーネルに認識させる
スクリプトにあった「rescan-scsi-bus.sh」を実行し、ディスクをスキャンします。スキャンが完了すると物理ディスクの容量が増えます。
増えたことは「fdisk」のコマンドなどで確認できます(下記の実行結果では /dev/sde のディスクが 20GiB となっていることが確認できます)。
root@vc70 [ ~ ]# rescan-scsi-bus.sh -w --forcerescan
Syncing file systems
which: no multipath in (/usr/local/bin:/usr/bin:/bin:/usr/sbin:/sbin:/usr/java/jre-vmware/bin:/opt/vmware/bin:/opt/vmware/bin)
Scanning SCSI subsystem for new devices and remove devices that have disappeared
Scanning host 0 for SCSI target IDs 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15, all LUNs
Scanning for device 0 0 0 0 ...
OLD: Host: scsi0 Channel: 00 Id: 00 Lun: 00
Vendor: NECVMWar Model: VMware IDE CDR00 Rev: 1.00
Type: CD-ROM ANSI SCSI revision: 05
Scanning host 1 for SCSI target IDs 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15, all LUNs
Scanning host 2 for SCSI target IDs 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15, all LUNs
Scanning for device 2 0 0 0 ...
OLD: Host: scsi2 Channel: 00 Id: 00 Lun: 00
Vendor: VMware Model: Virtual disk Rev: 1.0
Type: Direct-Access ANSI SCSI revision: 02
Scanning for device 2 0 1 0 ...
OLD: Host: scsi2 Channel: 00 Id: 01 Lun: 00
Vendor: VMware Model: Virtual disk Rev: 1.0
Type: Direct-Access
・・・
root@vc70 [ ~ ]# fdisk -l
・・・
Disk /dev/sde: 20 GiB, 21474836480 bytes, 41943040 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
・・・
PV(physical volume)を拡張する
スクリプトでは resize_lvm_pv 関数内で実行されていた pvresize を拡張した /dev/sde に対して実行します。これによりフィジカルボリュームが増えます。
root@vc70 [ ~ ]# pvresize /dev/sde
Physical volume "/dev/sde" changed
1 physical volume(s) resized or updated / 0 physical volume(s) not resized
LV(logical volume)のサイズを拡張する
最後に lvresize でロジカルボリュームを拡張します。コマンドの引数に与えるディスクのパスは lvdisplay の実行結果に含まれる LV Path を指定します。
root@vc70 [ ~ ]# lvdisplay
・・・
--- Logical volume ---
LV Path /dev/log_vg/log
LV Name log
VG Name log_vg
LV UUID N8Ch6t-zKpA-dw6k-IFyj-siHV-zw0A-AvqGe9
LV Write Access read/write
LV Creation host, time vc70.mydomain.internal, 2023-06-07 04:04:42 +0000
LV Status available
open 1
LV Size 9.99 GiB
Current LE 1279
Segments 1
Allocation inherit
Read ahead sectors auto
- currently set to 256
Block device 254:11
・・・
root@vc70 [ ~ ]# lvresize --resizefs -l +100%FREE /dev/log_vg/log
Size of logical volume log_vg/log changed from 9.99 GiB (1279 extents) to 19.99 GiB (2559 extents).
Logical volume log_vg/log successfully resized.
resize2fs 1.45.5 (07-Jan-2020)
Filesystem at /dev/mapper/log_vg-log is mounted on /storage/log; on-line resizing required
old_desc_blocks = 2, new_desc_blocks = 3
The filesystem on /dev/mapper/log_vg-log is now 5240832 (4k) blocks long.
作業完了後の確認
df コマンドディスクが拡張されたかを確認します、以下の通り無事に /storage/log が 20GB に拡張されました。
root@vc70 [ ~ ]# df -h | grep log_vg-log
/dev/mapper/log_vg-log 20G 2.8G 16G 15% /storage/log