Linux Native KVM Toolsを使ってみよう

Pocket

少しずつ認知され始めたLinux Native KVM Tools(NLKT)を使ってゲス トを起動する方法について解説します.この記事は,カーネル/VM Advent Calendar : ATNDの11日目です.

Linux Native KVM Toolsとは?

今広く使われているKVMは,QEMUを用いたものですが,Linux Native KVM Tools(以下LNKT)は,QEMUを使わず1から書いたVMMです.またカーネルの メインラインにはマージされていませんが,近い内にマージされるよう です.Github上(penberg/linux-kvm – GitHub)で開発が行われています.

使ってみる

さて,何はともあれまずは動かしてみましょう. 私は,X60s,i386,GentooLinuxで検証しています.えらく古い環境です が,VTは動くので検証する分には問題ありません.

まずはソースコードを入手します.Githubからリポジトリをcloneするの が一番簡単です.

$ cd ~/
$ git clone https://github.com/penberg/linux-kvm.git

linux-kvm/tools/kvmに移動してmakeしましょう.

$ cd linux-kvm/tools/kvm
$ make

とりあえず動かすために,linux-0.2のディスクイメージを使います.ダ ウンロードして展開しておきます.

$ wget http://wiki.qemu.org/download/linux-0.2.img.bz2 && bunzip2 linux-0.2.img.bz2

kvm-toolsではディスクイメージとは別にカーネルイメージが必要です. ホストマシンで使っているカーネルイメージを使ってもいいでし, linux-kvm用に作ってもいいですね.その際, カーネルは以下の設定が有効になっている必要があります.

  • デフォルトコンソール出力
    • CONFIG_SERIAL_8250=y
      • CONFIG_SERIAL_8250_CONSOLE=y
  • 32ビットのイメージを62ビットのホストで動かす
    • CONFIG_IA32_EMULATION=y
  • ディスクイメージで使っているファイルシステム(例: CONFIG_EXT2_FS, CONFIG_EXT4_FS) linux-0.2.imgを使う場合はCONFIG_EXT2_FSを有効にする.
  • virtioデバイス
    • CONFIG_VIRTIO=y
    • CONFIG_VIRTIO_RING=y
    • CONFIG_VIRTIO_PCI=y
  • virtio-blkデバイス(–disk, -dで使う) 疑似仮想化ブロックデバイス向けの仮想ブロックデバイスドライバら しいです.
    • CONFIG_VIRTIO_BLK=y
  • virtio-netデバイス([–network, -n] virtio): 仮想ネットワークドライバ.
    • CONFIG_VIRTIO_NET=y
  • virtio-9pデバイス(–virtio-9p):
    • CONFIG_NET_9P=y
    • CONFIG_NET_9P_VIRTIO=y
    • CONFIG_9P_FS=y
  • virtio-balloonデバイス(–balloon): 動的メモリ割当のためのメモリドライバで,これがあるとゲストに割 り当てるメモリを動的に変更できる.
    • CONFIG_VIRTIO_BALLOON=y
  • virtio-consoleデバイス(–console virtio):
    • CONFIG_VIRTIO_CONSOLE=y
  • virtio-rngデバイス(–rng):
    • CONFIG_HW_RANDOM_VIRTIO=y

カーネルを用意できたら,後は起動するだけです.今回は,linux-kvm内 でビルドしたカーネルを使っています.

$ ./kvm run -k ~/linux-kvm/arch/i386/boot/bzImage -d linux-0.2.img
  # kvm run -k /home/takaishi/linux-kvm/arch/i386/boot/bzImage -m 320 -c 2 --name guest-632

Decompressing Linux... Parsing ELF... done.
Booting the kernel.
[    0.000000] Initializing cgroup subsys cpuset
[    0.000000] Initializing cgroup subsys cpu
[    0.000000] Linux version 3.0.0-rc5+ (takaishi@localhost) (gcc version 4.5.3 (Gentoo 4.5.3-r1 p1.0, pie-0.4.5) ) #3 SMP Wed Dec 7 14:39:03 JST 2011
[    0.000000] BIOS-provided physical RAM map:
[    0.000000]  BIOS-e820: 0000000000000000 - 000000000009fc00 (usable)
[    0.000000]  BIOS-e820: 000000000009fc00 - 00000000000a0000 (reserved)
[    0.000000]  BIOS-e820: 00000000000f0000 - 00000000000fffff (reserved)
[    0.000000]  BIOS-e820: 0000000000100000 - 0000000014000000 (usable)
[    0.000000] bootconsole [earlyser0] enabled
...
[    1.543773] VFS: Mounted root (ext2 filesystem) on device 253:0.
[    1.545773] Freeing unused kernel memory: 432k freed
[    1.548772] Write protecting the kernel text: 6504k
[    1.550772] Write protecting the kernel read-only data: 2184k
[    1.964708] mount used greatest stack depth: 6132 bytes left

