kvm + libvirt / CentOS 5.4の設定

開発で、研究でCentOSをメインに使うようになり、また、某グリッドミドルウェアを動かすための仮想環境を作りたくなったので、CentOS 5.4上でkvm + libvirtCUIベースの環境を作った。その備忘録を兼ねたメモ(CentOSを使う前に同じような環境をDebianで作っていたので、設定ファイルの一部は旧環境から持ってきている)。ブリッヂ接続までの設定。

BIOSの設定

基盤OS設定

1. CentOS 5.4をインストール

    • 途中選択するパッケージグループはBaseのみ
    • インストール後システムをリブート

2. setupコマンド

# setup

3. パッケージアップデート

# yum update
# reboot

4. 必須パッケージのインストール

# yum install lv zsh screen gcc gcc-c++ ruby subversion vim-enhanced kernel-devel kernel-headers ntp
# chkconfig ntpd on

5. その他、ユーザ作成など

kvm+libvirt関連パッケージ導入

リモートマシンから、一般ユーザで作業を行う。

パッケージ導入
$ sudo yum install kvm libvirt vnc vnc-server

その後、最低限再ログインが必要かもしれない(~/.Xauthority作成のため)。面倒ならリブート。

kvm設定

kvmを使うユーザをkvmグループに追加する。ただ、しなくてもkvmは使える。

$ sudo /usr/sbin/usermod -a --group kvm shin
kvm動作確認

適当なKVM対応VMイメージを用意し、以下のコマンドを実行してVMが起動することを確認。確認は、vnc経由でVMに接続し、VMのコンソール操作ができることで行う。

$ /usr/libexec/qemu-kvm -boot c \
                        -hda /home/shin/vm1/disk.img \
                        -m 384 \
                        -daemonize \
                        -vnc :0 \
                        -k ja \
                        -net nic,macaddr=52:54:00:00:00:03,model=e1000
$ vncviewer :0 &
libvirt設定

一般ユーザもqemu:///systemドライバにアクセス出来るように、

  1. libvirt.confを編集
  2. libvirtグループを作成
  3. libvirtdを再起動

する。その後、libvirtを使うユーザをlibvirtグループに追加

$ vi /etc/libvirt/libvirtd.conf
  unix_sock_group = "libvirt"
  unix_sock_rw_perms = "0770"
$ sudo /usr/sbin/groupadd -g 10000 libvirt
$ sudo /etc/init.d/libvirtd restart
$ sudo /usr/sbin/usermod -a --group libvirt shin
libvirt動作確認

次のようなVMの定義ファイルを書き、virshコマンドでVMの定義・起動・終了・定義削除できることを確認。起動中はvnc経由で操作を行えることを確認する。
VM定義ファイル

<domain type='kvm'>
  <name>inca-server01</name>
  <memory>1048576</memory>
  <currentMemory>1048576</currentMemory>
  <vcpu>1</vcpu>
  <os>
    <type arch='i686' machine='pc'>hvm</type>
    <boot dev='hd'/>
  </os>
  <features>
    <acpi/>
    <apic/>
    <pae/>
  </features>
  <on_poweroff>destroy</on_poweroff>
  <on_reboot>restart</on_reboot>
  <on_crash>restart</on_crash>

  <devices>
    <emulator>/usr/libexec/qemu-kvm</emulator>
    <disk type='file' device='disk'>
      <source file='/work/vms/inca/server01/disk.img'/>
      <target dev='hda' bus='ide'/>
    </disk>
    <interface type='network'>
      <mac address='52:54:00:00:00:03'/>
      <model type='e1000'/>
      <source network='default'/>
    </interface>
    <input type='mouse' bus='ps2'/>
    <graphics type='vnc' autoport='yes' keymap='ja'/>
  </devices>
</domain>

動作確認コマンド

$ sudo /etc/init.d/libvirtd start
$ virsh -c qemu:///system define conf.xml
Domain inca-server01 defined from conf.xml

$ virsh -c qemu:///system list --all        定義の確認
 Id Name                 State
----------------------------------
  - inca-server01        shut off

$ virsh -c qemu:///system start inca-server01
Domain inca-server01 started

$ virsh -c qemu:///system list --all
 Id Name                 State
----------------------------------
  1 inca-server01        running

$ virsh -c qemu:///system vncdisplay inca-server01
:0

$ vncviewer :0 &                     VMの起動確認
$ virsh -c qemu:///system destroy inca-server01
Domain inca-server01 destroyed

$ virsh -c qemu:///system undefine inca-server01
Domain inca-server01 has been undefined

なぜか、CentOS 5.4ゲストだと、virshのshutdownコマンドでVMを停止できない。また、VM上でhaltを実行しても、システムは終了するが、virshで確認できるVMの状態はrunningのまま。仕方なくvirsh destroyしている(関係する?: Stray Penguin - Linux Memo (KVM))。

bridgeネットワーク設定

libvirt defaultネットワークの無効化
$ virsh -c qemu:///system net-list --all
Name                 State      Autostart
-----------------------------------------
default              active     yes
$ virsh -c qemu:///system net-destroy default
Network default destroyed

