Product SiteDocumentation Site

12.2. 仮想化

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

12.2.1. Xen

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

12.2.2. LXC

LXC は「仮想マシン」を作るために使われるにも関わらず、厳密に言うと仮想システムではなく、同じホスト上で実行されるプロセスのグループを隔離するためのシステムです。LXC は近年 Linux カーネルに対して行われた数々の機能の利点を活用しています。これらの機能はまとめて control groups として知られています。control groups を使うことにより、「グループ」と呼ばれるさまざまなプロセス群に対してシステム全体の特定の側面の状態を強制することが可能です。中でも最も注目すべき側面はプロセス ID、ネットワーク接続、マウントポイントです。隔離されたプロセスのグループはシステムの他のプロセスにアクセスできませんし、グループによるファイルシステムへのアクセスを特定の一部に限定することが可能です。さらにグループにネットワークインターフェースとルーティングテーブルを設定することにより、グループがシステム上の利用できるデバイスの一部だけを見えるように設定することが可能です。
これらの機能を組み合わせることで、init プロセスから起動されたすべてのプロセスファミリーを隔離することが可能です。その結果、仮想マシンにとてもよく似たものが作られます。このようなセットアップの正式名称が「コンテナ」です (LXC の名称 LinuX Containers はこれに由来しています)。Xen や KVM が提供する「真の」仮想マシンとのより重要な違いは仮想マシン用のカーネルがない点です。このため、コンテナはホストシステムと全く同じカーネルを使います。これには利点と欠点があります。すなわち、利点はオーバーヘッドが全くないことで素晴らしい性能を得ることが可能という点とカーネルはシステムで実行しているすべてのプロセスを見ることが可能という点です。このため 2 つの独立したカーネルが異なるタスクセットでスケジュールを行うよりも効果的なスケジューリングが可能です。欠点の最たるものはコンテナの中で異なるカーネルを動作させることが不可能という点です (異なる Linux バージョンや異なるオペレーティングシステムを同時に動かすことができません)。
LXC による隔離は単純な仮想化と異なるため、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-utilsvde2 パッケージが必要です。/etc/network/interfaces ファイルは以下のようになります。
# eth0 インターフェースは同じものを使います
auto eth0
iface eth0 inet dhcp

# 仮想インターフェース
auto tap0
iface tap0 inet manual
  vde2-switch -t tap0

# コンテナ用のブリッジ
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 は /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:~# 
これでコンテナの中に入りました。プロセスへのアクセスはコンテナ自身によって開始されたものだけに制限されていることがわかります。同様に、ファイルシステムへのアクセスも 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 を意味しており、仮想化システムの使うほとんどの基礎構造を提供する最初で最高のカーネルモジュールです。しかしながら、LVM 自身は仮想化システムではありません。仮想化の実際の制御を行うには QEMU に基づくアプリケーションを使います。この節で qemu-* コマンドがあっても心配しないでください。なぜならこのコマンドは KVM に関連するものだからです。
他の仮想化システムと異なり、KVM は最初から Linux カーネルにマージされていました。KVM の開発者はプロセッサが備える仮想化専用命令セット (Intel-VT と AMD-V) を有効活用することを選びました。仮想化専用命令セットを活用することで、KVM は軽量で簡潔でリソースを大量に消費しないものになっています。もちろんその代償として 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 を使うことで、仮想マシンのグラフィカルコンソールにアクセスすることが可能になります。

12.2.3.2. ネットワークの設定

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

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

仮想マシンの作成は普通のシステムをインストールするのとよく似ています。違いは、仮想マシンの性質をコマンドラインから非常に長々と指定する点です。
具体的に言えば、これはホストシステムに保存された Debian DVD イメージを挿入された仮想 DVD-ROM ドライブから仮想マシンを起動することにより Debian インストーラを使うことを意味します。仮想マシンは 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

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

3

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

4

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

5

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

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-install を実行した時点で仮想マシンが実行されます。インストール作業に進むためには、グラフィカルコンソールに接続する必要があります。上の操作をグラフィカルデスクトップ環境から行った場合、自動的に接続が開始されます。そうでない場合、グラフィカルコンソールを開くために 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 を使ったマシンの管理

これでインストールが終了しました。利用できる仮想マシンを取り扱う方法に移りましょう。最初に 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