KVM

提供: ArchWiki
2017年10月13日 (金) 12:14時点におけるKusanaginoturugi (トーク | 投稿記録)による版 (ハイパーバイザーからハイパーバイザに変更)
ナビゲーションに移動 検索に移動

関連記事

KVM (Kernel-based Virtual Machine) は Linux カーネルに搭載されているハイパーバイザです。意図しているところは Xen と似ていますがもっとシンプルに動作します。エミュレーションを使うネイティブの QEMU と違って、KVM は仮想化のための CPU 拡張命令 (HVM) をカーネルモジュールを介して利用する QEMU の特殊なオペレーティングモードです。

KVM を使用することで、修正を加えずに GNU/Linux や Windows などのオペレーティングシステムが動作する仮想マシンを複数動かすことができます (詳しくは Guest Support Status を見て下さい)。それぞれの仮想マシンには専用の仮想化されたハードウェアが使われます: ネットワークカード、ディスク、グラフィックカードなど。

KVM と Xen, VMware, QEMU の違いについては KVM FAQ で説明されています。

この記事では KVM をバックエンドに使うエミュレータに共通の機能は扱いません。そのような情報は各々の該当する記事を見て下さい。

KVM サポートの確認

ハードウェアのサポート

KVM を使うには仮想マシンのホストのプロセッサが仮想化をサポートしている必要があります (Intel のプロセッサでは VT-x、AMD のプロセッサでは AMD-V という名前が付けられています)。あなたの使っているプロセッサがハードウェア仮想化をサポートしているかは次のコマンドで確認できます:

$ lscpu

プロセッサが仮想化をサポートしていれば、それを示す行があるはずです。

次を実行することでも確認できます:

$ egrep --color=auto 'vmx|svm|0xc0f' /proc/cpuinfo

このコマンドを実行しても何も表示されない場合、あなたのプロセッサはハードウェア仮想化をサポートしていないため、KVM を使用することはできません

ノート: BIOS の方で仮想化サポートを有効にする必要があるときもあります。

カーネルのサポート

Arch Linux のカーネルは KVM と VIRTIO をサポートする適切なカーネルモジュールを提供しています。

KVM モジュール

あなたの使っているカーネルで必要なカーネルモジュール (kvm と、kvm_amdkvm_intel のどちらか) が使えるようになっているかは次のコマンドで確認できます (カーネルが CONFIG_IKCONFIG_PROC を有効にしてビルドされたことが前提です):

$ zgrep CONFIG_KVM /proc/config.gz

モジュールが ym に設定されていない場合、そのモジュールは利用できないことを意味します。

準仮想化デバイス

ゲストがホストマシンのデバイスを使えるように、準仮想化は高速で効率的な通信手段を提供します。KVM はハイパーバイザーとゲスト間のレイヤーとして Virtio API を使って仮想マシンに準仮想化デバイスを提供します。

virtio デバイスは全て2つに分けることができます: ホストのデバイスとゲストのドライバーです。

VIRTIO モジュール

Virtio はネットワークやディスクデバイスドライバーの仮想化規格です。これによってゲストはネットワークやディスク操作の高いパフォーマンスを得ることが可能になり、準仮想化で役に立ちます。次のコマンドで必要なモジュールが使用可能か確認します:

$ zgrep VIRTIO /proc/config.gz

カーネルモジュールのロード

まず、カーネルモジュールが自動でロードされているか確認してください。最新の udev ではそうなっているはずです。

$ lsmod | grep kvm
$ lsmod | grep virtio

上記のコマンドが何もメッセージを返さない場合、カーネルモジュールをロードする必要があります。

ヒント: kvm_intelkvm_amd の modprobe が失敗して kvm の modprobe が成功する場合 (そして lscpu でハードウェアアクセラレーションがサポートされていると表示される場合)、BIOS の設定を確認してください。メーカーによっては (特にノートパソコンメーカー)、プロセッサの拡張をデフォルトで無効にしていることがあります。BIOS で無効化されている拡張があるかどうかは、modprobe に失敗した後に dmesg の出力を見ることで確認できます。

準仮想化デバイスの一覧

  • ネットワークデバイス (virtio-net)
  • ブロックデバイス (virtio-blk)
  • コントローラデバイス (virtio-scsi)
  • シリアルデバイス (virtio-serial)
  • バルーンデバイス (virtio-balloon)

KVM の使い方

次の記事を参照してください: QEMU

ヒントとテクニック

ノート: 一般的な小技やヒントは QEMU#ヒントとテクニックQEMU#トラブルシューティングを見て下さい。