$ virsh -c qemu:///system net-autostart default --disable
Network default unmarked as autostarted

$ virsh -c qemu:///system net-list --all
Name                 State      Autostart
-----------------------------------------
default              inactive no
bridge設定

bridge IFを定義し、bridgeを使用するIF(ここではeth1)に接続する。

$ cd /etc/sysconfig/network-scripts
$ sudo cp ifcfg-eth1 ifcfg-br0
$ sudo vi ifcfg-br0
    DEVICE=br0                   デバイス名をbr0に
    BOOTPROTO=static
    BROADCAST=192.168.0.255
    HWADDR=00:1B:21:4C:F5:A5
    IPADDR=192.168.0.2
    NETMASK=255.255.255.0
    NETWORK=192.168.0.0
    ONBOOT=yes
    TYPE=Bridge                  追加
$ sudo cp ifcfg-eth1 ifcfg-eth1.orig
$ sudo vi ifcfg-eth1
    DEVICE=eth1
    BOOTPROTO=static
    BROADCAST=192.168.0.255
    HWADDR=00:1B:21:4C:F5:A5
    IPADDR=192.168.0.2
    NETMASK=255.255.255.0
    NETWORK=192.168.0.0
    ONBOOT=yes
    BRIDGE=br0                   追加
$ sudo /etc/init.d/network restart

qemuコマンドでbridgeが使えるように、/etc以下にqemu-(ifup|ifdown)を用意。

$ sudo vi /etc/qemu-ifup
    #!/bin/sh
    switch=$(/sbin/ip route ls | awk '/^default / { for(i=0;i<NF;i++) { if ($(i) == "dev") print $(i+1) }}')
    /sbin/ifconfig $1 0.0.0.0 up
    /usr/sbin/brctl addif ${switch} $1
    exit 0
$ sudo chmod +x /etc/qemu-ifup
$ sudo vi /etc/qemu-ifdown
    #!/bin/sh
    switch=$(/sbin/ip route ls | awk '/^default / { for(i=0;i<NF;i++) { if ($(i) == "dev") print $(i+1) }}')
    /usr/sbin/brctl delif ${switch} $1
    /sbin/ifconfig $1 down
    exit 0
$ sudo chmod +x /etc/qemu-ifdown
qemuによるbridge動作確認

以下のコマンドを実行してVMが起動し、bridgeが有効になっていることを確認。bridgeネットワーク上でDHCPが有効になっている、または、VMに静的にIPを割り当てているならば、ホストからsshVMに接続を試みる、VM内からリモートマシンにpingを打つなどして確認できる。
bridgeはroot権限がないと使用できない。

$ sudo /usr/libexec/qemu-kvm -boot c \
                             -hda /home/shin/vm1/disk.img \
                             -m 384 \
                             -daemonize \
                             -vnc :0 \
                             -k ja \
                             -net nic,macaddr=52:54:00:00:00:03,model=e1000 \
                             -net tap          これを追加
libvirtによるbridge動作確認

次のようなVM定義ファイルを作成する。virshコマンドでVMが起動し、bridgeが有効になっていることを確認。確認方法はkvmの場合と一緒。
VM定義ファイル

<domain type='kvm'>
  <name>inca-server01</name>
  <memory>1048576</memory>
  <currentMemory>1048576</currentMemory>
  <vcpu>1</vcpu>
  <os>
    <type arch='i686' machine='pc'>hvm</type>
    <boot dev='hd'/>
  </os>
  <features>
    <acpi/>
    <apic/>
    <pae/>
  </features>
  <on_poweroff>destroy</on_poweroff>
  <on_reboot>restart</on_reboot>
  <on_crash>restart</on_crash>

  <devices>
    <emulator>/usr/libexec/qemu-kvm</emulator>
    <disk type='file' device='disk'>
      <source file='/work/vms/inca/server01/disk.img'/>
      <target dev='hda' bus='ide'/>
    </disk>
    <interface type='bridge'>            変更箇所はここ
      <mac address='52:54:00:00:00:03'/>
      <model type='e1000'/>
      <source bridge='br0'/>
    </interface>
    <input type='mouse' bus='ps2'/>
    <graphics type='vnc' autoport='yes' keymap='ja'/>
  </devices>
</domain>

動作確認コマンド

$ virsh -c qemu:///system define conf.xml
Domain inca-server01 defined from conf.xml

$ virsh -c qemu:///system list --all        定義の確認
 Id Name                 State
----------------------------------
  - inca-server01        shut off

$ virsh -c qemu:///system start inca-server01
Domain inca-server01 started

$ virsh -c qemu:///system list --all
 Id Name                 State
----------------------------------
  1 inca-server01        running

$ virsh -c qemu:///system vncdisplay inca-server01
:0

$ ssh inca-server01                     VMの起動確認
$ virsh -c qemu:///system destroy inca-server01
Domain inca-server01 destroyed

$ virsh -c qemu:///system undefine inca-server01
Domain inca-server01 has been undefined

参考

その他、CentOS kvmでググったページや、Debianでの設定方法も参考にしたんだけど、参考ページを記録し忘れた・・・