Linux version 3.0.0-rc5+ (takaishi@localhost) (gcc version 4.5.3 (Gentoo 4.5.3-r1 p1.0, pie-0.4.5) ) #3 SMP Wed Dec 7 14:39:03 JST 2011

QEMU Linux test distribution (based on Redhat 9)

Type 'exit' to halt the system

sh-2.05b# ls
20thfull.mp2  nbench
sh-2.05b# df
Filesystem           1K-blocks      Used Available Use% Mounted on
rootfs                   19827     17136      1667  92% /
/dev/root                19827     17136      1667  92% /
sh-2.05b# ps
[   20.218915] ps[761]: segfault at b7845000 ip b783e737 sp bf9511a0 error 4 in libproc.so.2.0.11[b7837000+a000]
Segmentation fault

VMを終了するには,kvm stopを使います.その際に,VMの名前を指定す るのですが,これはkvm listで確認することができます.

$ ./kvm list
パスワード:
   PID NAME                 STATE
------------------------------------
632    guest-632            running
$ ./kvm stop -n guest-632

kvm runには他にもオプションがあり,kvm help runで見ることができま す.残念ながら,筆者の環境と能力では全てのオプションの動作確認を することができませんでした.また,動作したオプションについては別 の記事で紹介する予定です.

  • –name: ゲストの名前
  • -c,–cpus: VMに割り当てるCPU数を指定
  • -m,–mem: VMのメモリサイズ.MBで指定する.
  • –shmem: PCIデバイス経由でホストとゲストが共有するメモリを指定
  • -d,–disk: ディスクイメージまたはrootfsディレクトリを指定
  • –balloon: virtio balloonを有効にする
  • –vnc: VMCフレームバッファを有効にする
  • –sdl: SDLフレームバッファを有効にする
  • –rng: virtio Random Number Generatorを有効にする
  • –9p virtio 9pを有効に.ホストとゲストのファイル共有に用いる.
  • –console 使用するコンソールを指定
  • –dev=: KVMのデバイスファイル
  • –tty: ゲストのTTYをホストのptyにリマップする
  • -k,–kernel=: VM用カーネル
  • -r,–initrd=: initrdのイメージを指定する
  • -p,–params: カーネルに与える追加の引数
  • -n,–network: ゲストNICを作成
  • –no-dhcp: rootfs中ではカーネルのDHCPを無効に
  • –vidmode: Video mode
  • –debug: デバッグメッセージを有効に
  • –debug-single-step: シングルステッピングを有効に
  • -debug-ioport: ioportingデバッグを有効に
  • -debug-iodelay: IOのディレイをミリ秒で指定

Debianのイメージを起動してみる

さて,次はDebianを起動してみましょう.まずは,イメージファイルを ダウンロードします.

$ wget http://people.debian.org/~aurel32/qemu/i386/debian_squeeze_i386_standard.qcow2

さて,このイメージファイルをディスクに指定して起動するのですが, カーネルに引数を与えることに注意します.このイメージファイルは, 内部がパーティションで区切られているため,どのパーティションが rootなのかを指定する必要があるのです.カーネルの引数は-pオプショ ンで指定できます.

$ ./kvm run --name test -m 64 -c 1 -k ~/linux-kvm/arch/i386/boot/bzImage -d debian_squeeze_i386_standard.qcow2 -p "root=/dev/vda1"
  Warning: Forcing read-only support for QCOW
  # kvm run -k /home/takaishi/linux-kvm/arch/i386/boot/bzImage -m 64 -c 1 --name test

