2009年6月12日金曜日

Xen Guest OSのOfflink Migration

Live Migrationの課題

ライブマイグレーションは、移動元と移動先のHost OSが、同一のサブネットワークに接続されていることを前提としています。なぜならば、Guest OSが利用するネットワーク環境はHost OSのネットワーク環境に依存しているため、Host OSとInternetとの接続状態が変更されると、それに応じてGuest OSのネットワーク設定を変更しなければなりません。

Network Mobility Basic Support (NEMO BS)

NEMO BSはIPv6モバイルルータを実現するプロトコルで、RFC3963として標準化されています。NEMO BSを実装したモバイルルータは、自身が抱えるネットワークに固定のアドレスを提供しつつ、任意のネットワークに自由に接続できるようになります。

Host OSのモバイルルータ化

Live Migrationの問題である、Host OSのネットワーク環境の変化は、NEMO BSを組み合わせることで解決できます。Guest OSが接続するネットワークを、NEMO BSの機能として提供される固定ネットワークにすることで、NEMO BSの設定情報を共有するHost OS間で、Host OSの物理的な位置に関わらずGuest OSをMigrationできます。

Interop Tokyo 2009での実験

Interop Tokyo 2009では、NEMO BS機能を追加したXenサーバを2台作成し、それぞれのサーバを異なるサブネットワークに配置しました。Guest OSは、いずれかのXenサーバで動作します。

Guest OSのMigrationは、通常のXen Guest OSのMigrationと同様の手順で実施されます。異なっている点は、Migration先のXenサーバが、同一サブネットワークではなく、異なるサブネットワーク上に配置してある点です。通常、このような構成ではGuest OSのMigrationは成功しません。Guest OSが他方のXenサーバに移動した時点で、ネットワークから切り離されてしまうためです。

本実験では、Guest OSをMigrationすると同時に、移動元のXenサーバ上で動作しているモバイルルータ機能を停止し、他方のXenサーバでモバイルルータ機能を開始します。Guest OSが接続しているネットワークには、モバイルルータによって固定のネットワークが提供されています。このネットワークは実際にはInterop Tokyo 2009のShowNetネットワーク内に配置されたホームエージェントによって管理されており、論理的にはShowNetネットワークの一部になります。

Gust OSは二つのモバイルルータ間を移動しますが、モバイルルータが提供するネットワークアドレスは変化しないため、Guest OSはHost OSが接続したネットワークが変わったことを意識する必要が無くなります。

トラフィックのグラフ

実験では、Guest OSから定常的なストリーミングトラフィックを送信しながら、5分間隔でふたつのHost OSの間をMigrationさせています。それぞれのXenサーバのインターフェースのトラフィックを示します。グラフからGuest OSがふたつのXenサーバの間を移動していたことがわかります。

謝辞

本実験の実施に際して、ShowNet NOCメンバーのみなさまに多大なご支援をいただきました。ここに感謝いたします。

2009年6月11日木曜日

Xenカーネルの再構築

XenのLive Migrationで遊ぶために、LinuxのインストールやNFS rootの設定やらに四苦八苦しつつも、なんとか基本的なMigrationまではできる環境を構築できた。本当にやりたかったことは、このLive Migrationを、異なるふたつのネットワークセグメントに配置されているXenサーバ間で実行することだったりする。

アイデアとしてはシンプルで、XenサーバをNetwork Mobility (NEMO) 機能を持ったモバイルルータとし、Guest OSが接続するネットワークをMobile Networkとして運用するというものだ。ふたつのXenサーバを用意して、それぞれを同じモバイルルータとして設定しておく。Guest OSのMigrationと同時に、元のHost OSのモバイルルータ機能を停止し、Migration先のHost OSのモバイルルータ機能を有効化すれば、Guest OSからみるとネットワーク的には移動していないように見える。

ところが、Xenを導入したDebianでNetwork Mobilityのプログラム (NEPL) を起動させようとしてみたところ、動作しないことが判明した。どうやら、NEPLが必要としているカーネル機能が組み込まれていないことが原因らしい。最近のLinuxは多くの機能が動的にロードされるモジュールとなっているが、中には動的モジュールとして分離できない拡張機能も少ないながら存在する。今回問題になったのはxfrmのポリシー拡張機能 (CONFIG_XFRM_SUB_POLICY) だった。この機能がカーネルに組み込まれていないと、そもそもMobile IPv6やNEMOの機能を利用することができない。しかし、カーネルのモジュールディレクトリには、Mobile IPv6やNEMOの基本部分を実装したmip6.koが収められており、一見Mobile IPv6/NEMOを利用できるかのように見えてしまう。これはまぎらわしい。

