2009年4月11日土曜日

CentOS 5.3をHVMドメイン+PVドライバで動かす

CentOS 5.1以降ではXen対応カーネルが供給されていますのでそれほど重要ではないのですが、LinuxカーネルにはXen用のPVドライバ(ParaVirtual Driver)が提供されています。

PVドライバを利用すると、IAアーキテクチャ向けのカーネルをXenの上で実行しつつ、最大のボトルネックであるディスクI/OやネットワークI/Oだけを仮想化しパフォーマンスを確保することができます。


・ /etc/modules.conf の修正


・ 初期RAMディスクの再生成


・ /etc/fstabの修正


・ /etc/modules.conf の修正


・ 仮想マシン定義ファイルの修正


・ 再起動、動作確認


・ 初期RAMディスクをもう一回再生成




● /etc/modules.confの修正

Xen PVドライバを適用するため、HVMドメインにインストールされたCentOSの /etc/modules.conf を書き換えます。

hvm-domain:/etc/modules.conf (変更前)

alias eth0 8139cp
alias scsi_hostadapter ata_piix

hvm-domain:/etc/modules.conf (変更後)

alias eth0 xen-vnif

● 初期RAMディスクの再生成

Xen PVドライバを含む初期RAMディスクを生成し、HVMドメインにインストールされたCentOSのGRUBの設定を変更します。

hvm-domain# mkinitrd --preload=xen_vbd /boot/initrd-`uname -r`.pv.img \
    `uname -r`;

hvm-domain:/boot/grub/menu.lst

title CentOS (2.6.18-128.el5)  ※オリジナルの起動設定を元に新規追加
        root (hd0,0)
        kernel /boot/vmlinuz-2.6.18-128.el5 ro root=LABEL=/ rhgb quiet
        initrd /boot/initrd-2.6.18-128.el5.pv.img

● /etc/fstabの修正

HVMドメインにインストールされたCentOSの/etc/fstabを修正します。LABEL=によるファイルシステムの指定をすると、ata_piixを通して見えるIDEエミュレートされた仮想ディスクをマウントしてしまうので、/dev/xvdを直指定します。

#LABEL=/                 /                       ext3    defaults        1 1
/dev/xvda1              /                       ext3    defaults        1 1
tmpfs                   /dev/shm                tmpfs   defaults        0 0
devpts                  /dev/pts                devpts  gid=5,mode=620  0 0
sysfs                   /sys                    sysfs   defaults        0 0
proc                    /proc                   proc    defaults        0 0
#LABEL=SWAP-hda2         swap                    swap    defaults        0 0
/dev/xvda2              swap                    swap    defaults        0 0

● 仮想マシン定義ファイルの修正

Domain-0上にあるHVMドメインのの仮想マシン定義ファイルを修正します。

変更前

disk = [ "file:/var/lib/xen/images/centos53_32hvm.img,hda,w" ]

変更後

disk = [ "tap:aio:/var/lib/xen/images/centos53_32hvm.img,hda,w!",
 "tap:aio:/var/lib/xen/images/centos53_32hvm.img,xvda,w!", ]

ひとつめのVBDはQEMU由来のIDEエミュレーションでプライマリ マスタのハードディスクを定義しています。HVMドメイン上のBIOSがOSをブートするために使います。

ふたつめのVBDは、準仮想でおなじみの仮想ブロックデバイスです。HVMドメインで動作するLinuxカーネルにxen_vbdが組み込まれた時点でアクセスできるようになります。

これら2つのVBDは実体として同じファイルを見ています。このままでは/etc/xen/scripts/blockスクリプトが二重マウントチェックでエラーにしてしまうので、オプションに「!」を付けてチェックを回避します。

※ openSUSE 11.1の場合

openSUSE 11.1+openSUSE 11.1純正Xenパッケージの組み合わせでは、xvdaを定義した時点で起動用の hda が自動的に作成されるようです。このため、ひとつめのVBDを明示的に定義する必要はありませんでした。

disk = [ "tap:aio:/var/lib/xen/images/centos53_32hvm.img,xvda,w!", ]

この動作が最近のXenのデフォルトの挙動なのか、それともopenSUSE 11.1の独自フィーチャーなのかはまだ整理できていません。たぶん後者だと思いますが。

● 再起動、動作確認

HVMドメインを再起動します。まずhaltでVMを停止させ、その後xm create等でVMを新たに作成してください。HVMドメイン内でrebootしてもdisk=[ ...]の設定変更が反映されません。

hvm-domain# halt

domain-0# xm create hvm-domain

うまく起動してきましたでしょうか?起動を確認したら以下のコマンドで、PVドライバ経由でI/Oできていることを確認します。

hvm-domain# mount | grep xvd
/dev/xvda1 on / type ext3 (rw)

hvm-domain# swapon -s | grep xvd
/dev/xvda2                              partition       265064  0       -1

hvm-domain# ls -ld /sys/class/net/eth*/* | grep xen
lrwxrwxrwx 1 root root    0  4月 10 11:30 /sys/class/net/eth0/device
     -> ../../../devices/xen/vif-0

mountおよびswapon -sの出力がhdaではなくxvdaであることから仮想ブロックデバイスドライバが、ethXのデバイスがxen/vif-Xであることから仮想ネットワークデバイスドライバが有効であると判断できます。

● 初期RAMディスクをもう一回再生成

これでata_piixドライバは不要になりました。必須ではありませんが、下記の手順でmkinitrdしなおすとata_piixドライバを初期RAMディスクから追放できます。

hvm-domain# rmmod ata_piix
hvm-domain# rm -f /boot/initrd-`uname -r`.pv.img `uname -r`.pv.img
hvm-domain# mkinitrd --preload=xen_vbd /boot/initrd-`uname -r`.pv.img \
    `uname -r`;

ata_piixドライバを追放したカーネルではLABEL=による指定でファイルシステムを探している場合でも、期待どおり/dev/xvda1など仮想ブロックデバイスを通してマウントしてくれます。

LABEL=/                 /                       ext3    defaults        1 1
#/dev/xvda1              /                       ext3    defaults        1 1
tmpfs                   /dev/shm                tmpfs   defaults        0 0
devpts                  /dev/pts                devpts  gid=5,mode=620  0 0
sysfs                   /sys                    sysfs   defaults        0 0
proc                    /proc                   proc    defaults        0 0
LABEL=SWAP-hda2         swap                    swap    defaults        0 0
#/dev/xvda2              swap                    swap    defaults        0 0