Product SiteDocumentation Site

12.2. 仮想化

仮想化は最近のコンピューティングにおける最も大きな進歩の一つです。仮想化という用語は、実際のハードウェアに対するさまざまな独立性の度合いを持つ仮想コンピュータを模倣するさまざまな抽象化と技術を指します。1 台の物理的なサーバが同時かつ隔離された状態で動く複数のシステムをホストすることが可能です。仮想化アプリケーションは数多く存在し、隔離された仮想システムを使うことができます。たとえば、さまざまに設定されたテスト環境を作ったり、安全性を確保する目的で異なる仮想マシン間でホストされたサービスを分離したり、することが可能です。
複数の仮想化ソリューションが存在し、それぞれが利点と欠点を持っています。本書では Xen、LXC、KVM に注目しますが、他にも以下の様な注目すべき実装が存在します。

12.2.1. Xen

Xen は「準仮想化」ソリューションです。Xen には薄い抽象化層が含まれ、この抽象化層は「ハイパーバイザ」と呼ばれ、ハードウェアとその上にあるシステムの間に位置します。さらにハイパーバイザは審判員として振る舞い、仮想マシンからハードウェアへのアクセスを制御します。しかしながら、ハイパーバイザは命令のほんの一部だけを取り扱い、残りはシステムの代わりにハードウェアによって直接的に実行されます。こうすることによる主な有効性は性能が低下せず、システムがネイティブ速度に迫る性能を発揮するという点です。一方で欠点は Xen ハイパーバイザ上で使いたいオペレーティングシステムのカーネルは Xen 上で実行するために修正される必要があるという点です。
用語について少し時間を割きましょう。ハイパーバイザはカーネルよりも下層の最も低い層に位置し、ハードウェア上で直接動きます。ハイパーバイザは残りのソフトウェアをいくつかのドメインに分割することが可能で、ドメインは多数の仮想マシンと考えられます。これらのドメインの 1 つ (最初に起動されたもの) は dom0 として知られており、特別な役割を担います。なぜなら、dom0 だけがハイパーバイザを制御することが可能だからです。他のドメインは domU として知られています。ユーザ視点で言い換えれば、dom0 は他の仮想システムにおける「ホスト」、これに対して domU は「ゲスト」になります。
Debian の下で Xen を使うには 3 つの要素が必要です。
  • ハイパーバイザ自身。適切なパッケージは利用できるハードウェアによって決まり、xen-hypervisor-4.4-amd64xen-hypervisor-4.4-armhfxen-hypervisor-4.4-arm64 のうちどれか一つです。
  • ハイパーバイザ上で実行するカーネル。Jessie の提供するバージョン 3.16 を含めて、バージョン 3.0 より新しい Linux カーネルが動作します。
  • i386 アーキテクチャでは、Xen を活用するための適切なパッチを取り込んだ標準的なライブラリが必要です。そしてこれは libc6-xen パッケージに含まれます。
複数の構成要素を手作業で選択するという煩わしさを避けるために、いくつかの便利なパッケージ (xen-linux-system-amd64 など) が用意されています。そしてこれらのパッケージをインストールすることで、適切なハイパーバイザとカーネルパッケージが既知の良い組み合わせで導入されます。ハイパーバイザには xen-utils-4.4 が含まれます。このパッケージには dom0 からハイパーバイザを操作するためのツールが含まれます。同様に、このパッケージには適切な標準的ライブラリが含まれます。すべてのインストール中に、設定スクリプトは Grub ブートローダメニューに新しいエントリを作成します。こうすることで Xen dom0 から選択されたカーネルを開始することが可能です。しかしながら、通常このエントリはリストの最初に置かれないため、デフォルトで選択されません。この点に注意してください。これを望まない場合、以下のコマンドを使って変更してください。
# mv /etc/grub.d/20_linux_xen /etc/grub.d/09_linux_xen
# update-grub
これらの前提要件をインストールしたら、次に dom0 の挙動をテストします。そしてこれを行うには、ハイパーバイザと Xen カーネルの再起動が必要です。システムは標準的な方法で起動するべきです。初期化の早い段階でコンソールにいくつかの追加的メッセージが表示されます。
これで、有用なシステムを domU システムに実際にインストールできるようになりました。これを行うには xen-tools の提供するツールを使います。このパッケージには xen-create-image コマンドが含まれます。これはタスクの大部分を自動化します。必須のパラメータは --hostname だけで、このパラメータは domU の名前を設定します。他のオプションは重要ですが、/etc/xen-tools/xen-tools.conf 設定ファイルに保存することが可能です。そして、コマンドラインでオプションを指定しなくてもエラーは起きません。このため、イメージを作る前にこのファイルの内容を確認するか、xen-create-image の実行時に追加的パラメータを使うことが重要です。以下に注目すべき重要なパラメータを示します。
  • --memory、新たに作成するシステム用の RAM のサイズを指定します。
  • --size--swap、domU で利用できる「仮想ディスク」のサイズを定義します。
  • --debootstrapdebootstrap を使って新しいシステムをインストールします。さらに、このオプションを使う場合、--dist オプション (ディストリビューションの名前、たとえば jessie) を一緒に使うことが多いです。
  • --dhcp は domU のネットワーク設定を DHCP で取得することを宣言します。対して、--ip は静的 IP アドレスを定義します。
  • 最後に、作成されるイメージ (domU からはハードディスクドライブに見えるイメージ) の保存方法を選択します。最も簡単な方法は、対応する --dir オプションを使い、各 domU を格納するデバイス用のファイルを dom0 上に作成する方法です。LVM を使っているシステムでは、--lvm オプションを使い、ボリュームグループの名前を指定しても良いでしょう。そして xen-create-image は新しい論理ボリュームをグループの中に作成し、この論理ボリュームがハードディスクドライブとして domU から利用できるようにされます。