ともかく、カーネルの再構築が必要なので、その作業を進めることにする。XenのHost OSサポートはまだLinuxカーネルのメインラインに取り込まれていないので、再構築の際にはXenパッチを適用する必要がある。今回、Xen Host OSカーネルはAPTを使ってバイナリパッケージをインストールしているが、APTにはパッケージをソースから再構築する手段も提供されている。

今回使ったバイナリパッケージはlinux-image-2.6.26-2-xen-686なので、まずはこのパッケージをソースから再構築するために必要なツール群をインストールする。これもAPTを利用すれば簡単だ。APT便利だなぁ。

# apt-get build-dep linux-image-2.6.26-2-xen-686

これで必要なツール群がインストールされる。続いて、カーネルパッケージのソースを入手する。

# apt-get source linux-image-2.6.26-2-xen-686


カレントディレクトリにソースと必要なパッチが展開されるので、それを使ってパッケージの再構築をおこなう。単に再構築するだけならば、ここからさらに次のコマンドを実行するだけでよい。

# dpkg-buildpackage

これで、バイナリパッケージとして配布されている物と同じパッケージを再構築できる。もちろん、今回の目的はカーネルの組み込み機能を変更することなので、そのまま構築するだけでは意味がない。パッケージ構築時に参照されるカーネルスイッチは、ソースが展開されたディレクトリにあるlinux-2.6-2.6.26/debian/config/configファイルに列挙してある。なるほど確かに、先のオプションスイッチ (CONFIG_XFRM_SUB_POLICY) は定義されていない。このスイッチを有効化して、パッケージを再構築するが、単にdpkg-buidpackageコマンドで再構築すると、カーネルABIの一貫性チェックで失敗するので、linux-2.6-2.6.26/debian/abi/2.6.26-2/ディレクトリの名前を変更 (あるいは削除) しておく。このディレクトリには、コンパイルされたカーネルのシンボル情報とアドレス情報が記述されており、実際に構築されたカーネルがこの情報と一致しない限りパッケージは作成されない。

これでようやくXen + NEMOカーネルが完成した。ソースを展開したディレクトリに、.debパッケージができているはずなので、これをdpkgコマンドでインストールし、ようやく準備完了。

# dpkg -i linux-headers-2.6.26-2-common-xen_2.6.26-15lenny2_i386.deb

# dpkg -i linux-headers-2.6.26-2-xen-686_2.6.26-15lenny2_i386.deb

# dpkg -i linux-image-2.6.26-2-xen_2.6.26-15lenny2_i386.deb


# dpkg -i linux-modules-2.6.26-2-xen_2.6.26-15lenny2_i386.deb

2009年6月2日火曜日

NFS rootによるXen Guest OS

Xenには、あるHost OSから、同一セグメント上にある別のHost OSにGuest OSを移動させる機能があり、migrationと呼ばれている。今回はmigration可能なGuest OSを作成するときの手順をメモしておく。

Migrationといっても、Guest OSのすべてのコンポーネントがHost OS間を移動するわけではない。移動するのはGuest OSのメモリイメージである。すなわち、ストレージに関してはmigration前後で同じ物を参照しておかなければならない。結果として、ストレージをすべてネットワークの向こう側に配置することになるのだけれど、一点注意しておかなければならないことがある。それは、Guest OSの起動に使われるrootパーティションもネットワークストレージに置いておかなければならないと言う点だ。

今回はネットワークストレージとしてNFSを使うこととし、以下の手順でNFS rootパーティションから起動するGuest OSを準備した。
  1. 通常のXen Guest OSイメージを作成する。
  2. 作成したイメージをNFS公開ディレクトリに展開する。
  3. NFS機能を組み込んだkernelを作成する。
  4. 作成したkernelでGuest OSを起動する。
