トップ > コンピューティング環境 > NetBSD/xen 実験メモ

[前ページ] [次ページ]


NetBSD/xen 実験メモ

Author: Takeshi Fujiyoshi
Last update: 2010/06/26

この文書は、筆者が2009年7月頃に NetBSD/xen を試したときの覚え書き。

目次

実験環境

ドメイン0を動かす

大雑把な手順はこう:

  1. Xen カーネルと Xen ツールをインストール
  2. Xen3 の ドメイン0 対応の NetBSD カーネルを用意
  3. NetBSD/xen ドメイン0 を起動
  4. Xen デーモンを起動

1. XenカーネルとXenツールをインストール

pkgsrc/sysutils にある xenkernel3 と xentools3 をインストールする。:

# cd /usr/pkgsrc/sysutils
# (cd xenkernel3 && make install)
# (cd xentools3 && make install)

Xen カーネルは /usr/pkg/xen3-kernel/ 以下に置かれる。 ここにある xen.gz をルートディレクトリにコピーする。:

# cp /usr/pkg/xen3-kernel/xen.gz /

2. Xen3 の ドメイン0 対応の NetBSD カーネルを用意

ソースからビルドするか NetBSD の配布物に含まれているバイナリを持ってきて ルートディレクトリに適当な名前で置く。

ここでは /netbsd-XEN3_DOM0 とする。

なお、通常のカーネルは圧縮されていてもブートできるが、 少なくとも現在のNetBSDの現状のブートローダからブートする場合、 圧縮形式は非対応につき伸長しておく必要あり。

ソースからビルドする例:

# cd /anywhere/to/build
# config -b . -s /usr/src/sys /usr/src/sys/arch/i386/XEN3_DOM0
# make depend
# make
# cp netbsd /netbsd-XEN3_DOM0

3. NetBSD/xen ドメイン0 を起動

マシンを再起動し、ブートローダのプロンプトに落ちた後、 以下のようにして起動する。:

> load /netbsd-XEN3_DOM0 console=pc  # (デフォルトはシリアルっぽい)
> boot /xen.gz dom0_mem=512M

あるいは、/boot.cfg に以下のようなメニューを追加すればメニュー番号に 対応する数字キーを押すだけで起動できるようになる。:

menu=Boot Xen:load /netbsd-XEN3_DOM0 console=pc;multiboot /xen.gz

ここで NetBSD カーネルの引数 console=pc はコンソールデバイスとして 通常通りVGAを使うことを意味する。 デフォルトはシリアル(com0)になるようである。

Xen カーネルの引数 dom0_mem=512M はドメイン0に割り当てるメモリ量を指定する。 デフォルトでは全メモリがドメイン0に割り当てられるようであるが、 ドメインU用のメモリを必ず残しておかなくてはならないので必須。

4. Xen デーモンを起動

/usr/pkg/share/example/rc.d/ 以下にある xend、xenbackendd、xendomains を /etc/rc.d にコピーし、/etc/rc.conf に xend=YESxenbackendd=YES を追加し、それぞれ起動すること。:

# cp /usr/pkg/share/example/rc.d/xen* /etc/rc.d
# vi /etc/rc.conf     # xend=YES、xenbackendd=YES を追加
# /etc/rc.d/xend start
# /etc/rc.d/xenbackendd start

メモ

  • xenkernel33 ではバージョン違うと言われてうまく行かない。
  • netbsd-XEN3_DOM0 はローダブルモジュールを使っていないようである。
  • boot.cfg(5) のマニュアルを見ると '#' で開始する行はコメント行とのことだが 実装されていないように思う(→ src/sys/arch/i386/stand/lib/bootmenu.c)。
  • boot.cfg のサイズがでかくなると Xen のメニューを選んでも exit が 無限表示されて固まる。意味不明。

ドメインU で NetBSD-5.0 を動かす

大雑把な手順はこう。

  1. インストール用 CD-ROM イメージを用意
  2. ドメインU 用のカーネルを用意
  3. ハードディスクイメージを作成
  4. ドメインコンフィグファイルを作成
  5. ハードディスクイメージに OS をインストール
  6. インストールしたOSを起動

1. インストール用 CD-ROM イメージを用意

NetBSD のミラーサイトから NetBSD-5.0 の CD-ROM イメージをダウンロードする。:

# cd /home/xen
# ftp ftp://ftp.netbsd.org/pub/NetBSD/NetBSD-5.0/iso/i386/i386cd-5.0.iso