これらを選んだ後、将来の Xen domU 用のイメージを作成することが可能です。
# xen-create-image --hostname testxen --dhcp --dir /srv/testxen --size=2G --dist=jessie --role=udev

[...]
General Information
--------------------
Hostname       :  testxen
Distribution   :  jessie
Mirror         :  http://ftp.debian.org/debian/
Partitions     :  swap            128Mb (swap)
                  /               2G    (ext3)
Image type     :  sparse
Memory size    :  128Mb
Kernel path    :  /boot/vmlinuz-3.16.0-4-amd64
Initrd path    :  /boot/initrd.img-3.16.0-4-amd64
[...]
Logfile produced at:
         /var/log/xen-tools/testxen.log

Installation Summary
---------------------
Hostname        :  testxen
Distribution    :  jessie
MAC Address     :  00:16:3E:8E:67:5C
IP-Address(es)  :  dynamic
RSA Fingerprint :  0a:6e:71:98:95:46:64:ec:80:37:63:18:73:04:dd:2b
Root Password   :  adaX2jyRHNuWm8BDJS7PcEJ
これで仮想マシンが作成されましたが、仮想マシンはまだ実行されていません (このため dom0 のハードディスク上の領域だけが使われています)。もちろん、異なるパラメータを使ってより多くのイメージを作成することが可能です。
仮想マシンを起動する前に、仮想マシンにアクセスする方法を定義します。もちろん仮想マシンは隔離されたマシンですから、仮想マシンにアクセスする唯一の方法はシステムコンソールだけです。しかし、システムコンソールだけで要求を満足できることはほとんどないと言っても過言ではありません。ほとんどの時間、domU はリモートサーバとして機能し、ネットワークを通じてのみアクセスされます。しかしながら、各 domU 専用のネットワークカードを追加するのはかなり不便です。このため Xen は仮想インターフェースの作成機能を備えています。各ドメインは仮想インターフェースを参照し、標準的な方法で使うことが可能です。これらのネットワークカードは仮想的なものですが、ネットワークに接続したら便利に使えるという点に注意してください。Xen は複数のネットワークモデルを備えています。
  • 最も単純なモデルは bridge モデルです。この場合、すべての eth0 ネットワークカードが (dom0 と domU システムに含まれるものも含めて) 直接的にイーサネットスイッチに接続されているかのように振る舞います。
  • 2 番目に単純なモデルは routing モデルです。これは dom0 が domU システムと (物理) 外部ネットワークの間に位置するルータとして振る舞うモデルです。
  • 最後が NAT モデルです。これは dom0 が domU システムとその他のネットワークの間に位置するモデルですが、domU システムに外部から直接アクセスすることは不可能です。dom0 の行ういくつかのネットワークアドレス変換がトラフィックを仲介します。
これら 3 種類のネットワークノードには、独特な名前を付けられた数多くのインターフェースが含まれます。vif*veth*peth*xenbr0 です。Xen ハイパーバイザは定義された配置に従いユーザ空間ツールの制御の下でインターフェースを準備します。NAT と routing モデルは特定の場合にのみ適合します。このためわれわれは bridging モデルを使います。
Xen パッケージの標準的な設定はシステム全体のネットワーク設定を変更しません。しかしながら、xend デーモンは既存のネットワークブリッジの中に仮想ネットワークインターフェースを統合する (複数のブリッジが存在する場合 xenbr0 を優先する) ように設定されています。このためわれわれは /etc/network/interfaces の中にブリッジをセットアップして (bridge-utils パッケージをインストールする必要があります。このため bridge-utils パッケージは xen-utils-4.4 パッケージの推奨パッケージになっています)、既存の eth0 エントリを置き替えます。
auto xenbr0
iface xenbr0 inet dhcp
    bridge_ports eth0
    bridge_maxwait 0