仮想化のネスト

Nested Virtualization を使うことで、元の仮想マシンやネットワークに修正を加えることなく、既存の仮想マシンを別のハイパーバイザーや他のクラウド上で動作させることができるようになります。

ホスト側で、kvm_intel の nested 機能を有効にしてください:

# modprobe -r kvm_intel
# modprobe kvm_intel nested=1

永続化させるには (カーネルモジュール#モジュールオプションを設定するを参照):

/etc/modprobe.d/kvm_intel.conf
options kvm_intel nested=1

機能が有効になっているか確認:

$ systool -m kvm_intel -v | grep nested
    nested              = "Y"

次のコマンドでゲスト VM を実行してください:

$ qemu-system-x86_64 -enable-kvm -cpu host

VM を起動したら vmx フラグが存在するか確認:

$ egrep --color=auto 'vmx|svm' /proc/cpuinfo

手軽なネットワーク

ブリッジネットワークの設定は少し厄介です。実験目的で VM を使いたいのであれば、SSH トンネリングを使ってホストとゲストを接続するという方法があります。

基本的な手順は以下の通りです:

  • ホスト OS で SSH サーバーをセットアップ
  • (任意) トンネリング用のユーザーを作成 (例: tunneluser)
  • VM に SSH をインストール
  • セットアップ認証

SSH のセットアップについては SSH の記事、特に SSH#他のポートのフォワーディングを参照してください。

デフォルトのユーザーネットワークスタックを使用する場合、ホストには 10.0.2.2 アドレスでアクセスできます。

全てが動作しホストに SSH できるようになったら、/etc/rc.local に以下を追加してください:

# Local SSH Server
echo "Starting SSH tunnel"
sudo -u vmuser ssh tunneluser@10.0.2.2 -N -R 2213:127.0.0.1:22 -f
# Random remote port (e.g. from another VM)
echo "Starting random tunnel"
sudo -u vmuser ssh tunneluser@10.0.2.2 -N -L 2345:127.0.0.1:2345 -f

上記の例では VM の SSH サーバーのトンネルを作成してホストの任意のポートを VM に引き入れています。

VM における基礎的なネットワークですが、堅牢であり大抵の場合はこれで上手く行きます。

ヒュージページの有効化

ヒュージページを有効にすることで仮想マシンのパフォーマンスを向上させることができます。最新の Arch Linux と KVM ならおそらく必要条件はすべて満たされているはずです。/dev/hugepages ディレクトリが存在しているかどうかチェックしてください。ディレクトリが存在しなかったら、作成してください。そしてこのディレクトリに適切なパーミッションを設定します。

/etc/fstab に以下を追加:

hugetlbfs       /dev/hugepages  hugetlbfs       mode=1770,gid=78        0 0

もちろん gid は kvm グループに一致している必要があります。1770 ではグループの誰でもファイルを作成することができますが、他人のファイルを消去することはできません。/dev/hugepages が正しくマウントされていることを確認してください:

# umount /dev/hugepages
# mount /dev/hugepages
$ mount | grep huge
hugetlbfs on /dev/hugepages type hugetlbfs (rw,relatime,mode=1770,gid=78)

それから必要なヒュージページの数を計算します。ヒュージページの大きさを確認するには:

$ grep Hugepagesize /proc/meminfo

通常は 2048 kB ≙ 2 MB です。仮想マシンを 1024 MB で動作させたい場合、1024 / 2 = 512 となり少し追加して550まで丸めることができます。必要とするヒュージページをマシンに設定:

# echo 550 > /proc/sys/vm/nr_hugepages

十分な空きメモリがあれば以下のように表示されるはずです:

$ grep HugePages_Total /proc/meminfo 
HugesPages_Total:  550

数字がさらに小さい場合、アプリケーションを閉じるか少ないメモリで仮想マシンを起動してください (number_of_pages x 2):

$ qemu-system-x86_64 -enable-kvm -m 1024 -mem-path /dev/hugepages -hda <disk_image> [...]

そして -mem-path パラメータを使うことでヒュージページが利用されます。

仮想マシンの実行中に、使われているヒュージページを確認するには:

$ grep HugePages /proc/meminfo 
HugePages_Total:     550
HugePages_Free:       48
HugePages_Rsvd:        6
HugePages_Surp:        0

問題がないようでしたらデフォルトでヒュージページを有効にすることができます。以下を /etc/sysctl.d/40-hugepage.conf に追加してください:

vm.nr_hugepages = 550

参照:

参照