2. ドメインU 用のカーネルを用意

CD-ROMイメージから、ドメインU用のカーネルを取り出す。以下の2種類が必要。

  • netbsd-INSTALL_XEN3_DOMU.gz (インストール用)
  • netbsd-XEN3_DOMU.gz (メイン用)

作業例:

# cd /home/xen
# vnconfig vnd0 i386iso-5.0.iso
# mount /dev/vnd0a /mnt
# cp /mnt/i386/binary/kernel/netbsd-{INSTALL_,}XEN3_DOMU.gz .
# umount /mnt
# vnconfig -u vnd0

3. ハードディスクイメージを作成

1GBのハードディスクイメージ dom1-hdd.img を作成する例:

# cd /home/xen
# dd if=/dev/zero of=dom1-hdd.img bs=1m count=1024

4. ドメインコンフィグファイルを用意

ここでは、インストール用のドメインとメインのドメインの コンフィグファイルを別々に用意することにする。 本当は変数と条件分岐を使って1つにすれば良いと思うけど、 Python 知らないので書けないだけ。

ドメインコンフィグファイルは /usr/pkg/etc/xen 以下に置くことにする。 ここに置くと xm create で指定するファイル名のディレクトリ部分を省略できる。

インストール用 dom1-install:

kernel = "/home/xen/netbsd-INSTALL_XEN3_DOMU.gz"
memory = 128
name = "dom1"
vif = [ 'ip=192.168.201.254 script=vif-ip' ]
disk = [ 'file:/home/xen/dom1-hdd.img,0x3,w',
         'file:/home/xen/i386cd-5.0.iso,0x4,r' ]

メイン用 /usr/pkg/etc/xen/dom1:

kernel = "/home/xen/netbsd-XEN3_DOMU.gz"
memory = 128
name = "dom1"
vif = [ 'ip=192.168.201.254 script=vif-ip' ]
disk = [ 'file:/home/xen/dom1-hdd.img,0x3,w',
         'file:/home/xen/i386cd-5.0.iso,0x4,r' ]

4. ハードディスクイメージにOSをインストール

以下のコマンドを実行するとNetBSDのインストーラが起動するので、 好きなようにインストールすること。:

# xm create dom1-install -c

なお、上のコンフィグファイルの場合、

  • ハードディスクイメージには /dev/xbd0
  • CD-ROMイメージには /dev/xbd1

という名前のデバイスファイルが割り当てられる。

インストールが完了したら、他の端末から:

# xm shutdown dom1-install

と入力して ドメインU を終了させる。 暴走して終了しない場合は:

# xm destroy dom1-install

で強制終了可能。

5. インストールした OS を起動

以下のコマンドによりインストールした NetBSD を起動する。:

# xm create dom1 -c

ところで、xm create コマンドの引数 -c はコンソールに接続すること を意味する。 -c を付けないとOSを起動したらすぐにプロンプトにもどる。 -c を使わずに以下のように入力しても同じ。:

# xm create dom1
# xm console dom1

NetBSD wiki によると、起動時にエラーを表示させないために ドメインU に以下の設定をすると良いらしい。

  • /etc/ttys の console 以外の行を全てコメントアウト。
  • /etc/rc.conf で wscons=NO とする。

また、/etc/rc.conf に powerd=YES を追加して powerd を動かしておくと、 ドメイン0 から xm shutdown したときにドメインU側で自動的に シャットダウン処理を実行してくれるから安全である。

ドメインU 内でOSを普通に再起動するとコンソール接続が切れてプロンプトに 戻るようであるが、 xm list で確認するとドメインはまだ終了していない。 そのときは、 xm console dom1= とすれば再び接続可能。

ネットワークの前知識

接続形態について

各ドメインUのネットワークインタフェースは ドメイン0の仮想ネットワークインタフェースに一対一(Point-to-point)で 接続される。

ドメインU側のインタフェース名は xennet0、xennet1、xennet2、...、 ドメイン0側の仮想インタフェース名は xvif1.0、xvif1.1、xvif1.2、...となる。 ここで、 xvif の後の数字は接続先のドメインIDとそのドメインの インタフェース番号を意味する。 例えばドメインIDが4のドメインUの xennet2 は ドメイン0の xvif4.2 と接続されている。:

DomainU domid=1       Domain0
+------------+        +-------------
|   [xennet0]----------[xvif1.0]
|   [xennet1]----------[xvif1.2]
|   ...      |        |
+------------+        |
                      |