再起動の後、ブリッジが自動的に作成されることを確認します。この後 Xen 制御ツール、特に xl コマンドを使って domU を起動することが可能です。さらに、ドメインを表示、起動、終了するなどの操作を行うことが可能です。
# xl list
Name                                        ID   Mem VCPUs      State   Time(s)
Domain-0                                     0   463     1     r-----      9.8
# xl create /etc/xen/testxen.cfg
Parsing config from /etc/xen/testxen.cfg
# xl list
Name                                        ID   Mem VCPUs      State   Time(s)
Domain-0                                     0   366     1     r-----     11.4
testxen                                      1   128     1     -b----      1.1
testxen domU は仮想メモリではなく RAM から取った真のメモリを使い、このメモリ領域は dom0 によって使われる場合もあります。この点に注意してください。このため、サーバを作ることが Xen インスタンスをホストすることを意味する場合、それに応じて物理 RAM を供給することになる点に注意が必要です。
これで、仮想マシンが開始されました。仮想マシンにアクセスするには 2 種類の方法があります。通常の方法は、真のマシンに接続するのと同様に、ネットワークを介して「リモートで」仮想マシンに接続することです。そしてこれを行うには、通常別の DHCP サーバや DNS 設定をセットアップすることが必要です。別の方法は xl console コマンドから hvc0 コンソールを使う方法です。ネットワーク設定が正しくない場合にはこれが唯一の方法です。
# xl console testxen
[...]

Debian GNU/Linux 8 testxen hvc0

testxen login: 
仮想マシンのキーボードの前に座っているかのごとくセッションを開くことが可能です。このコンソールからデタッチするには、Control+] キーの組み合わせを使用します。
domU の起動完了後、domU は他のサーバと同様に使うことが可能です (domU は結局 GNU/Linux システムに過ぎません)。しかしながら、domU の仮想マシンの状態はいくつかの追加的機能を備えています。たとえば、xl pausexl unpause コマンドを使って domU を一時的に停止したり再開することが可能です。一時的に停止された domU は全くプロセッサを使いませんが、割り当てられたメモリを解放しません。xl savexl restore コマンドを考慮することは興味深いかもしれません。なぜなら domU を保存すれば domU の使っていた RAM などの資源が解放されるからです。domU を元に戻す時 (ついでに言えば再開する時)、domU は時間が経過したことに全く気が付きません。dom0 を停止した時に domU が動いていた場合、パッケージに含まれるスクリプトが自動的に domU を保存し、dom0 の次回起動時に domU を自動的に再開します。もちろんこれにはラップトップコンピュータをハイバネートする場合と同様の標準的な不便さがあります。特に、domU が長い間一時停止されていた場合、ネットワーク接続が切断される可能性があります。今現在 Xen は ACPI 電源管理のほとんどに互換性がない点にも注意してください。このため、ホスト (dom0) システムを一時停止することは不可能です。
domU を停止したり再起動するには、domU の内部から (shutdown コマンドを使って) 行ったり、xl shutdown または xl reboot を使って dom0 から行うことも可能です。

12.2.2. LXC