Debianにはxen-toolsAPTパッケージが用意されており、簡単にDebianのXen Guest OSを作成することができる。
# xen-create-image --hostname=guest --ip=10.0.0.64 --netmask=255.255.255.0 --gateway=10.0.0.1 --dir
--hostname--ip--netmask--gatewayはそれぞれ、作成されるGuest OSのノード情報となる。--dirスイッチを指定するとGuest OSのディスクイメージが/home/xen/domains/ディレクトリの下に作成される。evmslvmといったボリューム管理システムを使っている場合は、オプションスイッチで新しいボリュームにGuest OSイメージを作成することもできる。他にも多くのスイッチがあるので、細かく制御したい方はマニュアルページを参照のほど。

作成されるディスクイメージは単一ファイル (上記の例の場合は /home/xen/domains/guest/disk.img) になっているので、ループバックマウントしてNFS公開ディレクトリにコピーする。

続いてGuest OS用のkernelを再構築する。通常、Host OSにXenをインストールした時点で、Guest OSのkernelとして利用できるkernelイメージが/boot/ディレクトリにインストールされている。しかし、このイメージはrootパーティションをNFS上に置く場合は利用できない。Debian kernel では (おそらく他の多くのDistributionでも)、NFS機能はダイナミックモジュールとして提供されるのが普通である。そのため、rootパーティションがNFS上にあると、NFS機能を有効化するためのダイナミックモジュールを読み込むことができなくなる。よって、NFS機能をモジュールとしてではなく、kernel組み込み機能として作成しておかなければならない。また、NFSをrootパーティションとしてマウントするための特別なkernelスイッチも有効にする必要がある。

Linux kernel再構築の詳細は省略するが、以下のスイッチ、および関連スイッチを調整することでNFS機能をkernelに組み込むことができる。
CONFIG_NFS_FS=y
CONFIG_ROOT_NFS=y
スイッチには依存関係があるので、make menuconfigを使って依存関係を壊さないように調整するようにしよう。少なくとも、僕は依存関係を手動で調整するのはあきらめた。今回はさらに、NFS関連設定に加え、XenのGuest OSとして動作するためのスイッチも有効化することを忘れないように。

作成したカーネルを適当な位置にコピーし、Xen Guest OSの設定ファイルを作成する。
kernel = '/boot/bzImage'
memory = '128'
root = '/dev/nfs'
nfs_server = '10.0.0.2'
nfs_root = '/export/xen/domains/guest'
extra = 'ip=10.0.0.64:10.0.0.2:10.0.0.1:255.255.255.0::eth0:'
name = 'guest'
vif = [ '10.0.0.64',mac=00:16:3E:E2:0A:2F' ]
on_poweroff = 'destroy'
on_reboot = 'restart'
on_crash = 'restart'
通常のGuest OSの設定ファイルと異なるのは、rootディレクティブに/dev/nfsが指定されること、nfs_serverディレクティブでNFSサーバのIPアドレスを指定する必要があること、nfs_rootディレクティブでNFSサーバのマウントポイントを指定する必要があること、extraディレクティブにNFSのrootパーティションから起動するためのkernelスイッチを指定する必要があるあたりだろうか。kernelスイッチに関しては、Linuxのソースを展開したディレクトリにある、Documentation/filesystems/nfsroot.txtに詳しい説明が書かれている。それによれば、ip=スイッチの意味は
ip=[client-ip]:[server-ip]:[gw-ip]:[netmask]:[hostname]:[device]:[autoconf]
とのことだ。hostnameは今回利用しないので空欄にしてある。autoconfについては、dhcpbootprarpなどを指定することでIPアドレスを自動設定できるようだが、今回は静的にアドレスをつけているので、ここも空欄にしてある。

後は、NFSサーバで適切に公開設定を行い、通常の手順でXen Guest OSを作成する。設定に問題がなければ、Guest OSの設定ファイルで指定したkernelを読み込み、起動した後、NFSサーバ経由でrootパーティションがマウントされ、通常のブートプロセスが開始する。

さて、現在のところ、LinuxのNFS実装は、まだIPv4しかサポートしていないようだ。少なくとも、Debianの通常のNFSサポートではIPv6アドレスを指定してNFSマウントすることができない。もちろん、NFS rootパーティションをIPv6経由でマウントすることもできない。少しGoogleしてみたところ、NFSのIPv6サポートを進めている開発者は存在するようで、2008年のLinux Storage & Filesystems WorkshopにてIPv6 support for Linux NFSという発表が行われていたようだ。2008年後半を目標に開発を進めると書かれていたので、近いうちにIPv6サポートが利用できるようになるのかもしれない。