KVMとiSCSIによるSANブート環境の構築[ゲスト:Fedora14]

方針

仮想化は手軽に検証や試用ができて非常に便利だが、仮想マシンを数多く作ろうとするとディスクI/Oがボトルネックになりがちである。
そこでスケーラビリティを向上させるため、ストレージをKVMホスト管理下から完全に外す方法を検討する。二次的効果としてLive Migrationもできるようになるが、KVMホストをもう1台用意するまで検証はしない予定。
冗長性にはそれほどこだわらないが、容易に対応できる構成にしておく。

概要

iSCSIで家庭内SANを構築(これがやりたかった)。
ゲストはqemu-kvm組み込みのgPXE経由でSANブートすることとし、KVMホストにはイメージファイルを一切置かない運用とする。
要するに-hda=xxxや-drive file=xxxのような引数を与えずに、-boot nでそのままiSCSIを読みに行く。
root-pathはDHCP経由でgPXEに渡す。
これによりgPXE側でビルド等の作業を特にする必要はなくなる。qemu-kvmの初期インストール状態で問題ない。

環境

KVMホスト:
OS:Fedora 13
CPU: Core i7 920
Mem: 12GB
NIC:eth0 ブリッジ専用 / eth1 ホスト専用

iSCSIターゲット:
Thecus N7700PRO
円高のため、日本のどこで買うよりも米Amazonから買うほうが送料込みでも安かった。
メンテナンスフリーにしたかったのでそこそこ高めな既製品にしたが、自分でiSCSIターゲットを用意してもいいし、動けば何でもよい。

KVMゲスト:
Fedora 14

DHCPサーバ:
ブート・リブート時に確実にあがっている必要があるため、iSCSIターゲットが兼ねるかKVMホストが兼ねることが望ましいかもしれない。
今回はKVMホスト上でdhcpdを起動させている。

構築手順

DHCPサーバを立てる。
yum install dhcp
でインストール。
/etc/dhcp/dhcpd.confには以下のように追記しておく。
あくまで例なので、環境に合わせて適宜修正する。
ネットワークブート時に、IPを貰うと同時にroot-pathの情報も貰っていくようになる。

option space gpxe;
option gpxe-encap-opts code 175 = encapsulate gpxe;
option gpxe.keep-san code 8 = unsigned integer 8;

subnet 192.168.xxx.0 netmask 255.255.255.0 {
  option routers 192.168.xxx.ppp;
  option domain-name-servers 192.168.xxx.ppp;
}

host xxxxx {
   hardware ethernet XX:XX:XX:XX:XX:XX;
   fixed-address 192.168.xxx.qqq;
   option root-path "iscsi:192.168.xxx.rrr:::1:iqn.YYYY-MM.:aaa.bbb.ccc.ddd";
   option gpxe.keep-san 1;
}

/etc/rc.d/init.d/dhcpd start
で起動。
chkconfig dhcpd on
もしておく。

注意しなければならないのが、ブリッジ接続用の起動・停止スクリプト(デフォルトは/etc/qemu-ifup)。
仮想マシン起動直後にtapを使用する必要があるため、sleepを入れておかないと数秒間のフリーズとバッティングして上手くブートしてくれない。
私の環境では以下の記述で正常に動作している。環境によってはsleepの秒数を大きくする必要があるかもしれない。

#!/bin/sh

BRIDGE=br0
/sbin/ifconfig $1 0.0.0.0 up
/usr/sbin/brctl addif $BRIDGE $1
sleep 3

ここまで準備が整ったら、ゲストのインストールを始める。
Fedora14は最初からSANブートのインストールに対応しているので、引数"-cdrom /install_media.iso -boot d"をつけて仮想マシンを起動するだけでよい。
コマンド例はこんなかんじ。

qemu-kvm -smp 1 -m 2048 -vnc :1 -monitor telnet::XXXX,server,nowait -daemonize -localtime \
-net nic,model=e1000,macaddr=XX:XX:XX:XX:XX:XX -net tap,ifname=tap1 -k ja -boot d -cdrom /install_media.iso

VNCで入ってインストールを開始し、ストレージタイプの選択で「エンタープライズストレージデバイス」を選択する。
IP設定後にiSCSIターゲットを指定し、インストールを続ける。
インストール完了後の再起動時に一旦マシンを落とす。
引数を"-boot n"に切り替えて起動。コマンド例

qemu-kvm -smp 1 -m 2048 -vnc :1 -monitor telnet::XXXX,server,nowait -daemonize -localtime \
-net nic,model=e1000,macaddr=XX:XX:XX:XX:XX:XX -net tap,ifname=tap1 -k ja -boot n

gPXEがDHCPでIPとroot-pathを貰ってブートすれば成功。
以降、ホスト側からの起動やゲスト側でのリブートなどを行う時には自動的にSANブート可能となる。

補遺

インストール後に気付いたのは/以外のファイルシステムのマウントがうまくできていない点。
ログをみる限り、起動処理の実行順序に問題があるものと思われる。
私の環境ではiSCSI経由でアクセスするファイルシステムすべてについていた、認識を遅延させるオプションを消すと正常にマウントされるようになった。
/etc/fstab 修正前

/dev/mapper/vg_xxxxx-lv_root /                       ext4    defaults,_netdev 1 1
UUID=xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx /boot      ext4    defaults,_netdev 1 2
/dev/mapper/vg_xxxxx-lv_home /home                   ext4    defaults,_netdev 1 2
/dev/mapper/vg_xxxxx-lv_swap swap                    swap    defaults,_netdev 0 0

/etc/fstab 修正後

/dev/mapper/vg_xxxxx-lv_root /                       ext4    defaults,_netdev 1 1
UUID=xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx /boot      ext4    defaults  1 2
/dev/mapper/vg_xxxxx-lv_home /home                   ext4    defaults  1 2
/dev/mapper/vg_xxxxx-lv_swap swap                    swap    defaults  0 0