LXC は「仮想マシン」を作るために使われるにも関わらず、厳密に言うと仮想システムではなく、同じホスト上で実行されるプロセスのグループを隔離するためのシステムです。LXC は近年 Linux カーネルに対して行われた数々の機能の利点を活用しています。これらの機能はまとめて control groups として知られています。control groups を使うことにより、「グループ」と呼ばれるさまざまなプロセス群に対してシステム全体の特定の側面の状態を強制することが可能です。中でも最も注目すべき側面はプロセス識別子、ネットワーク接続、マウントポイントです。隔離されたプロセスのグループはシステムの他のプロセスにアクセスできませんし、グループによるファイルシステムへのアクセスを特定の一部に限定することが可能です。さらにグループはネットワークインターフェースとルーティングテーブルを持っており、グループがシステムに存在する利用できるデバイスの一部だけを見えるように設定することが可能です。
これらの機能は init プロセスから起動されたすべてのプロセスファミリーに組み込むことが可能です。そして結果、仮想マシンにとてもよく似たものが作られます。このようなセットアップの正式名称は「コンテナ」です (これは LXC の名称 LinuX Containers に由来しています)。Xen や KVM が提供する「真の」仮想マシンとのより重要な違いは 2 番目のカーネルがない点です。このため、コンテナはホストシステムと同じカーネルを使います。これは利点と欠点があります。すなわち、利点はオーバーヘッドが全くないことによる素晴らしい性能と、カーネルがシステムで実行しているすべてのプロセスに対する包括的な視点を持つことです。このため 2 つの独立したカーネルが異なるタスクセットでスケジュールを行うよりも効果的なスケジューリングが可能です。欠点の最たるものはコンテナの中で異なるカーネルを動作させることができない点です (異なる Linux バージョンや異なるオペレーティングシステムを同時に動かすことができません)。
隔離は単純な仮想化と異なるため、LXC コンテナを設定することは仮想マシン上で単純に debian-installer を実行するよりも複雑な作業です。このため、いくつかの必要条件を説明した後、ネットワーク設定を行います。こうすることで、コンテナの中で実行するシステムを実際に作成することが可能です。

12.2.2.1. 準備段階

lxc パッケージには LXC を実行するために必要なツールが含まれるため、必ずこのパッケージをインストールしなければいけません。
LXC を使うには control groups 設定システムが必要で、/sys/fs/cgroup に仮想ファイルシステムをマウントする必要があります。Debian 8 からは init システムとして systemd が採用されており、systemd は control groups に依存しているため、設定せずとも /sys/fs/cgroup は起動時に自動でマウントされます。

12.2.2.2. ネットワーク設定

LXC をインストールする目的は仮想マシンをセットアップすることです。もちろん、仮想マシンをネットワークから隔離するように設定したり、ファイルシステムを介してのみ情報をやり取りするように設定することも可能ですが、コンテナに対して少なくとも最低限のネットワークアクセスを提供するように設定するのが一般的です。典型的な場合、各コンテナにはブリッジを介して実際のネットワークに接続された仮想ネットワークインターフェースが備えられています。この仮想インターフェースは、直接ホスト上の物理ネットワークインターフェースに接続されているか (この場合、コンテナは直接ネットワークに接続されています)、ホスト上に定義された他の仮想インターフェースに接続されています (ホストからトラフィックをフィルタしたり配送することが可能です)。どちらの場合も、bridge-utils パッケージが必要です。
最も簡単なやり方は /etc/network/interfaces を編集することです。物理インターフェース (たとえば eth0) に関する設定をブリッジインターフェース (通常 br0) に変え、物理とブリッジインターフェース間のリンクを設定します。たとえば、最初にネットワークインターフェース設定ファイルが以下のようなエントリを持っていたとします。
auto eth0
iface eth0 inet dhcp
このエントリを無効化し、以下の通り書き換えます。
#auto eth0
#iface eth0 inet dhcp

auto br0
iface br0 inet dhcp
  bridge-ports eth0
この設定により、コンテナをホストと同じ物理ネットワークに接続されたマシンとして考えた場合と、同様の効果が得られます。この「ブリッジ」設定はすべてのブリッジされたインターフェース間のイーサネットフレームの通過を管理します。これには物理的な eth0 およびコンテナ用に定義されたインターフェースが含まれます。
この設定を使うことができない場合 (たとえば、公開 IP アドレスをコンテナに割り当てることができない場合)、仮想 tap インターフェースを作成し、これをブリッジに接続します。これと等価なネットワークトポロジーは、ホストの 2 番目のネットワークカードが分離されたスイッチに接続されている状態です。コンテナはこのスイッチに接続されています。コンテナが外部と通信するには、ホストがコンテナ用のゲートウェイとして振る舞わなければいけません。
bridge-utils に加えて、この「ぜいたくな」設定を行うには vde2 パッケージが必要です。これで /etc/network/interfaces ファイルは以下のようになります。
# Interface eth0 is unchanged
auto eth0
iface eth0 inet dhcp

# Virtual interface 
auto tap0
iface tap0 inet manual
  vde2-switch -t tap0

# Bridge for containers
auto br0
iface br0 inet static
  bridge-ports tap0
  address 10.0.0.1
  netmask 255.255.255.0
コンテナのネットワークは静的またはホスト上で動く DHCP サーバを使って動的に設定されます。また、DHCP サーバを br0 インターフェースを介した問い合わせに応答するように設定する必要があります。

12.2.2.3. システムのセットアップ