DomainU domid=2       |
+------------+        |
|   [xennet0]----------[xvif2.0]
|   [xennet1]----------[xvif2.2]
|   ...      |        |
+------------+        |
   ...                |
                      +-------------

Xen 仮想マシンのネットワーク接続には以下の2種類の形態があるようである。

  • IP接続
  • ブリッジ接続

IP接続

ドメインコンフィグファイルに以下のように vif を設定した場合、:

vif = [ 'ip=10.0.0.254, netmask=255.0.0.0.0, script=vif-ip' ]

/usr/pkg/etc/xen/script 以下にあるスクリプト vif-ip によって 仮想マシンのネットワークは下図のように接続される。:

DomainU "dom1"        Domain0
+------------+        +-------------+
|            |        |10.0.0.254   |
|   [xennet0]----------[xvif1.0]    |
|   ...      |        |             |
+------------+        +-------------+

ドメイン0側の仮想インタフェース xvif?.0 は vif-ip によって 自動的にIPアドレスが設定される。 ドメインU側のインタフェース xennet0 のIPアドレスはドメインUの中で 設定すること。 両者はそれぞれのIPアドレスを使ってIPで通信できるようになる。

ドメイン0が xvif?.0 と他のインタフェースとの間でIPパケットの転送を 行なうならば、ドメインUにとってドメイン0はIPルータである。

ブリッジ接続

ドメインコンフィグファイルに以下のように`vif`を設定した場合、:

vif = [ 'bridge=bridge0, script=vif-bridge' ]

/usr/pkg/etc/xen/script 以下にあるスクリプト vif-bridge によって 仮想マシンのネットワークは下図のように接続される。:

DomainU "dom1"        Domain0
+------------+        +---------------------------+
|            |        |                           |
|   [xennet0]----------[xvif1.0]--(bridge0)-- ... |
|   ...      |        |                           |
+------------+        +---------------------------+

ここで、bridge0 は ドメイン0 の中に作られたMACブリッジである。 bridge0 に複数のネットワークインタフェースが接続されていれば ドメイン0 は bridge0 接続されたインタフェース間でイーサネットフレーム の転送を行なう。 ドメインU から見て ドメイン0 は ブリッジすなわちハブであるため、 xvif?.0 はIPアドレスを持たない。 xennet0 のIPアドレスは ドメインU の中で設定すること。

なお、vif-bridge はブリッジ自体の生成は行なわないので ドメインU を起動する前にドメイン0上にブリッジ bridge0 が存在していなければならない。 NetBSDでは ifconfig bridge0 create up と実行するか、 /etc/ifconfig.bridge0 に単に create と書いて /etc/rc.d/network restart を実行する。

ところで、もし実ネットワークに接続された物理インタフェースがブリッジに 接続されていれば、この ドメインU の仮想ホストが実ネットワークに接続された ことに等しい、はずである。 しかし、筆者の環境では今のところ上手く言ってない。 OS の不具合か設定が間違っているのか筆者の勘違いなのかは不明。

疑問点

IP接続にしてもブリッジ接続にしても Xen 自体が行なうことは 「ドメインU のインタフェースと ドメイン0 の物理インタフェースを生成して 両者を仮想的なリンクで接続すること」だけのはず。 それだけを行ないたい、つまり ドメインU 起動時にはまだIPアドレスの設定も ブリッジへの接続も行なわずに仮想インタフェースの生成とリンクの確立だけ 行ないたい場合、コンフィグファイルにはどのように記述すれば良いのだろうか? スクリプトは必ず必要なのだろうか?

試しに vif = [ '' ] とか、 vif = [ 'script=/dev/null' ] とか 書いてみたが、 xm create するとすぐに固まる。

ネットワーク設定の実際

少々ややこしい仮想ネットワークを組んでみる。

構成

この実験では下図のようなネットワーク構成にする。:

DomainU "dom1"      Domain0
+-----------+      +-------------------------------+
|  10.0.0.1 |      |          +--------+ 10.0.0.254|     家庭内LAN
|  [xennet0]--------[xvif?.0]-|        |-[tap0]    |
+-----------+      |          |        |           |      +------+ to the
                   |          |bridge0 |   x.y.z.u |      |Bridge| Internet
DomainU "dom2"     |          |        |     [ath0]=======|Router|=======
+-----------+      |          |10.0.0.0|           |      |NAT   |
|  10.0.0.2 |      |          | /8     |           |      |DHCP  |
|  [xennet0]--------[xvif?.0]-|        |           |      +------+
+-----------+      |          |        |           |         |
    ...            |  ...     |        |           |         |
    ...            |          +--------+           |    他のマシン ...
                   +-------------------------------+

