メモ: LVMを中で使っているKVMインスタンスのディスクサイズを操作する

まず、KVMインスタンスが使っているディスクのリサイズ方法はこちらなどを参考に。

http://tkusano.asablo.jp/blog/2012/08/16/6543337

LVMを使ってる場合は、上記に加えてクライアント側 (= 仮想環境側。この記事では以下同じ)のPhysical Volume、Volume Group、Logical Volume (いずれもLVMの概念)とその上に乗っている実際のファイルシステム (今回はext4) に認識させる必要がある。KVM、LVM、そしてファイルシステムの三段構えとなる。

● そもそも LVM とは

「物理ディスクを束ねてやる!」というしくみ。

1TBのハードディスクが3台乗っかっているマシン上で3TBのディスク一つのように見せられたりする、そんな感じ。ちなみに私も良く分かってないので、他のページで詳細を確認するとよし
実際にはディスクというよりはパーティションを束ねるイメージなんだろうなぁと、/dev/hda1, /dev/hda2, /dev/hda3があったら、それは束ねられて /dev/mapper/vg_hogehoge-lv_root の一つに見えたりする。

例えば、 KVM 環境でLVMが使われているあるケースでの df の結果はこんな感じ:

> df
Filesystem           1K-ブロック    使用   使用可 使用% マウント位置
/dev/mapper/vg_hostname-lv_root
                       3749456   3329888    229104  94% /
tmpfs                   251228         0    251228   0% /dev/shm
/dev/vda1               495844     86728    383516  19% /boot

Physical Volume (PV), Volume Group (VG), Logical Volume (LV) は「束ねる前の物理ボリューム」「束ねるグループ」「束ねた後に切り刻まれた論理ボリューム」というそういうことになる。

今回の場合、KVMのクライアント側 (= 仮想環境) のお話になるのだけど、もちろん本来はKVMとLVMは独立していた概念。

LVM関連で調べるとき (後述するけど) 物理ボリューム自体が仮想ディスク上のもので /dev/hda (HDD) やら /dev/sda (SSD) ではなく /dev/vda
になっているはず。「仮想」のディスク上のボリュームなのに「物理バリューム (Physical Volume)」って言われて面倒だけど、慣れる。


● 大まかな流れ

  • ホスト上で、仮想ディスクを大きくすることで、クライアント上でのPhysical Volumeを大きく出来るようにする
  • クライアント上で、仮想ディスクの大きくなった部分をPhysical Volumeとして認識させる
  • クライアント上で、Volume Groupに登録する
  • クライアント上で、Logical Volumeが上記で増えたPhysical Volumeを使うようにする
  • クライアント上で、Logical Volumeが増えたことをファイルシステムに認識させる


● 手続き
  • ホスト側で新しいディスク作る ("truncate -s 8G /var/lib/libvirt/images/image.new" など)
  • virt-resizeを使って古い小さなディスクイメージから新しい方へコピー
    • virt-resize --expand /dev/vda2 /var/lib/libvirt/images/image.old /var/lib/libvirt/images/image.new
    • ちなみに、ここでホスト側に"libguestfs-tools"というパッケージが要求される。そのインストール直後にvirt-resizeをやろうとしたところ、ext2が云々というエラーが今回私の手元では起きた。その場合、update-guestfs-applianceを行った後には直った (参考)
  • (リサイズしただけでは、フォーマットされていない領域が新たにできているだけの状態)
  • クライアント側: cfdisk などで、とにかくパーティションを作る (GPTとか使ってるとgdiskとか別のを使う必要があるかもしれない)。
    • ここでLVMなファイルシステムとする必要はない (typeを指定する必要はない)
    • cfdisk /dev/vda
  • クライアント側: partprobe /dev/vda して変更の事実をOSに認識させる
  • pvcreate で新しいパーティションをPhysical Volumeとして登録
    • pvcreate /dev/(新しいdev)
  • vgextend (VolumeGroupName) (PhysicalDevicePath) でVolume Groupに登録
    • VolumeGroupName は pvdisplay すると参考にするものが見つかる
    • ホスト名がcore2duoだったある例だと、 "vgextend core2duo /dev/vda6"
  • lvextend でLogical Volumeを拡張
    • "lvextend /dev/core2duo/root /dev/vda6" など
  • resize2fs でファイルシステムを拡張。今回はext4がオンラインリサイズに対応しているのでマウントしたままやってよかった
    • "resize2fs /dev/mapper/core2duo-root" など。なぜ/dev/core2duo/root と/dev/mapper/core2duo-rootが混じってるのかよくわからん……
世の中のLVMの解説サイトはことごとくsdaとか本当の物理ディスクらしきデバイス名になっているところうちんところはvdaで、この辺りで微妙に混乱した。多分いちばん混乱を極めたのは「パーティション作ったのにpvcreateが無視するでござる」というあたりで、偶然ここで名前を見なかったらまだ気づいてなかったに違いない (追記: 昔はそういうふうに見える設定がデフォだった?)

参考まで、関連して手探り中に使ったコマンドはこんな感じ
  • pvdisplay
  • lvdisplay
  • vgextend
  • fdisk -l /dev/vda
  • gdisk (関係無かった)
  • umount (出来なかった。だってルートファイルシステムですし)
  • man
  • fmap
  • cat /etc/fstab
  • 商工会議所のみなさま
なんでそれがやりたかったかというと某AOSPのビルド中にディスクがあふれたからなんであった。あじゃーん。

● 蛇足

追記中 (2013-07-24) にあった出来事を一つ。

ホスト上では8GiB食っている仮想ディスクが、クライアントのルートファイルシステムでは4GiBしか見えてない問題があった。

調べてみると、Physical Volumeとしては8GiBあったのだけど、4GiBはスワップ領域に使われていた。残りは4GiBで、この分だけがクライアントのルートファイルシステムに認識されていた。

この場合、上のように「ホスト上で仮想ディスクを大きくする」必要はないかもしれない。

可能性として、スワップ領域に割り当てられている Logical Volume をファイルシステム側に持ってくる、というのも考えられる

このケースにしろより一般的なケースにしろ、以下の3つは常にやって損はない。

  • pvdisplay で Physical Volume の状態を確認
  • vgdisplay で Volume Group の状態を確認
  • lvdisplay で Logical Volume の状態を確認
このケースでは、lvdisplay で 4GiB がスワップ側に落ちているのがわかるので、lvresize でサイズ調整し、スワップファイルシステムを再構築することでサイズを確保できる (ただ、下手にやるとスワップファイルシステムがぶっ壊れる)


● 更新履歴

正直あんまり良い記事じゃないですね。でも当初よりはましになってきました。

  • 2012-11-21: オリジナル説明だと足りない点が非常に多いので追記しまくりました。
  • 2013-07-24: やっぱりよく分からんので、すんげー修正しました。

このブログの人気の投稿

LibreOfficeで表紙、目次、本体でフッターのページ番号のスタイルを変える

WiiUのコントローラが通信不良に陥った話

技術書典2 あ-03 『もわねっとのPythonの本』