コンテナがファイルシステムを使うようにファイルシステムを設定しましょう。この「仮想マシン」はハードウェア上で直接的に実行されないため、標準的なファイルシステムに比べていくつかの微調整を必要とします。これは特にカーネル、デバイス、コンソールが該当します。幸いなことに、lxc にはこの設定をほぼ自動化するスクリプトが含まれます。たとえば、以下のコマンド (debootstraprsync パッケージが必要です) で Debian コンテナがインストールされます。
root@mirwiz:~# lxc-create -n testlxc -t debian
debootstrap is /usr/sbin/debootstrap
Checking cache download in /var/cache/lxc/debian/rootfs-jessie-amd64 ... 
Downloading debian minimal ...
I: Retrieving Release 
I: Retrieving Release.gpg 
[...]
Download complete.
Copying rootfs to /var/lib/lxc/testlxc/rootfs...
[...]
Root password is 'sSiKhMzI', please change !
root@mirwiz:~# 
ファイルシステムは最初に /var/cache/lxc の中に作成され、その後目的のディレクトリに移動されます。こうすることで、同一のコンテナが極めて素早く作成されます。なぜなら、単純にコピーするだけだからです。
この debian テンプレート作成スクリプトは、インストールされるシステムのアーキテクチャを指定する --arch オプションと、現在の Debian 安定版以外の物をインストールしたい場合に指定する --release オプションを受け入れます。また、MIRROR 環境変数を設定してローカル Debian ミラーを指定することも可能です。
これで、新規に作成されたファイルシステムが最低限の Debian システムを含むようになりました。デフォルト状態だとこのコンテナにはネットワークインターフェースがありません (ループバックインターフェースすらありません)。これは全く望むべき状態ではないため、コンテナの設定ファイル (/var/lib/lxc/testlxc/config) を編集し、いくつかの lxc.network.* エントリを追加します。
lxc.network.type = veth
lxc.network.flags = up
lxc.network.link = br0
lxc.network.hwaddr = 4a:49:43:49:79:20
これらのエントリの意味するところはそれぞれ、仮想インターフェースはコンテナによって作られます。そして仮想インターフェースはコンテナが開始された時に自動的に利用できる状態にされます。そして仮想インターフェースはホストの br0 ブリッジに自動的に接続されます。さらに仮想インターフェースの MAC アドレスは指定したものになります。最後のエントリを削除するか無効化した場合、ランダムな MAC アドレスが生成されます。
設定ファイル内の便利なエントリを使ってホスト名を設定することも可能です。
lxc.utsname = testlxc

12.2.2.4. コンテナの開始

これで仮想マシンイメージの準備が整いました。それではコンテナを開始しましょう。
root@mirwiz:~# lxc-start --daemon --name=testlxc
root@mirwiz:~# lxc-console -n testlxc
Debian GNU/Linux 8 testlxc tty1

testlxc login: root
Password: 
Linux testlxc 3.16.0-4-amd64 #1 SMP Debian 3.16.7-ckt11-1 (2015-05-24) x86_64

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@testlxc:~# ps auxwf
USER       PID %CPU %MEM    VSZ   RSS TTY      STAT START   TIME COMMAND
root         1  0.0  0.2  28164  4432 ?        Ss   17:33   0:00 /sbin/init
root        20  0.0  0.1  32960  3160 ?        Ss   17:33   0:00 /lib/systemd/systemd-journald
root        82  0.0  0.3  55164  5456 ?        Ss   17:34   0:00 /usr/sbin/sshd -D
root        87  0.0  0.1  12656  1924 tty2     Ss+  17:34   0:00 /sbin/agetty --noclear tty2 linux
root        88  0.0  0.1  12656  1764 tty3     Ss+  17:34   0:00 /sbin/agetty --noclear tty3 linux
root        89  0.0  0.1  12656  1908 tty4     Ss+  17:34   0:00 /sbin/agetty --noclear tty4 linux
root        90  0.0  0.1  63300  2944 tty1     Ss   17:34   0:00 /bin/login --     
root       117  0.0  0.2  21828  3668 tty1     S    17:35   0:00  \_ -bash
root       268  0.0  0.1  19088  2572 tty1     R+   17:39   0:00      \_ ps auxfw
root        91  0.0  0.1  14228  2356 console  Ss+  17:34   0:00 /sbin/agetty --noclear --keep-baud console 115200 38400 9600 vt102
root       197  0.0  0.4  25384  7640 ?        Ss   17:38   0:00 dhclient -v -pf /run/dhclient.eth0.pid -lf /var/lib/dhcp/dhclient.e
root       266  0.0  0.1  12656  1840 ?        Ss   17:39   0:00 /sbin/agetty --noclear tty5 linux
root       267  0.0  0.1  12656  1928 ?        Ss   17:39   0:00 /sbin/agetty --noclear tty6 linux
root@testlxc:~# 
これでコンテナの中に入りました。さらに、プロセスへのアクセスはコンテナ自身によって開始されたものだけに制限されています。同様に、ファイルシステムへのアクセスもこのコンテナ専用に割り当てられた完全なファイルシステムの一部分 (/var/lib/lxc/testlxc/rootfs) に制限されています。コンソールを終了するには Control+a q を使います。
lxc-start--daemon オプションを渡したおかげで、コンテナがバックグラウンドプロセスとして実行されていることに注意してください。コンテナを中止するには lxc-stop --name=testlxc などのコマンドを使います。
lxc パッケージには、ホストの起動時に自動的に 1 つまたは複数のコンテナを開始するための初期化スクリプトが含まれます (この初期化スクリプトは lxc.start.auto オプションが 1 に設定されているコンテナを起動する lxc-autostart に依存しています)。起動順序を非常に細かく制御するには lxc.start.orderlxc.group を使います。デフォルトの場合、初期化スクリプトは onboot グループに所属するコンテナを起動し、その後いかなるグループにも所属しないコンテナを起動します。どちらの場合も、グループ内の起動順序を制御するには lxc.start.order オプションを使います。