ドメイン0 は実インタフェース ath0 から家庭内LANへ接続し、 DHCP を用いてIPアドレス、デフォルトルータ、ネームサーバなどの ネットワーク情報をマシン起動時に取得している。

各 ドメインU の仮想インタフェースは ドメイン0 内で作成したブリッジ bridge0 に接続する。 更に ドメイン0内で仮想インタフェース tap0 を作成し bridge0 に接続する。 ドメイン0は、tap0 と ath0 の間でIPパケットを転送する。

仮想ネットワークではIPアドレスはプライベートアドレス空間 10.0.0.0/8 を使用する。dom1 には 10.0.0.1、dom2 には 10.0.0.2 を割り当てる。 また、ドメインU の仮想インタフェース tap0 には 10.0.0.254 を割り当てる。

ドメイン0は、パケット転送を行なう際に NAT によりプライベートアドレスを ath0 に割り当てられたIPアドレスに変換する。 なお、NAT には IPFilter を使用する。

ドメイン0の設定

家庭内LANへの接続:

Xenとは関係ないが一応書いておく。

/etc/rc.conf に dhclient=YES と記述する。 /etc/rc.d/dhclient restart を実行するか再起動して dhclient が 起動すると、IPアドレス、ネームサーバ(in resolv.conf)、 デフォルトルータが自動的に設定される。

メモ: dhclient 使うと後述する tap0 のIPアドレス設定が 0.0.0.0 になって しまう。インタフェースを明示すれば良いのかも知れないけど試してない。 別方法として /etc/ifconfig.ath0 に dhcp とだけ書いておくと このインタフェース用に dhcpcd を起動してくれる。こっちの方が綺麗?

bridge0 の生成:

/etc/ifconfig.bridge0 に以下のように記述する。:

create
!brconfig $int up

/etc/network restart を実行するか再起動により有効になる。

tap0 の生成:

/etc/ifconfig.tap0 に以下のように記述する。:

create
inet 10.0.0.254
!brconfig bridge0 $int

/etc/network restart を実行するか再起動により有効になる。

ところで、3行目はブリッジへの接続である。 ifconfig.bridge0 と ifconfig.tap0 のうち後に読まれる方にそれを 記述する必要があるが、ifconfig.tap0 が必ず後になるという保証はあるのか?

IP転送の設定:
/etc/sysctl.conf に net.inet.ip.forwarding=1 を追加する。 /etc/rc.d/sysctl restart を実行するか再起動により有効になる。
NAT の設定:

/etc/rc.d に ipnat=YES を追加する。 また /etc/ipnat.conf に以下のように記述する。:

map ath0 10.0.0.0/8 -> 0.0.0.0/32 portmap tcp/udp 50000:60000

/etc/rc.d/ipnat restart を実行するか再起動により有効になる。

0.0.0.0/32 は ドメイン0 に設定されている(たぶん ath0 の)IPアドレスに 置き換えられるようであるが、マニュアルに書いてなかったの自信ない。 ipnat -l により NAT の設定内容と現在のセッションエントリを確認できる。

ドメインU のネットワーク設定

仮想インタフェースを生成しブリッジ bridge0 に接続するため、 ドメイン0 上の各ドメインコンフィグファイル(/usr/pkg/etc/xen/dom1 など) の中の vif を以下のように設定する。:

vif = [ 'bridge=bridge0, script=vif-bridge' ]

以下は各ドメインUの中での設定。

NetBSDのドメインU "dom1" では以下のようにする。

IPアドレスの設定:
/etc/ifconfig.xennet0 に inet 10.0.0.1 と記述。
デフォルトルータの設定:
/etc/mygate に 10.0.0.254 と記述。
DNSの設定:
家庭内LANのDNSサーバのアドレスはドメイン0の /etc/resolv.conf に 設定されているのだが、それを利用する綺麗な方法が分からない。 気にならなければ、各ドメインUでネームサーバを立ち上げてしまうのが 簡単である。 /etc/named.conf のデフォルトでは各自勝手にルートサーバに 問い合わせてキャッシュするようである。 /etc/rc.conf に named=YES と記述し、 /etc/rc.d/named start を実行するか再起動すればネームサーバが起動する。

トップ > コンピューティング環境 > NetBSD/xen 実験メモ

[前ページ] [次ページ]