Decompressing Linux... Parsing ELF... done.
Booting the kernel.
[    0.000000] Initializing cgroup subsys cpuset
[    0.000000] Initializing cgroup subsys cpu
[    0.000000] Linux version 3.0.0-rc5+ (takaishi@localhost) (gcc version 4.5.3 (Gentoo 4.5.3-r1 p1.0, pie-0.4.5) ) #3 SMP Wed Dec 7 14:39:03 JST 2011
[    0.000000] BIOS-provided physical RAM map:
[    0.000000]  BIOS-e820: 0000000000000000 - 000000000009fc00 (usable)
[    0.000000]  BIOS-e820: 000000000009fc00 - 00000000000a0000 (reserved)
[    0.000000]  BIOS-e820: 00000000000f0000 - 00000000000fffff (reserved)
[    0.000000]  BIOS-e820: 0000000000100000 - 0000000004000000 (usable)
[    0.000000] bootconsole [earlyser0] enabled
[    0.000000] Notice: NX (Execute Disable) protection missing in CPU!
[    0.000000] DMI not present or invalid.
[    1.373799] EXT3-fs: barriers not enabled
[    1.375799] kjournald starting.  Commit interval 5 seconds
[    1.377798] EXT3-fs (vda1): mounted filesystem with writeback data mode
[    1.379798] VFS: Mounted root (ext3 filesystem) readonly on device 253:1.
[    1.381798] Freeing unused kernel memory: 432k freed
[    1.383797] Write protecting the kernel text: 6504k
[    1.385797] Write protecting the kernel read-only data: 2184k
SELinux:  Could not open policy file <= /etc/selinux/targeted/policy/policy.26:  No such file or directory
INIT: version 2.88 booting
[    1.606763] stty used greatest stack depth: 5928 bytes left
Using makefile-style concurrent boot in runlevel S.
.udev/ already exists on the static /dev! ... (warning).
Starting the hotplug events dispatcher: udevd.
Synthesizing the initial hotplug events...done.
Waiting for /dev to be fully populated...done.
Setting preliminary keymap...done.
Activating swap...[    2.913563] Adding 731132k swap on /dev/vda5.  Priority:-1 extents:1 across:731132k
done.
Checking root file system...fsck from util-linux-ng 2.17.2
/dev/vda1: clean, 25194/1003680 [    3.030545] EXT3-fs (vda1): using internal journal
files, 261172/4010752 blocks
done.
Cleaning up ifupdown....
Setting up networking....
Loading kernel modules...done.
Activating lvm and md swap...done.
Checking file systems...fsck from util-linux-ng 2.17.2
done.
Mounting local filesystems...done.
Activating swapfile swap...done.
Cleaning up temporary files....
Configuring network interfaces...done.
Starting portmap daemon....
Starting NFS common utilities: statd.
Cleaning up temporary files....
Setting console screen modes.
Skipping font and keymap setup (handled by console-setup).
Setting up console font and keymap...[    4.786277] dhclient-script used greatest stack depth: 5792 bytes left
done.
Setting kernel variables ...done.
[   34.685701] rc used greatest stack depth: 5720 bytes left
INIT: Entering runlevel: 2
Using makefile-style concurrent boot in runlevel 2.
Starting portmap daemon...Already running..
Starting NFS common utilities: statd.
Starting enhanced syslogd: rsyslogd.
Starting ACPI services...RTNETLINK1 answers: No such file or directory
acpid: error talking to the kernel via netlink
.
Starting deferred execution scheduler: atd.
Starting periodic command scheduler: cron.
Starting MTA: exim4.

Debian GNU/Linux 6.0 debian-i386 ttyS0

debian-i386 login: root
Password:
Linux debian-i386 3.0.0-rc5+ #3 SMP Wed Dec 7 14:39:03 JST 2011 i686

The programs included with the Debian GNU/Linux system are free software;
the exact distribution terms for each program are described in the
individual files in /usr/share/doc/*/copyright.

Debian GNU/Linux comes with ABSOLUTELY NO WARRANTY, to the extent
permitted by applicable law.
root@debian-i386:~# ls /
bin   etc         lib         mnt   root     srv  usr
boot  home        lost+found  opt   sbin     sys  var
dev   initrd.img  media       proc  selinux  tmp  vmlinuz
root@debian-i386:~# df
Filesystem           1K-blocks      Used Available Use% Mounted on
/dev/vda1             15791024    792904  14195972   6% /
tmpfs                    27364         0     27364   0% /lib/init/rw
udev                     10240       148     10092   2% /dev
tmpfs                    27364         0     27364   0% /dev/shm
root@debian-i386:~# ps
  PID TTY          TIME CMD
 1593 ttyS0    00:00:00 login
 1594 ttyS0    00:00:00 bash
 1610 ttyS0    00:00:00 ps
root@debian-i386:~#

起動できました.まだうまくいっていませんが,KVMで作成したディスク 等も起動できそうです.

まだまだ実用的なレベルとは言えませんが,きちんと動いていておもし ろいですね.また,カーネルのデバッグ用途に使えるようなので,こち らについても試したい所です.

Leave a Reply

Your email address will not be published. Required fields are marked *