12.2.3. KVM を使った仮想化

KVM は Kernel-based Virtual Machine を意味しており、仮想化システムの使うほとんどの基礎構造を提供する、最初で最高のカーネルモジュールですが、これ自身は仮想化システムではありません。仮想化の実際の制御を行うには QEMU に基づくアプリケーションを使います。この節で qemu-* コマンドがあっても心配しないでください。なぜならこのコマンドは KVM に関連するものだからです。
他の仮想化システムと異なり、KVM は最初から Linux カーネルにマージされていました。KVM の開発者はプロセッサが備える仮想化専用命令セット (Intel-VT と AMD-V) を有効活用することを選びました。仮想化専用命令セットを活用することで、KVM は軽量で簡潔でリソースを大量に消費しないものになっています。KVM の欠点は、KVM はすべてのコンピュータで動くわけではなく、適切なプロセッサを備えたコンピュータでなければ動かない、という点です。x86 ベースのコンピュータでは、/proc/cpuinfo 内の CPU フラグを確認して、ここに「vmx」または「svm」が含まれている場合、そのプロセッサは KVM を動かすことができることを意味します。
Red Hat が KVM の開発を活発に支援したことで、KVM は事実上 Linux 仮想化の基準点になりました。

12.2.3.1. 準備段階

VirtualBox などのツールと異なり、KVM は仮想マシンを作成管理するためのユーザインターフェースを含みません。qemu-kvm パッケージには、仮想マシンを開始することが可能な実行ファイルおよび適切なカーネルモジュールを読み込むための初期化スクリプトが含まれます。
幸いなことに、Red Hat は libvirt ライブラリおよび関連する仮想マシンマネージャツールを開発することで、この問題に対処するためのツールを提供しています。libvirt により、仮想マシンを管理する方法が統一され、管理方法が裏で動く仮想システムに依存しなくなります (libvirt は現在 QEMU、KVM、Xen、LXC、OpenVZ、VirtualBox、VMWare、UML をサポートしています)。virtual-manager はグラフィルインターフェースで、仮想マシンを作成管理するために libvirt を使います。
最初に apt-get install qemu-kvm libvirt-bin virtinst virt-manager virt-viewer を使って、必要なパッケージをインストールします。libvirt-bin には、libvirtd デーモンが含まれます。libvirtd デーモンを使うことで、ホストで実行されている仮想マシンを (潜在的にリモートで) 管理したり、ホスト起動時に要求された VM を開始する、ことが可能です。加えて、libvirt-bin パッケージは virsh コマンドラインツールを提供します。virsh を使うことで、libvirtd の管理するマシンを操作することが可能です。
virtinst パッケージには virt-install コマンドが含まれます。virt-install を使うことで、コマンドラインから仮想マシンを作成することが可能になります。最後に、virt-viewer は VM のグラフィカルコンソールへのアクセスを提供します。

12.2.3.2. ネットワーク設定

Xen や LXC と同様に、最もよく使われるネットワーク設定は仮想マシンのネットワークインターフェースをグループ化するブリッジです (第 12.2.2.2 節「ネットワーク設定」を参照してください)。
別の方法として、KVM の提供するデフォルト設定の中では、仮想マシンに (192.168.122.0/24 の範囲内に) プライベートアドレスを割り当てており、さらに NAT が設定されています。この設定により VM は外部ネットワークにアクセスすることが可能です。
この節の残りでは、ホストが eth0 物理インターフェースと br0 ブリッジを備え、eth0br0 に接続されていることを仮定します。

12.2.3.3. virt-install を使ったインストール

仮想マシンの作成は普通のシステムをインストールするのとよく似ています。違いは、仮想マシンの性質をコマンドラインから非常に長々と指定する点です。
具体的に言えば、これはホストシステムに保存された Debian DVD イメージを挿入された仮想 DVD-ROM ドライブから仮想マシンを起動することにより Debian インストーラを使うことを意味します。VM は VNC プロトコル (詳しくは第 9.2.2 節「リモートグラフィカルデスクトップの利用」を参照) を介してグラフィカルコンソールに表示されます。これによりインストール作業を操作することが可能になります。
最初にディスクイメージの保存先を libvirtd に伝える必要があります。デフォルトの保存先 (/var/lib/libvirt/images/) でも構わないならばこれは必要ありません。
root@mirwiz:~# mkdir /srv/kvm
root@mirwiz:~# virsh pool-create-as srv-kvm dir --target /srv/kvm
Pool srv-kvm created

root@mirwiz:~# 
それでは仮想マシンのインストール作業を開始し、virt-install の最も重要なオプションを詳細に見て行きましょう。virt-install は仮想マシンとそのパラメータを libvirtd に登録し、インストールを進めるために仮想マシンを開始します。
# virt-install --connect qemu:///system  1
               --virt-type kvm           2
               --name testkvm            3
               --ram 1024                4
               --disk /srv/kvm/testkvm.qcow,format=qcow2,size=10 5
               --cdrom /srv/isos/debian-8.1.0-amd64-netinst.iso  6
               --network bridge=br0      7
               --vnc                     8
               --os-type linux           9
               --os-variant debianwheezy

Starting install...
Allocating 'testkvm.qcow'             |  10 GB     00:00
Creating domain...                    |    0 B     00:00
Guest installation complete... restarting guest.

1

--connect オプションは使用する「ハイパーバイザ」を指定します。これは仮想システムを表す URL (xen://qemu://lxc://openvz://vbox:// など) と VM をホストするマシン (ローカルホストの場合、空でも構いません) の形をしています。QEMU/KVM の場合、これに加えて各ユーザは制限されたパーミッションで稼働する仮想マシンを管理できます。この場合 URL パスは「システム」マシン (/system) かその他 (/session) かで識別されます。

2

URL を一見すると QEMU が使われるように見えますが、KVM は QEMU と同じ方法で管理されているため、--virt-type kvm を指定することで KVM を使うことが可能です。

3

--name オプションは仮想マシンの (一意的な) 名前を定義します。

4

--ram オプションは仮想マシンに割り当てる RAM の量 (MB 単位) を指定します。

5

--disk オプションは仮想マシンのハードディスクとして利用するイメージファイルの場所を指定します。そして、このファイルが存在しなければ、size パラメータで指定されたサイズ (GB 単位) で作成されます。format パラメータはイメージファイルを保存するさまざまな方法を選択します。デフォルトフォーマット (raw) はディスクサイズと内容が全く同じ単一ファイルです。ここではより先進的なフォーマット qcow2 を選びました。qcow2 は QEMU 専用のフォーマットで、最初は小さなファイルで仮想マシンが領域を実際に利用することになった時に増加するファイルです。

6

--cdrom オプションはインストール時に利用する光学ディスクの場所を指定するために使われます。パスは ISO ファイルのローカルパス、ファイル取得先の URL、物理 CD-ROM ドライブのデバイスファイル (例 /dev/cdrom) のどれか 1 つを使うことが可能です。

7

--network はホストネットワーク設定の中に仮想ネットワークを統合する方法を指定します。デフォルトは既存のネットワークブリッジに仮想ネットワークを統合する方法です (例では明示的にこの挙動を指定しています)。このブリッジが存在しない場合、仮想マシンが到達できるネットワークは NAT を介した物理ネットワークだけに限定されるので、仮想マシンはプライベートサブネット範囲 (192.168.122.0/24) に含まれるアドレスを割り当てられます。

8

--vnc は VNC を使ってグラフィカルコンソールを利用できるようにすることを意味します。関連する VNC サーバに対するデフォルトの挙動はローカルインターフェースだけをリッスンします。さらに仮想マシンを操作する VNC クライアントを別のホスト上で実行する場合、VNC 接続を確立するには SSH トンネルを設定する必要があります (第 9.2.1.3 節「ポート転送を使った暗号化トンネルの作成」を参照してください)。別の方法として、VNC サーバをすべてのインターフェースを介して利用できるようにするために、--vnclisten=0.0.0.0 を使うことも可能です。しかしこの方針を取る場合、ファイアウォールを適切に設計するべきという点に注意してください。

9

--os-type--os-variant オプションは、指定されたオペレーティングシステムの備える既知の機能に基づいて、仮想マシンのいくつかのパラメータを最適化するためのものです。
この時点で仮想マシンは実行されています。インストール作業に進むためには、グラフィカルコンソールに接続する必要があります。上の操作をグラフィカルデスクトップ環境から行った場合、自動的に接続を開始します。そうでない場合、グラフィカルコンソールを開くために virt-viewer を任意のグラフィカル環境から実行します (この時にリモートホストの root パスワードが 2 回尋ねられる点に注意してください。この理由はこの操作には 2 つの SSH 接続を必要とするからです)。
$ virt-viewer --connect qemu+ssh://root@server/system testkvm
root@server's password: 
root@server's password: 
インストール作業が終了したら、仮想マシンが再起動されます。これで仮想マシンを利用する準備が整いました。

12.2.3.4. virsh を使ったマシンの管理

これでインストールが終了しました。利用できる仮想マシンを取り扱う方法に移りましょう。最初に libvirtd を使って管理している仮想マシンのリストを確認します。
# virsh -c qemu:///system list --all
 Id Name                 State
----------------------------------
  - testkvm              shut off
それではテスト用仮想マシンを起動しましょう。
# virsh -c qemu:///system start testkvm
Domain testkvm started
そして、グラフィカルコンソールへの接続命令を出します (接続する VNC 画面を vncviewer へのパラメータの形で指定することが可能です)。
# virsh -c qemu:///system vncdisplay testkvm
:0
その他の利用できる virsh サブコマンドには以下のものがあります。
  • reboot は仮想マシンを再起動します。
  • shutdown は仮想マシンを正常にシャットダウンします。
  • destroy は仮想マシンを無理やり停止します。
  • suspend は仮想マシンを一時停止します。
  • resume は一時停止された仮想マシンを再開します。
  • autostart はホスト起動時にこの仮想マシンを自動的に起動することを有効化します (または --disable オプションを付けて無効化します)。
  • undefine は仮想マシンのすべての痕跡を libvirtd から削除します。
ここに挙げたすべてのサブコマンドは仮想マシン識別子をパラメータとして受け取ります。

12.2.3.5. yum を使い RPM に基づくシステムを Debian の中にインストールする

仮想マシンが Debian (または Debian 派生物) を実行することを意図している場合、システムは上で述べた通り debootstrap を使って初期化されます。しかし、仮想マシンに RPM に基づくシステム (Fedora、CentOS、Scientific Linux など) をインストールする場合、yum ユーティリティ (同名のパッケージに含まれます) を使ってセットアップする必要があります。
RPM に基づくシステムをインストールする際には、特に yum 設定ファイルを含むファイルの初期セットを展開するために rpm を使い、その後パッケージの残りのセットを展開するために yum を呼び出す必要があります。しかし、chroot の外から yum を呼び出しているため、一時的な修正が必要です。以下に載せた例では、対象の chroot 先は /srv/centos です。
# rootdir="/srv/centos"
# mkdir -p "$rootdir" /etc/rpm
# echo "%_dbpath /var/lib/rpm" > /etc/rpm/macros.dbpath
# wget http://mirror.centos.org/centos/7/os/x86_64/Packages/centos-release-7-1.1503.el7.centos.2.8.x86_64.rpm
# rpm --nodeps --root "$rootdir" -i centos-release-7-1.1503.el7.centos.2.8.x86_64.rpm
rpm: RPM should not be used directly install RPM packages, use Alien instead!
rpm: However assuming you know what you are doing...
warning: centos-release-7-1.1503.el7.centos.2.8.x86_64.rpm: Header V3 RSA/SHA256 Signature, key ID f4a80eb5: NOKEY
# sed -i -e "s,gpgkey=file:///etc/,gpgkey=file://${rootdir}/etc/,g" $rootdir/etc/yum.repos.d/*.repo
# yum --assumeyes --installroot $rootdir groupinstall core
[...]
# sed -i -e "s,gpgkey=file://${rootdir}/etc/,gpgkey=file:///etc/,g" $rootdir/etc/yum.repos.d/*.repo