「QEMU」の版間の差分
(同期) |
Kusakata.bot (トーク | 投稿記録) (update Pkg/AUR templates) |
||
40行目: | 40行目: | ||
AUR より: |
AUR より: |
||
* {{AUR|aqemu-git}} |
* {{AUR|aqemu-git}} |
||
− | * {{AUR|virtualbricks}} |
+ | * {{AUR|virtualbricks}}{{Broken package link|{{aur-mirror|virtualbricks}}}} |
== 新しい仮想化システムの作成 == |
== 新しい仮想化システムの作成 == |
2017年5月11日 (木) 08:03時点における版
関連記事
QEMU ホームページ より:
- QEMU は汎用なオープンソースのマシンエミュレータ・バーチャライザーです。
マシンエミュレータとして使う場合、QEMU はあるマシン (例: ARM ボード) 用に作られた OS やプログラムを他のマシン (例: x86 PC) で動かすことができます。動的変換を利用することによって、素晴らしいパフォーマンスを実現します。
Xen や KVM など他のハイパーバイザーを使うことで QEMU は仮想化のための CPU 拡張命令を利用することができます。バーチャライザーとして使う場合、ゲストコードをホスト CPU で直接実行することにより QEMU はネイティブに近いパフォーマンスを得ることができます。
目次
- 1 インストール
- 2 QEMU のグラフィカルフロントエンド
- 3 新しい仮想化システムの作成
- 4 仮想化システムを実行する
- 5 ホスト・ゲスト OS 間でデータを移動する
- 6 ネットワーク
- 7 グラフィック
- 8 オーディオ
- 9 virtio ドライバーのインストール
- 10 Tips and tricks
- 11 トラブルシューティング
- 11.1 仮想マシンの動作が遅すぎる
- 11.2 マウスカーソルが敏感すぎたり迷走する
- 11.3 カーソルが表示されない
- 11.4 カーソルが移動・アタッチできない
- 11.5 キーボードが壊れているまたは矢印キーが動作しない
- 11.6 ウィンドウのリサイズでゲストのディスプレイが引き伸ばされる
- 11.7 ioctl(KVM_CREATE_VM) failed: 16 Device or resource busy
- 11.8 libgfapi エラーメッセージ
- 11.9 ライブ環境でカーネルパニックが発生する
- 11.10 Windows 7 ゲストの音質が酷い
- 11.11 ユーザーネットワークでインターネットに接続できない
- 12 参照
インストール
qemu パッケージ (または GUI が必要ない場合は qemu-headless) をインストールしてください。また、任意で以下のパッケージもインストールしてください:
- qemu-arch-extra - 特殊なアーキテクチャのサポート
- qemu-block-gluster - GlusterFS ブロックのサポート
- qemu-block-iscsi - iSCSI ブロックのサポート
- qemu-block-rbd - RBD ブロックのサポート
- samba - SMB/CIFS サーバーのサポート
QEMU のグラフィカルフロントエンド
VirtualBox や VMware など他の仮想化プログラムと違って、QEMU は仮想マシンを管理するための GUI を提供しません (仮想マシンを動かすときに表示されるウィンドウは別です)。また、保存された設定を使って永続的な仮想マシンを作成する方法も提供していません。仮想マシンを起動するためのカスタムスクリプトを作成しないかぎり、仮想マシンを起動するための全てのパラメータは起動する度にコマンドラインに指定する必要があります。ただし、QEMU の GUI フロントエンドは複数存在します:
AUR より:
- aqemu-gitAUR
- virtualbricksAUR[リンク切れ: アーカイブ: aur-mirror]
新しい仮想化システムの作成
ハードディスクイメージの作成
CD-ROM やネットワークからライブシステムを起動するのでない (そしてオペレーティングシステムをハードディスクイメージにインストールしない) 限り、QEMU を実行するにはハードディスクイメージが必要になります。ハードディスクイメージはエミュレートするハードディスクの内容を保存するファイルです。
ハードディスクイメージを raw にすると、ゲストからは文字通りバイト単位で等しいようになり、ホスト上のゲストハードドライブをフルに使用することになります。この方法は I/O のオーバーヘッドを最小に抑えられますが、ゲストで使用していない領域もホストは使えないため、大量の容量を消費するのが欠点です。
また、ハードディスクイメージを qcow2 などのフォーマットにすることもできます。ゲストオペレーティングシステムが実際に仮想ハードディスク上のセクタに書き込んだ時にイメージファイルに容量を割り当てます。ホストシステムで占める容量はかなり少なくて済み、ゲストオペレーションにはフルサイズのイメージとして見えます。こちらの形式では raw と違ってパフォーマンスに多少影響を与えます。
QEMU にはハードディスクイメージを作成するための qemu-img
コマンドがあります。例えば raw フォーマットで 4GB イメージを作成するには:
$ qemu-img create -f raw image_file 4G
-f qcow2
を使うことで qcow2 ディスクを作成できます。
オーバーレイストレージイメージ
一度ストレージメディアを作成してから ('backing' イメージ)、QEMU にイメージへの変更を overlay イメージとして維持させることができます。これによってストレージメディアを前の状態に戻すことが可能になります。戻りたい時点で、オリジナルの backing イメージを元に新しい overlay イメージを作成することで戻すことができます。
overlay イメージを作成するには、次のようにコマンドを実行してください:
$ qemu-img create -o backing_file=img1.raw,backing_fmt=raw -f qcow2 img1.cow
その後通常通り QEMU VM を起動することができます (仮想化システムを実行するを参照):
$ qemu-system-i386 img1.cow
backing イメージには変更が加えられず、ストレージへの追記は overlay イメージファイルに保存されるようになります。
backing イメージのパスが変更された場合、修正が必要になります。
オリジナルの backing イメージのパスからこのイメージに繋がるようにしてください。必要ならば、オリジナルのパスに新しいパスへのシンボリックリンクを作成します。次のようなコマンドを実行してください:
$ qemu-img rebase -b /new/img1.raw /new/img1.cow
あなたの判断で、backing イメージの古いパスがチェックされない'危険な' rebase を実行することもできます:
$ qemu-img rebase -u -b /new/img1.raw /new/img1.cow
イメージのリサイズ
qemu-img
実行可能ファイルには resize
オプションがあり、ハードドライブイメージの簡単なリサイズができます。このコマンドは raw と qcow2 の両方で使えます。例えば、イメージ容量を 10GB 増やすには、次を実行してください:
$ qemu-img resize disk_image +10G
インストールメディアを準備する
ディスクイメージにオペレーティングシステムをインストールするには、オペレーティングシステムのインストールメディア (例: オプティカルディスク、USB ドライブ、ISO イメージ) が必要です。QEMU はメディアに直接アクセスできないのでインストールメディアをマウントしてはいけません。
オペレーティングシステムのインストール
ここで初めてエミュレータを起動することになります。ディスクイメージにオペレーティングをインストールするには、ディスクイメージとインストールメディアの両方を仮想マシンに結びつけて、インストールメディアから起動するようにする必要があります。
例えば i386 環境で、CD-ROM と raw ディスクイメージのブータブル ISO ファイルからインストールするには:
$ qemu-system-i386 -cdrom iso_image -boot order=d -drive file=disk_image,format=raw
フロッピーやディスクイメージ、物理ドライブなどの他のメディアタイプをロードする方法は qemu(1)
を見てください。
オペレーティングシステムのインストールが終了したら、直接 QEMU イメージを起動することができます (仮想化システムを実行するを参照)。
仮想化システムを実行する
qemu-system-*
バイナリ (例えば qemu-system-i386
や qemu-system-x86_64
など、エミュレートするアーキテクチャによって異なります) を使って仮想化システムを実行します。使用方法は:
$ qemu-system-i386 options disk_image
全ての qemu-system-*
バイナリでオプションは共通です、全てのオプションのドキュメントは qemu(1)
を見て下さい。
デフォルトで、QEMU は仮想マシンのビデオ出力をウィンドウに表示します。注意: QEMU ウィンドウの中をクリックすると、マウスポインタが取り込まれます。ポインタを戻すには、Ctrl+Alt+g
を押して下さい。
KVM を有効にする
使用しているプロセッサとカーネルが KVM をサポートしている必要があります。また、必要なカーネルモジュールがロードされてなければなりません。詳しくは KVM を見て下さい。
QEMU を KVM モードで起動するには、起動オプションに -enable-kvm
を追加してください。実行中の仮想マシンで KVM が有効になっているかどうか確認するには、Ctrl+Alt+Shift+2
を使って QEMU Monitor に入り、info kvm
と入力してください。
IOMMU (Intel VT-d/AMD-Vi) サポートを有効にする
IOMMU を使うことで PCI パススルーやメモリの保護などの機能が利用できます。Wikipedia:ja:IOMMU#利点 や Memory Management (computer programming): Could you explain IOMMU in plain English? を見てください。
IOMMU を有効化するには:
- CPU によって AMD-Vi/Intel VT-d がサポートされていること、BIOS の設定で有効になっていることを確認してください。
- Intel の CPU を使っている場合は
intel_iommu=on
、AMD の CPU を使っている場合はamd_iommu=on
をカーネルパラメータに追加してください。 - 再起動して
dmesg
にDMAR
があることを確認して IOMMU が有効になっていることをチェックしてください:[0.000000] DMAR: IOMMU enabled
。 -device intel-iommu
を追加して IOMMU デバイスを作成してください:
$ qemu-system-x86_64 -enable-kvm -machine q35,accel=kvm -device intel-iommu -cpu host,hv_relaxed,hv_spinlocks=0x1fff,hv_vapic,hv_time ..
ホスト・ゲスト OS 間でデータを移動する
ネットワーク
ファイルを転送できるネットワークプロトコルであれば NFS, SMB, NBD, HTTP, FTP, SSH など何でも使ってホストとゲスト OS 間でデータを共有することができます、ただしネットワークを適切に設定して適切なサービスを有効にする必要があります。
デフォルトのユーザーモードネットワークは IP アドレス 10.0.2.2 でゲストがホスト OS にアクセスするのを許可します。ホスト OS で動作する全てのサーバー、SSH サーバーや SMB サーバーなどは、この IP アドレスでアクセスすることが可能になります。そしてゲストでは、SMB や NFS でホストのディレクトリをマウントしたり、ホストの HTTP サーバーなどにアクセスすることが可能です。 ゲスト OS で動作しているサーバーにホスト OS がアクセスすることはできませんが、他のネットワーク設定を使えば不可能ではありません (#QEMU の Tap ネットワーク を参照)。
QEMU の内蔵 SMB サーバー
QEMU のドキュメントには "内蔵の" SMB サーバーがあると書かれていますが、実際は自動的に生成された設定ファイル (/tmp/qemu-smb.pid-0/smb.conf
) で Samba を起動して別の IP アドレス (デフォルトでは 10.0.2.4) でゲストにアクセスできるようにするだけです。この機能はユーザーネットワークでしか動作せず、また、共有を設定していればホストの通常の Samba サービスにゲストがアクセスすることもできるので、必ずしも便利な機能とは言えません。
この機能を有効にするには、次のようなコマンドで QEMU を起動します:
$ qemu-system-i386 disk_image -net nic -net user,smb=shared_dir_path
shared_dir_path
はゲストとホストで共有したいディレクトリに置き換えてください。
これで、ゲストから、ホスト 10.0.2.4 の共有ディレクトリに共有名 "qemu" でアクセスすることができるようになります。例えば、Windows エクスプローラーなら \\10.0.2.4\qemu
を開きます。
raw ディスクイメージの中にパーティションをマウントする
仮想マシンが動作していないときに、raw ディスクイメージファイル内のパーティションをループバックデバイスとして設定することでマウントすることが可能です。これは qcow2 などの特別なフォーマットのディスクイメージでは動作しませんが、qemu-nbd
を使ってマウントすることはできます。
手動でバイトオフセットを指定する
ディスクイメージのパーティションをマウントする一つの方法として、次のようなコマンドを使って特定のオフセットでディスクイメージをマウントする方法があります:
# mount -o loop,offset=32256 disk_image mountpoint
offset=32256
オプションは losetup
プログラムにわたされて、ファイルのバイトオフセット 32256 から最後まで続くループバックデバイスが設定され、それからこのループバックデバイスがマウントされます。sizelimit
オプションを使ってパーティションの実際のサイズを指定することもできますが、これは基本的に必要ありません。
ディスクイメージによって、必要なパーティションがオフセット 32256 から始まってない可能性があります。fdisk -l disk_image
を実行してイメージ内のパーティションを見て下さい。fdisk は512バイトセクタ単位で起点と終点を表示するので、512 を掛けて適当なオフセットを mount
で指定してください。
loop モジュールでパーティションを自動検出する
Linux の loop ドライバーはループバックデバイスのパーティションをサポートしていますが、デフォルトでは無効にされています。有効にするには、以下を行なって下さい:
- 全てのループバックデバイスを取り除いて下さい (マウントされているイメージを全てアンコメントするなど)。
loop
モジュールを一度アンロードしてから、max_part=15
パラメータを設定してロードしてください。また、ループデバイスの最大数はmax_loop
パラメータで決めることができます。
あなたのイメージをループバックデバイスとして設定:
# losetup -f -P disk_image
これで、デバイスが /dev/loop0
の場合、追加のデバイス /dev/loop0pX
が自動的に作成されます。X はパーティションの番号です。これらのパーティションのループバックデバイスは直接マウントすることができます。例:
# mount /dev/loop0p1 mountpoint
udisksctl でディスクイメージをマウントする方法は Udisks#ISO イメージのマウントを見てください。
kpartx を使う
AUR の multipath-toolsAUR パッケージに入っている kpartx はデバイスのパーティションテーブルを読み込んでパーティションごとに新しいデバイスを作成することができます。例えば:
# kpartx -a disk_image
上記のコマンドで、ループバックデバイスがセットアップされ /dev/mapper/
に必要なパーティションデバイスが作成されます。
qcow2 イメージの中にパーティションをマウントする
qcow2 イメージの中のパーティションは qemu-nbd
を使ってマウントできます。Wikibooks を見て下さい。
実際のパーティションをハードディスクイメージのシングルプライマリパーティションとして使う
場合によって、QEMU の中からシステムパーティションのどれかを使いたくなることもあるでしょう。仮想マシンでの raw パーティションの使用は、読み書きの操作が物理ホストのファイルシステムレイヤーを通過しないため、パフォーマンスが高くなります。そのようなパーティションをホストとゲストでのデータの共有手段として使うこともできます。
Arch Linux では、raw パーティションのデバイスファイルは、デフォルトで、root と disk グループが所有者です。root 以外のユーザーで raw パーティションに読み書きできるようにしたい場合は、パーティションのデバイスファイルの所有者をそのユーザーに変える必要があります。
その後、パーティションを QEMU の仮想マシンに仮想ディスクとしてアタッチできます。
ただし、仮想マシン全体をパーティションに収めたいときは、自体は多少複雑になります。そのような場合、実際に仮想マシンを起動するディスクイメージファイルがないために、MBR でパーティション分けされたデバイスではなくファイルシステムとしてフォーマットされたパーティションにブートローダーをインストールすることができません。このような仮想マシンはカーネルと initrd を手動で指定するか、リニア RAID を使って MBR のディスクをシミュレートすることで起動できます。
カーネルと initrd を手動で指定する
QEMU は GRUB などのブートローダーを迂回して、Linux カーネルと init ramdisk を直接ロードすることをサポートしています。それから root ファイルシステムを含んでいる物理パーティションで、パーティションされていない仮想ディスクとして起動することができます。以下のようなコマンドを実行することで行います:
$ qemu-system-i386 -kernel /boot/vmlinuz-linux -initrd /boot/initramfs-linux.img -append root=/dev/sda /dev/sda3
上の例では、ゲストの root ファイルシステムに使われている物理パーティションはホストの /dev/sda3
で、ゲストでは /dev/sda
として表示されます。
もちろん、Arch Linux で使われているものとは違うカーネルや initrd を自由に指定することができます。
複数のカーネルパラメータを -append
オプションで指定するときは、クォートを使って囲む必要があります。例:
... -append 'root=/dev/sda1 console=ttyS0'
リニア RAID を使って MBR で仮想ディスクをシミュレート
ファイルシステムでフォーマットされたパーティションを維持しながらゲストのパーティションをまるでディスクであるかのようなパーティションにしないで、仮想マシンで物理パーティションを使用するもっと複雑な方法として、MBR をシミュレートして GRUB などのブートローダーを使って起動できるようにする方法があります。
リニアモードのソフトウェア RAID (linear.ko
カーネルドライバーが必要) とループバックデバイスを使えばこれが可能です: 方策としては QEMU の raw ディスクイメーに埋め込みたい物理パーティションに動的にマスターブートレコード (MBR) を先頭に付け加えます。
QEMU ディスクイメージの一部にしたいファイルシステムがあるプレーンな、マウントされていない /dev/hdaN
パーティションがあるとします。まず最初に、MBR を入れるための小さなファイルを作成:
$ dd if=/dev/zero of=/path/to/mbr count=32
これで 16 KB (32 * 512 バイト) のファイルが作成されます。(MBR は512バイトのブロックしか必要としませんが) あまり小さくしすぎないことが重要です。なぜならファイルを小さくすればするほど、ソフトウェア RAID デバイスのチャンクサイズも小さくしなくてはならなくなり、パフォーマンスに影響を与えるからです。次に、MBR ファイルのループバックデバイスを設定します:
# losetup -f /path/to/mbr
他にループバックを使っていないために、作成されるデバイスは /dev/loop0
になるとします。次のステップはソフトウェア RAID を使って "merged" MBR + /dev/hdaN
ディスクイメージを作成することです:
# modprobe linear # mdadm --build --verbose /dev/md0 --chunk=16 --level=linear --raid-devices=2 /dev/loop0 /dev/hdaN
作成した /dev/md0
は QEMU の raw ディスクイメージとして使用します (エミュレータがアクセスできるようにパーミッションを設定するのを忘れないでください)。最後にプライマリパーティションの開始位置が /dev/md0
の /dev/hdaN
に一致するようにディスクの設定 (ディスクのジオメトリとパーティションテーブルの設定) を行います (上の例では 16 * 512 = 16384 バイトのオフセットです)。ホストマシンで fdisk
を使って行ってください。エミュレータの中で行ってはいけません: QEMU のデフォルトのディスク認識ルーチンによってキロバイトで割り切れないオフセットが生まれるとソフトウェア RAID コードで管理できなくなります。ホストから以下を実行してください:
# fdisk /dev/md0
X
を押してエキスパートメニューを開きます。トラック毎のセクタ数を設定してシリンダーの容量が MBR ファイルの容量に一致するようにしてください。ヘッダが2つでセクタサイズが512の場合、1トラックあたりのセクタ数は16となり、シリンダのサイズは 2x16x512=16k になります。
R
を押してメインメニューに戻って下さい。
P
を押してシリンダーのサイズが 16k になってることを確認します。
/dev/hdaN
にあわせてシングルプライマリパーティションを作成してください。パーティションの開始位置はシリンダー2で終了位置はディスクの末尾になります (シリンダーの数は fdisk に入力したときの値で変わります)。
最後に、結果をファイルに書き出してください ('w')。これでホストから直接パーティションをディスクイメージとしてマウントすることができます:
$ qemu-system-i386 -hdc /dev/md0 [...]
もちろん、元のパーティション /dev/hdaN
に必要ツールが含まれていれば、QEMU を使ってディスクイメージにブートローダーを設定できます。
nbd-server を使う
リニア RAID を使う代わりに、(nbd パッケージに含まれている) nbd-server
を使って QEMU の MBR ラッパーを作成する方法もあります。
上記のように MBR ラッパーファイルを設定したら、wrapper.img.0
に名前を変更してください。そして同じディレクトリに wrapper.img.1
という名前のシンボリックリンクを作成して、パーティションにリンクするようにしてください。また、同じディレクトリに以下のスクリプトを作成します:
#!/bin/sh dir="$(realpath "$(dirname "$0")")" cat >wrapper.conf <<EOF [generic] allowlist = true listenaddr = 127.713705 port = 10809 [wrap] exportname = $dir/wrapper.img multifile = true EOF nbd-server \ -C wrapper.conf \ -p wrapper.pid \ "$@"
.0
と .1
という拡張子が重要です。他は変えてもかまいません。上記のスクリプトを実行後 (nbd-server がパーティションにアクセスできるように root で実行してください)、以下のコマンドで QEMU を起動できます:
$ qemu-system-i386 -drive file=nbd:127.713705:10809:exportname=wrap [...]
ネットワーク
仮想ネットワークのパフォーマンスはユーザーモードネットワークまたは vde によるよりも tap デバイスやブリッジを用いる方が良いでしょう。tap デバイスやブリッジはカーネル内で実装されているからです。
加えて、デフォルトの e1000 NIC のエミュレーションではなく virtio ネットワークデバイスを仮想マシンに指定することでネットワークのパフォーマンスを向上させることができます。詳しくは #virtio ドライバーのインストール を参照。
リンク層アドレス
QEMU に -net nic
引数を与えると、デフォルトで、仮想マシンにリンク層アドレス 52:54:00:12:34:56
のネットワークインターフェイスが割り当てられます。しかしながら、ブリッジネットワークで複数の仮想マシンを使用する場合、個別の仮想マシンにはタップデバイスの仮想マシン側からそれぞれ固有のリンク層 (MAC) アドレスを設定しなくてはなりません。設定を行わないと、ブリッジが上手く動きません。同一のリンク層アドレスを持つ複数のソースからパケットを受け取ることになるからです。たとえタップデバイス自体に固有のリンク層アドレスを設定していたとしても、ソースのリンク層アドレスはタップデバイスを通過するときに書き換えられないため、問題が発生します。
個々の仮想マシンに固有のリンク層アドレスを設定、それも、どのアドレスも 52:54:
で始まるように設定してください。以下のオプションを使って下さい (X は任意の16進数の数字に置き換えてください):
$ qemu-system-i386 -net nic,macaddr=52:54:XX:XX:XX:XX -net vde disk_image
固有のリンク層アドレスの生成は複数の方法で行うことができます:
1. NIC ごとに固有のリンク層アドレスを手動で指定する。仮想マシンを起動するたびに同じ IP アドレスが DHCP サーバーによって割り当てられるという利点がありますが、仮想マシンが大量にある場合は現実的ではありません。
2. 仮想マシンを起動するたびにランダムなリンク層アドレスを生成する。衝突する可能性はほとんどゼロですが、DHCP サーバーによって割り当てられる IP アドレスが毎回異なるのが欠点です。以下のコマンドをスクリプトで使うことで macaddr
変数にランダムなリンク層アドレスを生成できます:
printf -v macaddr "52:54:%02x:%02x:%02x:%02x" $(( $RANDOM & 0xff)) $(( $RANDOM & 0xff )) $(( $RANDOM & 0xff)) $(( $RANDOM & 0xff )) qemu-system-i386 -net nic,macaddr="$macaddr" -net vde disk_image
3. 以下のスクリプト qemu-mac-hasher.py
を使ってハッシュ関数を利用し仮想マシンの名前からリンク層アドレスを生成する。仮想マシンの名前を一意なものとして、上記の方法の良いところを組み合わせています。スクリプトが実行されるたびに同一のリンク層アドレスが生成される上、衝突する可能性はほとんどありません。
qemu-mac-hasher.py
#!/usr/bin/env python import sys import zlib if len(sys.argv) != 2: print("usage: %s <VM Name>" % sys.argv[0]) sys.exit(1) crc = zlib.crc32(sys.argv[1].encode("utf-8")) & 0xffffffff crc = str(hex(crc))[2:] print("52:54:%s%s:%s%s:%s%s:%s%s" % tuple(crc))
以下のように使うことができます:
vm_name="VM Name" qemu-system-i386 -name "$vm_name" -net nic,macaddr=$(qemu-mac-hasher.py "$vm_name") -net vde disk_image
ユーザーモードネットワーク
デフォルトで、-netdev
引数をつけていないと、QEMU は DHCP サーバーが内蔵されたユーザーモードネットワークを使用します。DHCP クライアントを実行したときに仮想マシンには IP アドレスが与えられ、QEMU による IP マスカレードを通して物理ホストのネットワークにアクセスできるようになります。
ホストがインターネットに接続されていれば、このデフォルトの設定で簡単に仮想マシンをインターネットにアクセスさせることができますが、外部ネットワークからは仮想マシンは直接は見えず、また、複数の仮想マシンを同時に起動していても仮想マシン同士が通信することはできません。
QEMU のユーザーモードネットワークには内蔵の TFTP や SMB サーバー、ゲストを VLAN に追加してゲストの通信を可能にするなどの機能があります。詳しくは -net user
フラグの QEMU ドキュメントを参照してください。
ただし、ユーザーモードネットワークには有用性とパフォーマンスの両方で制約があります。より高度なネットワーク設定をするには tap デバイスや他の方法を使って下さい。
QEMU の Tap ネットワーク
Tap デバイスは Linux カーネルの機能で、本当のネットワークインターフェイスのように見える仮想ネットワークインターフェイスを作成することができます。tap インターフェイスに送られたパケットは、そのインターフェイスに bind された、QEMU などのユーザースペースプログラムに送信されます。
QEMU は仮想マシンで tap ネットワークを利用して、tap インターフェイスに送られたパケットを仮想マシンに送信することで仮想マシンのネットワークインターフェイス (通常は Ethernet インターフェイス) から受け取ったように見せることが可能です。逆に、仮想マシンがネットワークインターフェイスを通して送信したものは全て tap インターフェイスが受け取ります。
Tap デバイスは Linux の bridge ドライバーによってサポートされているため、tap デバイスを互いに、または eth0
といったホストのインターフェイスとブリッジすることができます。これは、仮想マシンを互いに通信できるようにしたい場合や、LAN 上の他のマシンが仮想マシンに通信できるようにしたい場合に価値があります。
ホストオンリーネットワーク
ブリッジに IP アドレスが与えられていてそこへのトラフィックが許可されていながら、本当のインターフェイス (例: eth0
) がブリッジに接続されていない場合、仮想マシンは互いに通信したりホストシステムと通信することができるようになります。しかしながら、物理ホストで IP マスカレードを設定しないかぎり外部ネットワークとは一切通信することができません。この設定は VirtualBox などの他の仮想化ソフトウェアではホストオンリーネットワークと呼ばれています。
内部ネットワーク
ブリッジに IP アドレスを与えずにブリッジへの全てのトラフィックを INPUT チェインで drop する iptables ルールを追加した場合、仮想マシンは互いに通信することはできても、物理ホストや外側のネットワークに接続できなくなります。この設定は VirtualBox などの他の仮想化ソフトウェアでは内部ネットワークと呼ばれています。仮想マシンに固定 IP アドレスを割り当てるかマシンのどれか一つで DHCP サーバーを実行する必要があります。
デフォルトで iptables はブリッジネットワークのパケットを拒否します。ブリッジネットワークのパケットを許可する iptables のツールを使用する必要があります:
# iptables -I FORWARD -m physdev --physdev-is-bridged -j ACCEPT
qemu-bridge-helper を使用するブリッジネットワーク
この方法にはスタートアップスクリプトが必要なく、すぐに複数の tap やブリッジに対応することができます。既存のブリッジに tap デバイスを作成できるようにする、/usr/lib/qemu/qemu-bridge-helper
バイナリを使用します。
まず、/etc/qemu/bridge.conf.sample
を /etc/qemu/bridge.conf
にコピーします。そして /etc/qemu/bridge.conf
を編集して QEMU で使用するブリッジの名前を全て記述します:
/etc/qemu/bridge.conf
allow bridge0 allow bridge1 ...
設定したら VM を起動して下さい。一番基本的な使い方は:
$ qemu-system-i386 -net nic -net bridge,br=bridge0 [...]
tap が複数の場合、追加の NIC 全てに VLAN を指定する必要があります:
$ qemu-system-i386 -net nic -net bridge,br=bridge0 -net nic,vlan=1 -net bridge,vlan=1,br=bridge1 [...]
ブリッジを手動で作成する
以下では仮想マシンを eth0
などのホストインターフェイスにブリッジする方法を説明しています。おそらく一番よく使われている設定です。この設定では、物理的なホストマシンと同一の Ethernet セグメントに、直接外部ネットワークに仮想マシンが位置するようになります。
通常の Ethernet アダプタをブリッジアダプタで置き換えて、通常の Ethernet アダプタをブリッジアダプタに bind することにします。
- ブリッジを制御するための
brctl
が入っている bridge-utils をインストール。
- IPv4 フォワーディングを有効にする:
# sysctl net.ipv4.ip_forward=1
変更を永続的にするために、/etc/sysctl.d/99-sysctl.conf
の net.ipv4.ip_forward = 0
を net.ipv4.ip_forward = 1
に変えます。
tun
モジュールをロードして起動時にロードするように設定してください。詳しくはカーネルモジュールを参照。
- ブリッジを作成します。詳しくは netctl でブリッジ接続を見て下さい。ブリッジの名前を
br0
にするか、下のスクリプトを使用するブリッジの名前に忘れずに変更してください。
- QEMU 用に
root:kvm
750 パーミッションで tap アダプタを立ち上げるスクリプトを作成:
/etc/qemu-ifup
#!/bin/sh echo "Executing /etc/qemu-ifup" echo "Bringing up $1 for bridged mode..." sudo /usr/bin/ip link set $1 up promisc on echo "Adding $1 to br0..." sudo /usr/bin/brctl addif br0 $1 sleep 2
- QEMU 用に
root:kvm
750 パーミッションで/etc/qemu-ifdown
の tap アダプタを落とすスクリプトを作成:
/etc/qemu-ifdown
#!/bin/sh echo "Executing /etc/qemu-ifdown" sudo /usr/bin/ip link set $1 down sudo /usr/bin/brctl delif br0 $1 sudo /usr/bin/ip link delete dev $1
visudo
を使ってsudoers
ファイルに以下を追加します:
Cmnd_Alias QEMU=/usr/bin/ip,/usr/bin/modprobe,/usr/bin/brctl %kvm ALL=NOPASSWD: QEMU
- 以下の
run-qemu
スクリプトを使って QEMU を起動します:
run-qemu
#!/bin/bash USERID=$(whoami) # Get name of newly created TAP device; see https://bbs.archlinux.org/viewtopic.php?pid=1285079#p1285079 precreationg=$(/usr/bin/ip tuntap list | /usr/bin/cut -d: -f1 | /usr/bin/sort) sudo /usr/bin/ip tuntap add user $USERID mode tap postcreation=$(/usr/bin/ip tuntap list | /usr/bin/cut -d: -f1 | /usr/bin/sort) IFACE=$(comm -13 <(echo "$precreationg") <(echo "$postcreation")) # This line creates a random MAC address. The downside is the DHCP server will assign a different IP address each time printf -v macaddr "52:54:%02x:%02x:%02x:%02x" $(( $RANDOM & 0xff)) $(( $RANDOM & 0xff )) $(( $RANDOM & 0xff)) $(( $RANDOM & 0xff )) # Instead, uncomment and edit this line to set a static MAC address. The benefit is that the DHCP server will assign the same IP address. # macaddr='52:54:be:36:42:a9' qemu-system-i386 -net nic,macaddr=$macaddr -net tap,ifname="$IFACE" $* sudo ip link set dev $IFACE down &> /dev/null sudo ip tuntap del $IFACE mode tap &> /dev/null
それから VM を起動するために、以下のようにコマンドを実行して下さい:
$ run-qemu -hda myvm.img -m 512 -vga std
- パフォーマンスとセキュリティ上の理由でブリッジのファイアウォールは無効化するのが推奨されています [1]:
/etc/sysctl.d/10-disable-firewall-on-bridge.conf
net.bridge.bridge-nf-call-ip6tables = 0 net.bridge.bridge-nf-call-iptables = 0 net.bridge.bridge-nf-call-arptables = 0
すぐに変更を適用するには sysctl -p /etc/sysctl.d/10-disable-firewall-on-bridge.conf
を実行してください。
libvirt wiki や Fedora bug 512206 を参照。起動中にファイルが存在しないというエラーが起こるときは、起動時に bridge
モジュールをロードするようにしてください。カーネルモジュール#ロード を参照。
または、次のようにルールを追加することで全てのトラフィックをブリッジで通すように iptables を設定することができます:
-I FORWARD -m physdev --physdev-is-bridged -j ACCEPT
VDE2 によるネットワーク
VDE とは?
VDE は Virtual Distributed Ethernet の略です。uml_switch の拡張として始まりました。仮想ネットワークを管理するためのツールボックスです。
基本的にはソケットである仮想スイッチを作成して、物理マシンと仮想マシンを両方ともスイッチに"接続"するという考えになります。以下で説明する設定はとてもシンプルです。ただし、VDE はさらに強力な力を持っており、仮想スイッチ同士を接続したり、別のホストでスイッチを動作させスイッチのトラフィックを監視することなどができます。プロジェクトのドキュメント を読むことを推奨。
この方法の利点はユーザーに sudo 権限を与える必要がないということです。通常ユーザーに modprobe の実行を許可する必要はありません。
基本
VDE サポートは vde2 パッケージでインストールできます。
この設定では、tun/tap を使ってホストに仮想インターフェイスを作成します。tun
モジュールをロード (詳しくはカーネルモジュールを参照):
# modprobe tun
仮想スイッチを作成:
# vde_switch -tap tap0 -daemon -mod 660 -group users
上記のコマンドでスイッチと tap0
が作成され、接続され、そして users
グループのユーザーがスイッチを使えるようにします。
インターフェイスは接続されてもまだ設定がされていません。設定するには、次のコマンドを実行:
# ip addr add 192.168.100.254/24 dev tap0
そして、通常ユーザーで -net
オプションを使って KVM を実行してください:
$ qemu-system-i386 -net nic -net vde -hda [...]
物理ネットワークでやるのと同じようにゲストのネットワークを設定してください。
起動スクリプト
VDE を起動するメインスクリプトの例:
/etc/systemd/scripts/qemu-network-env
#!/bin/sh # QEMU/VDE network environment preparation script # The IP configuration for the tap device that will be used for # the virtual machine network: TAP_DEV=tap0 TAP_IP=192.168.100.254 TAP_MASK=24 TAP_NETWORK=192.168.100.0 # Host interface NIC=eth0 case "$1" in start) echo -n "Starting VDE network for QEMU: " # If you want tun kernel module to be loaded by script uncomment here #modprobe tun 2>/dev/null ## Wait for the module to be loaded #while ! lsmod | grep -q "^tun"; do echo "Waiting for tun device"; sleep 1; done # Start tap switch vde_switch -tap "$TAP_DEV" -daemon -mod 660 -group users # Bring tap interface up ip address add "$TAP_IP"/"$TAP_MASK" dev "$TAP_DEV" ip link set "$TAP_DEV" up # Start IP Forwarding echo "1" > /proc/sys/net/ipv4/ip_forward iptables -t nat -A POSTROUTING -s "$TAP_NETWORK"/"$TAP_MASK" -o "$NIC" -j MASQUERADE ;; stop) echo -n "Stopping VDE network for QEMU: " # Delete the NAT rules iptables -t nat -D POSTROUTING "$TAP_NETWORK"/"$TAP_MASK" -o "$NIC" -j MASQUERADE # Bring tap interface down ip link set "$TAP_DEV" down # Kill VDE switch pgrep -f vde_switch | xargs kill -TERM ;; restart|reload) $0 stop sleep 1 $0 start ;; *) echo "Usage: $0 {start|stop|restart|reload}" exit 1 esac exit 0
上のスクリプトを使う systemd サービスの例:
/etc/systemd/system/qemu-network-env.service
[Unit] Description=Manage VDE Switch [Service] Type=oneshot ExecStart=/etc/systemd/scripts/qemu-network-env start ExecStop=/etc/systemd/scripts/qemu-network-env stop RemainAfterExit=yes [Install] WantedBy=multi-user.target
qemu-network-env
が実行できるようにパーミッションを変更:
# chmod u+x /etc/systemd/scripts/qemu-network-env
通常の方法で起動することができます (詳しくは systemd#ユニットを使う を参照):
# systemctl start qemu-network-env
他の方法
上の方法が動作しない場合やカーネル設定, TUN, dnsmasq, iptables を変えたくない場合は以下のコマンドで同じ結果になります。
# vde_switch -daemon -mod 660 -group users # slirpvde --dhcp --daemon
ホストのネットワークの接続を使って VM を起動するには:
$ qemu-system-i386 -net nic,macaddr=52:54:00:00:EE:03 -net vde disk_image
VDE2 Bridge
quickhowto: qemu networking using vde, tun/tap, and bridge に基づいています。vde に接続された仮想マシンは外部から参照出来る状態になります。例えば、ADSL ルーターから直接 DHCP の設定を個々の仮想マシンが受け取ることが可能です。
基本
tun
モジュールと bridge-utils パッケージが必要です。
vde2/tap デバイスを作成:
# vde_switch -tap tap0 -daemon -mod 660 -group users # ip link set tap0 up
ブリッジを作成:
# brctl addbr br0
デバイスを追加:
# brctl addif br0 eth0 # brctl addif br0 tap0
ブリッジインターフェイスを設定:
# dhcpcd br0
起動スクリプト
全てのデバイスを設定する必要があります。ブリッジに必要なのは IP アドレスだけです。ブリッジの物理デバイスは (例: eth0
)、netctl でカスタム Ethernet プロファイルを使います:
/etc/netctl/ethernet-noip
Description='A more versatile static Ethernet connection' Interface=eth0 Connection=ethernet IP=no
以下のカスタム systemd サービスを使うことで users
ユーザーグループで使用する VDE2 tap インターフェイスを作成することができます。
/etc/systemd/system/vde2@.service
[Unit] Description=Network Connectivity for %i Wants=network.target Before=network.target [Service] Type=oneshot RemainAfterExit=yes ExecStart=/usr/bin/vde_switch -tap %i -daemon -mod 660 -group users ExecStart=/usr/bin/ip link set dev %i up ExecStop=/usr/bin/ip addr flush dev %i ExecStop=/usr/bin/ip link set dev %i down [Install] WantedBy=multi-user.target
そして最後に、netctl でブリッジネットワークを作成することが可能です。
グラフィック
QEMU は様々なグラフィック出力を使うことができます: std
, qxl
, vmware
, virtio
, cirrus
, none
。
std
-vga std
では 2560 x 1600 ピクセルまでの解像度を得ることができます。QEMU 2.2 からデフォルトとなっています。
qxl
QXL は 2D サポートのある準仮想化グラフィックドライバーです。使用するには -vga qxl
オプションを使用してゲストにドライバーをインストールしてください。QXL を使用する場合 SPICE を使うことでグラフィックの性能を向上させることができます。
Linux ゲストでは、パフォーマンスを得るために qxl
と bochs_drm
カーネルモジュールをロードしてください。
SPICE
Spice プロジェクト は仮想化されたデスクトップデバイスを操作するための完全な、オープンソースのソリューションを提供することを目的としています。主として QEMU 仮想マシンへの高品質なリモートアクセスを提供することに力を注いでいます。
グラフィック出力に QXL を使用している場合にのみ SPICE を利用できます。
リモートデスクトッププロトコルとして SPICE を使用して起動するコマンドの例:
$ qemu-system-i386 -vga qxl -spice port=5930,disable-ticketing -device virtio-serial-pci -device virtserialport,chardev=spicechannel0,name=com.redhat.spice.0 -chardev spicevmc,id=spicechannel0,name=vdagent
それから SPICE クライアントでゲストに接続してください。現在は spice-gtk3 が推奨されていますが、他のクライアントも利用できます [2]:
$ spicy -h 127.0.0.1 -p 5930
TCP ポートの代わりに Unix ソケットを使用することで、パフォーマンスが向上するという報告があります [3]。例:
$ qemu-system-x86_64 -vga qxl -device virtio-serial-pci -device virtserialport,chardev=spicechannel0,name=com.redhat.spice.0 -chardev spicevmc,id=spicechannel0,name=vdagent -spice unix,addr=/tmp/vm_spice.socket,disable-ticketing $ spicy --uri="spice+unix:///tmp/vm_spice.socket"
マルチモニターやクリップボードの共有などのサポートが必要な場合、以下のパッケージをゲスト側でインストールしてください:
- spice-vdagent: クライアントと X セッションの間でコピーアンドペーストを可能にする Spice エージェント
- xf86-video-qxlAUR xf86-video-qxl-gitAUR: Xorg の X11 qxl ビデオドライバー
- 他のオペレーティングシステムの場合、SPICE-Space ダウンロード ページのゲストセクションを見てください。
SPICE によるパスワード認証
SPICE のパスワード認証を有効にしたい場合、-spice
引数から disable-ticketing
を外して password=yourpassword
を追加してください。例:
$ qemu-system-x86_64 -vga qxl -spice port=5900,password=yourpassword -device virtio-serial-pci -device virtserialport,chardev=spicechannel0,name=com.redhat.spice.0 -chardev spicevmc,id=spicechannel0,name=vdagent
SPICE サーバーに接続する際に SPICE クライアントがパスワードを要求するようになります。
TLS 暗号化
SPICE サーバーとの通信を TLS で暗号化するよう設定することもできます。まず、以下のファイルが含まれたディレクトリが必要です (ファイルの名前は完全に一致している必要があります):
ca-cert.pem
: CA マスター証明書。server-cert.pem
:ca-cert.pem
で署名されたサーバー証明書。server-key.pem
: サーバー秘密鍵。
サーバー自身の CA で自己署名証明書を生成する方法は Spice User Manual に例が載っています。
証明書を用意したら -spice
引数を使って SPICE で QEMU を起動してください: -spice tls-port=5901,password=yourpassword,x509-dir=/path/to/pki_certs
(/path/to/pki_certs
は証明書が含まれているディレクトリのパスに置き換えてください)。
起動したら spice-gtk3 を使ってサーバーに接続することが可能です:
$ spicy -h hostname -s 5901 --spice-ca-file=ca-cert.pem --spice-host-subject="C=XX,L=city,O=organization,CN=hostname" --spice-secure-channels=all
--spice-host-subject
パラメータは server-cert.pem
のサブジェクトにあわせて設定する必要があります。また、サーバー証明書を検証するために ca-cert.pem
をクライアントにコピーしてください。
virt-viewer を使用する場合:
$ remote-viewer spice://hostname?tls-port=5901 --spice-ca-file=/path/to/ca-cert.pem --spice-host-subject="C=XX,L=city,O=organization,CN=hostname" --spice-secure-channels=all
vmware
多少バグが存在しますが、std や cirrus よりもパフォーマンスが上です。ゲストに、VMware ドライバーをインストールしてください (Arch Linux ゲストなら xf86-video-vmware と xf86-input-vmmouse)。
virtio
virtio-vga
/ virtio-gpu
は virgl がベースの順仮想化 3D グラフィックドライバーです。発展途上であり、カーネルバージョンが新しい (4.4 以上) Linux ゲストで --with-gallium-drivers=virgl
オプションを付けてコンパイルされた mesa (>=11.2) でしか動作しません。
ゲスト環境で 3D アクセラレーションを有効にするには -vga virtio
を使って vga を選択して -display sdl,gl=on
(sdl ディスプレイ出力) または -display gtk,gl=on
(gtk ディスプレイ出力) を使用してディスプレイデバイスで opengl コンテキストを有効にしてください。ゲスト側のカーネルログを見ることで設定が問題ないか確認できます:
$ dmesg | grep drm
[drm] pci: virtio-vga detected [drm] virgl 3d acceleration enabled
2016年9月現在、spice プロトコルのサポートは開発中で、spice (>= 0.13.2) の開発版をインストールして qemu を再コンパイルすることでテストできます。
詳しくは kraxel のブログ を見てください。
cirrus
cirrus グラフィカルアダプタは 2.2 以前まではデフォルト でした。新しいシステムでは 使用しないほうがよい とされています。
none
これは VGA カードが全くない PC と同じようになります。-vnc
オプションを使ってもアクセスすることはできません。また、QEMU に VGA カードをエミュレートさせ SDL ディスプレイを無効にする -nographic
オプションとは異なります。
vnc
-nographic
オプションを使っている場合、-vnc display
オプションを追加することで QEMU に display
を listen させて VGA ディスプレイを VNC セッションにリダイレクトさせることができます。#ブート時に QEMU 仮想マシンを起動する セクションの設定例にこれのサンプルがあります。
$ qemu-system-i386 -vga std -nographic -vnc :0 $ gvncviewer :0
VNC を使う際、ここで示されているようなキーボードの問題が発生するかもしれません。解決方法は、QEMU で -k
オプションを使わないことと、gtk-vnc の gvncviewer
を使うことです。libvirt のメーリングリストに投稿された この メッセージも参照してください。
オーディオ
ホスト
QEMU で使用するオーディオドライバーは QEMU_AUDIO_DRV
環境変数で設定できます:
$ export QEMU_AUDIO_DRV=pa
以下のコマンドを実行すると PulseAudio に関する QEMU の設定オプションが表示されます:
$ qemu-system-x86_64 -audio-help | awk '/Name: pa/' RS=
表示されたオプションは以下のように環境変数としてエクスポートできます:
$ export QEMU_PA_SINK=alsa_output.pci-0000_04_01.0.analog-stereo.monitor $ export QEMU_PA_SOURCE=input
ゲスト
使用できるエミュレーションオーディオドライバーのリストを表示するには:
$ qemu-system-x86_64 -soundhw help
例えば、ゲストで hda
ドライバーを使用するには -soundhw hda
を使ってください。
virtio ドライバーのインストール
QEMU にで virtio ドライバーを使って準仮想化ブロックとネットワークデバイスをゲストが利用できるようにすることができ、より良いパフォーマンス・少ないオーバーヘッドを実現します。
- virtio ブロックデバイスにはシンプルな
-hd*
の代わりに-drive
オプションとif=virtio
が必要です:
$ qemu-system-i386 -boot order=c -drive file=disk_image,if=virtio
- ネットワークでもほぼ同じです:
$ qemu-system-i386 -net nic,model=virtio
(Arch) Linux ゲストを用意する
Arch Linux ゲストをインストールした後 virtio デバイスを使うには、次のモジュールをゲストでロードする必要があります: virtio
, virtio_pci
, virtio_blk
, virtio_net
, virtio_ring
。32ビットのゲストの場合、特定の "virtio" モジュールは必要ありません。
virtio ディスクから起動したい場合、イニシャル RAM ディスクに必要なモジュールを含ませなければなりません。デフォルトでは、mkinitcpio の autodetect
フックによって管理されています。もしくは /etc/mkinitcpio.conf
の MODULES
行を使って必要なモジュールを含めてイニシャル RAM ディスクをリビルドしてください。
/etc/mkinitcpio.conf
MODULES="virtio virtio_blk virtio_pci virtio_net"
Virtio ディスクは前に v
が付いて認識されます (例: vda
, vdb
など)。なので、virtio ディスクから起動する際は /etc/fstab
や /boot/grub/grub.cfg
などに変更を加える必要があります。
KVM による準仮想化に関する詳細は こちら で読むことができます。
qemu-guest-agent をインストールすることでハイパーバイザーの管理機能を拡張する QMP コマンドのサポートを得ることができます。パッケージをインストールしたら qemu-ga.service
を起動・有効化してください。
Windows ゲストを用意する
ブロックデバイスドライバー
virtio ディスクから起動するように Windows ゲストを用意するのはやや面倒です。
Fedora のリポジトリ から virtio ディスクドライバーをダウンロードすることができます。
そして Windows がドライバーを検索するように、新しいディスクイメージを作成する必要があります。例:
$ qemu-img create -f qcow2 fake.qcow2 1G
(virtio モードの) フェイクディスクと CD-ROM とドライバーで元の Windows ゲストを起動 (ブートディスクを IDE モードで使う):
$ qemu-system-i386 -m 512 -vga std -drive file=windows_disk_image,if=ide -drive file=fake.qcow2,if=virtio -cdrom virtio-win-0.1-81.iso
Windows はフェイクディスクを検出してそのドライバーを検索します。ドライバーが見つからない場合は、Device Manager を開いて、エクスクラメーションマークのアイコンが付いた SCSI ドライブを探して (開いて下さい)、Update driver をクリックして仮想 CD-ROM を選択してください。ディレクトリを再帰的に検索すると書かれたチェックボックスを選択するのを忘れずに。
インストールが成功したら、仮想マシンを止めて virtio モードのブートディスクで再起動することができます:
$ qemu-system-i386 -m 512 -vga std -drive file=windows_disk_image,if=virtio
ネットワークドライバー
virtio ネットワークドライバーのインストールはもう少し簡単で、上記に -net
引数を追加します:
$ qemu-system-i386 -m 512 -vga std -drive file=windows_disk_image,if=virtio -net nic,model=virtio -cdrom virtio-win-0.1-74.iso
Windows はネットワークアダプタを検出してそのドライバーを検索します。ドライバーが見つからない場合は、Device Manager を開いて、エクスクラメーションマークのアイコンが付いたネットワークアダプタを探して (開いて下さい)、Update driver をクリックして仮想 CD-ROM を選択してください。ディレクトリを再帰的に検索すると書かれたチェックボックスを選択するのを忘れずに。
FreeBSD ゲストを用意する
FreeBSD 8.3 以降を使っている場合は emulators/virtio-kmod
port をインストールしてください、10.0-CURRENT ではカーネルに含まれています。インストール後、/boot/loader.conf
ファイルに以下を追加します:
virtio_loader="YES" virtio_pci_load="YES" virtio_blk_load="YES" if_vtnet_load="YES" virtio_balloon_load="YES"
そして次を実行して /etc/fstab
を修正してください:
sed -i bak "s/ada/vtbd/g" /etc/fstab
それから /etc/fstab
が問題ないか確認してください。何かがおかしい場合、レスキュー CD で起動して /etc/fstab.bak
を /etc/fstab
にコピーします。
Tips and tricks
ブート時に QEMU 仮想マシンを起動する
libvirt を使う
libvirt を使って仮想マシンをセットアップした場合、virsh autostart
や virt-manager の GUI を通して、仮想マシンの Boot Options から "Start virtual machine on host boot up" を選択することでホストの起動時に仮想マシンを起動するように設定することができます。
カスタムスクリプト
起動時に QEMU VM を実行するように、以下の systemd ユニットと設定を使うことができます。
/etc/systemd/system/qemu@.service
[Unit] Description=QEMU virtual machine [Service] Environment="type=system-x86_64" "haltcmd=kill -INT $MAINPID" EnvironmentFile=/etc/conf.d/qemu.d/%i ExecStart=/usr/bin/env qemu-${type} -name %i -nographic $args ExecStop=/bin/sh -c ${haltcmd} TimeoutStopSec=30 KillMode=none [Install] WantedBy=multi-user.target
VM ごとに、/etc/conf.d/qemu.d/vm_name
という名前の設定ファイルを作成して、以下の変数を設定します:
- type
- 実行する QEMU バイナリ。指定すれば、
/usr/bin/qemu-
が前に付けられて VM を起動するのにそのバイナリが使われます。例えばtype="system-arm"
でqemu-system-arm
イメージが起動できます。 - args
- 起動するときの QEMU コマンドライン。
-name ${vm} -nographic
はいつも前に付けます。 - haltcmd
- VM を安全にシャットダウンするためのコマンド。例えば
-monitor telnet:..
を使ってモニターにsystem_powerdown
を送信して ACPI で VM の電源を切ります。SSH やその他の方法が使えます。
設定例:
/etc/conf.d/qemu.d/one
type="system-x86_64" args="-enable-kvm -m 512 -hda /dev/mapper/vg0-vm1 -net nic,macaddr=DE:AD:BE:EF:E0:00 \ -net tap,ifname=tap0 -serial telnet:localhost:7000,server,nowait,nodelay \ -monitor telnet:localhost:7100,server,nowait,nodelay -vnc :0" haltcmd="echo 'system_powerdown' | nc localhost 7100" # or netcat/ncat # You can use other ways to shut down your VM correctly #haltcmd="ssh powermanager@vm1 sudo poweroff"
/etc/conf.d/qemu.d/two
args="-enable-kvm -m 512 -hda /srv/kvm/vm2.img -net nic,macaddr=DE:AD:BE:EF:E0:01 \ -net tap,ifname=tap1 -serial telnet:localhost:7001,server,nowait,nodelay \ -monitor telnet:localhost:7101,server,nowait,nodelay -vnc :1" haltcmd="echo 'system_powerdown' | nc localhost 7101"
以下のコマンドを使って、ブート時にそれぞれの仮想マシンが起動するように設定します:
# systemctl enable qemu@vm_name # systemctl disable qemu@vm_name
シームレスなマウス
ゲストのオペレーティングシステムのウィンドウをクリックしたときにマウスが取り込まれないようにするには、-usbdevice tablet
オプションを追加します。これによって QEMU はマウスを取り込むことなくマウスの位置を伝えることができるようになります。また、このコマンドは有効化されている場合 PS/2 マウスエミュレーションを上書きします。例:
$ qemu-system-i386 -hda disk_image -m 512 -vga std -usbdevice tablet
上のコマンドで動作しない場合は、#マウスカーソルが敏感すぎたり迷走する を参照してみて下さい。
ホスト USB デバイスのパススルー
VM からホストに接続された物理 USB デバイスにアクセスするために、以下のオプションを使って QEMU を起動することができます:
$ qemu-system-i386 -usbdevice host:vendor_id:product_id disk_image
lsusb
コマンドでデバイスの vendor_id
と product_id
がわかります。
デフォルトで qemu によってエミュレートされる I440FX チップセットはシングル UHCI コントローラ (USB 1) のため、-usbdevice
オプションは物理デバイスを USB 1 にアタッチしますが新しいデバイスでは場合によっては問題が発生することがあります。-machine type=q35
オプションを使って12個までのデバイスをサポートする EHCI コントローラを提供する ICH9 チップセットをエミュレートさせることで解決します。
-device usb-ehci,id=ehci
や -device nec-usb-xhci,id=xhci
オプションを使って EHCI (USB 2) または XHCI (USB 3) コントローラをエミュレートして以下のように -device usb-host,..
オプションを使って物理デバイスにアタッチするという方法もあります:
-device usb-host,bus=controller_id.0,vendorid=0xvendor_id,productid=0xproduct_id
...,port=<n>
設定を追加することで仮想コントローラの物理ポートを指定することができます。複数の USB デバイスを VM に追加したい場合に有用です。
SPICE による USB リダイレクト
SPICE を使用しているのであれば、QEMU コマンドで指定しなくてもクライアントから仮想マシンに USB デバイスをリダイレクトすることが可能です。USB スロットの数を設定することができます (スロットの数によって同時にリダイレクトできるデバイスの最大数が決まります)。-usbdevice
を使用する方法と違って SPICE でリダイレクトする場合は仮想マシンを起動した後に USB デバイスをホットスワップすることができ、リダイレクトから USB デバイスを削除・追加するのに仮想マシンを停止する必要がありません。また、ネットワーク経由でクライアントからサーバーに USB デバイスをリダイレクトすることもできます。QEMU 仮想マシンで USB デバイスを最大限に活用することが可能です。
使用するには USB リダイレクトスロットにそれぞれ EHCI/UHCI コントローラーと SPICE リダイレクトチャンネルを追加する必要があります。例えば、3つの USB スロットをリダイレクトで使用できるように SPICE モードで仮想マシンを起動するには QEMU コマンドに以下の引数を追加します:
-device ich9-usb-ehci1,id=usb \ -device ich9-usb-uhci1,masterbus=usb.0,firstport=0,multifunction=on \ -device ich9-usb-uhci2,masterbus=usb.0,firstport=2 \ -device ich9-usb-uhci3,masterbus=usb.0,firstport=4 \ -chardev spicevmc,name=usbredir,id=usbredirchardev1 \ -device usb-redir,chardev=usbredirchardev1,id=usbredirdev1 \ -chardev spicevmc,name=usbredir,id=usbredirchardev2 \ -device usb-redir,chardev=usbredirchardev2,id=usbredirdev2 \ -chardev spicevmc,name=usbredir,id=usbredirchardev3 \ -device usb-redir,chardev=usbredirchardev3,id=usbredirdev3
spice-gtk3 の spicy
(Input > Select USB Devices for redirection) と virt-viewer の remote-viewer
(File > USB device selection) の両方ともリダイレクト機能をサポートしています。期待通りに動作させるには仮想マシンに SPICE ゲストツールをインストールする必要があります (詳しくは #SPICE セクションを参照してください)。
KSM を有効にする
Kernel Samepage Merging (KSM) はアプリケーションがページをマージするように登録した他のプロセスとページをマージするようにカーネルに登録できるようにする Linux カーネルの機能です。この KSM 機構によってゲストの仮想マシンは互いにページを共有することが可能になります。同じようなゲストオペレーティングシステムが多数動作する環境では、メモリの使用量を著しく節約することができます。
KSM を有効にするには、次を実行してください:
# echo 1 > /sys/kernel/mm/ksm/run
systemd の一時ファイルを使って KSM を永続的に有効にできます:
/etc/tmpfiles.d/ksm.conf
w /sys/kernel/mm/ksm/run - - - - 1
KSM が動作しているとき、マージされるページが存在するために (つまり少なくとも2つの同じような VM が動いている)、/sys/kernel/mm/ksm/pages_shared
はゼロになりません。詳しくは https://www.kernel.org/doc/Documentation/vm/ksm.txt を参照。
マルチモニターのサポート
Linux QXL ドライバーはデフォルトで4台までのマルチモニター (仮想スクリーン) をサポートしています。qxl.heads=N
カーネルパラメータで変更することができます。
QXL デバイスのデフォルトの VGA メモリサイズは 16M です (VRAM のサイズは 64M です)。1920x1200 のモニターを2台使用しようとすると 2 × 1920 × 4 (色深度) × 1200 = 17.6 MiB の VGA メモリが必要になるためメモリが不足します。-vga qxl
を -vga none -device qxl-vga,vgamem_mb=32
に置き換えることでメモリ容量を変更できます。vgamem_mb を 64M 以上に増やした場合、vram_size_mb
オプションも増やす必要があります。
コピーアンドペースト
ホストとゲスト間のコピーアンドペーストを行うには spice エージェント通信チャンネルを有効にする必要があります。それには virtio-serial デバイスをゲストに追加して、spice vdagent のためにポートを開かなければなりません。また、ゲストへの spice vdagent のインストールも必須です (Arch ゲストの場合は spice-vdagent、Windows ゲストの場合は Windows ゲストツール)。エージェントが動いていること (さらに、今後のために、自動で起動すること) を確認してください。
QEMU を次のオプションを使って起動します:
$ qemu-system-i386 -vga qxl -spice port=5930,disable-ticketing -device virtio-serial-pci -device virtserialport,chardev=spicechannel0,name=com.redhat.spice.0 -chardev spicevmc,id=spicechannel0,name=vdagent
-device virtio-serial-pci
オプションが virtio-serial デバイスを追加し、-device virtserialport,chardev=spicechannel0,name=com.redhat.spice.0
がデバイスの spice vdagent のポートを開いて、-chardev spicevmc,id=spicechannel0,name=vdagent
でそのポートに spicevmc chardev を追加します。
chardev
オプションの id=
オプションと、virtserialport
デバイスの chardev=
オプションは一致していなければなりません (この例では spicechannel0
)。ポートの名前が com.redhat.spice.0
であることも重要です、これが vdagent がゲストで探す名前空間だからです。そして、name=vdagent
を指定することで spice がこのチャンネルが何のためなのか知ることができます。
Windows 特有のノート
QEMU は Windows 95 から Windows 10 まで全てのバージョンの Windows を動かすことができます。
QEMU で Windows PE を実行することも可能です。
高速スタートアップ
Windows 8 (あるいはそれ移行) をゲストにする場合、コントロールパネルの電源オプションから"高速スタートアップ"を無効にしないと、起動時にゲストがフリーズすることがあります。
-smp
オプションを正しく適用するために高速スタートアップを無効化しなくてはならないこともあります。
Remote Desktop Protocol
MS Windows ゲストを使っている場合、RDP を使ってゲスト VM に接続する方法もあります。VLAN を使用してしてゲストが同じネットワークにない場合、次を使って下さい:
$ qemu-system-i386 -nographic -net user,hostfwd=tcp::5555-:3389
そして Rdesktop か freerdp を使ってゲストに接続してください。例えば:
$ xfreerdp -g 2048x1152 localhost:5555 -z -x lan
トラブルシューティング
仮想マシンの動作が遅すぎる
仮想マシンのパフォーマンスを向上させることができる多数のテクニックがあります。例えば:
-cpu host
オプションを使うことで QEMU にホストの CPU を正確にエミュレートさせることができます。このオプションを使わない場合、もっと一般的な CPU がエミュレートされます。- Windows ゲストの場合、Hyper-V enlightenments を有効にしてください:
-cpu host,hv_relaxed,hv_spinlocks=0x1fff,hv_vapic,hv_time
。 - ホストマシンに CPU が複数ある場合は、
-smp
オプションを使ってゲストにもっと多くの CPU を割り当てて下さい。 - 仮想マシンに十分なメモリを割り当てているか確認してください。デフォルトでは、QEMU はそれぞれの仮想マシンに 128 MiB のメモリしか割り当てません。
-m
オプションを使って多めのメモリを割り当てて下さい。例えば、-m 1024
で仮想マシンは 1024 MiB のメモリを使って動作します。 - 可能な限り KVM を使って下さい: QEMU の起動コマンドに
-machine type=pc,accel=kvm
を追加します。 - ゲストのオペレーティングシステムのドライバーによってサポートされているときは、ネットワークやブロックデバイスに virtio を使って下さい。例えば:
$ qemu-system-i386 -net nic,model=virtio -net tap,if=tap0,script=no -drive file=disk_image,media=disk,if=virtio
- ユーザーモードネットワークの代わりに TAP デバイスを使って下さい。#QEMU の Tap ネットワーク を参照。
- ゲスト OS がディスクへの書き込みを頻繁に行う場合、ホストのファイルシステムで特定のマウントオプションを使うと良いかもしれません。例えば、ext4 ファイルシステム を
barrier=0
オプションでマウントすることが考えられます。ファイルシステムのパフォーマンスを向上させるオプションは、場合によってデータの保全性を犠牲にする可能性があるので、変更するオプションのドキュメントを読んでおいたほうが無難です。 - raw ディスクイメージを使っている場合、キャッシュを無効にする:
$ qemu-system-i386 -drive file=disk_image,if=virtio,cache=none
- ネイティブの Linux AIO を使用する:
$ qemu-system-i386 -drive file=disk_image,if=virtio,aio=native
- qcow2 ディスクイメージを使用している場合、十分な容量の L2 キャッシュを割り当てることで I/O の性能が著しく改善することがあります。L2 キャッシュを計算するときの 公式 は: l2_cache_size = disk_size * 8 / cluster_size です。デフォルトのクラスタサイズ 64K で、容量 8 GB の qcow2 イメージを作成した場合、最適な L2 キャッシュは 1 MB となります。QEMU はデフォルトでは 1 MB しか L2 キャッシュを使用しません。QEMU のコマンドラインでキャッシュの容量を指定することができます。例えば使用するキャッシュを 4 MB にするには:
$ qemu-system-i386 -drive file=disk_image,format=qcow2,l2-cache-size=4M
- 複数の仮想マシンを同時に動かしていて、全て同じオペレーティングシステムをインストールしている場合、kernel same-page merging を有効にすることでメモリを節約できます。#KSM を有効にするを見てください。
- 場合によっては、ゲストのオペレーティングシステムでメモリバルーニングドライバーを実行して QEMU を
-balloon virtio
オプションで起動することで、実行中の仮想マシンからメモリを回収することができます。
詳しくは http://www.linux-kvm.org/page/Tuning_KVM を参照してください。
マウスカーソルが敏感すぎたり迷走する
カーソルが画面を飛び回って手に負えない場合、QEMU を起動する前にターミナルに次を入力することで直るかもしれません:
$ export SDL_VIDEO_X11_DGAMOUSE=0
このコマンドで直ったら、~/.bashrc
ファイルにコマンドを追加することができます。
カーソルが表示されない
マウスカーソルを表示するには -show-cursor
を QEMU のオプションに追加してください。
オプションを追加しても表示されない場合、ディスプレイデバイスが正しく設定されているか確認してください。例: -vga qxl
。
カーソルが移動・アタッチできない
QEMU オプションの -usbdevice tablet
を -usb
に置き換えてください。
キーボードが壊れているまたは矢印キーが動作しない
キーの一部が動かなかったり間違ったキーが押されてしまう (特に矢印キー) ときは、おそらくキーボードレイアウトをオプションとして指定する必要があります。キーボードレイアウトは /usr/share/qemu/keymaps
で探すことができます。
$ qemu-system-i386 -k keymap disk_image
QEMU v2.8.0 のバグ が原因で、Wayland セッションでは手動でキーマップを設定しても方向キーが使えないことがあります。マスターブランチでは修正されているため qemu-gitAUR をインストールすれば解決します。
ウィンドウのリサイズでゲストのディスプレイが引き伸ばされる
デフォルトのウィンドウサイズに戻すには、Ctrl+Alt+u
を押して下さい。
ioctl(KVM_CREATE_VM) failed: 16 Device or resource busy
-enable-kvm
オプションを使って QEMU を起動した時に以下のようなエラーメッセージが表示される場合:
ioctl(KVM_CREATE_VM) failed: 16 Device or resource busy failed to initialize KVM: Device or resource busy
他のハイパーバイザーが動作しています。同時に複数のハイパーバイザーを動かすのは推奨されていません、もしくは不可能です。
libgfapi エラーメッセージ
起動時に以下のエラーメッセージが表示される場合:
Failed to open module: libgfapi.so.0: cannot open shared object file: No such file or directory
任意の依存パッケージである GlusterFS が存在しないというだけなので無視して問題ありません。glusterfs パッケージをインストールすれば消えます。
ライブ環境でカーネルパニックが発生する
ライブ環境を起動した場合に以下が発生する場合:
[ end Kernel panic - not syncing: VFS: Unable to mount root fs on unknown block(0,0)
-m VALUE
スイッチを付けて適当な量の RAM を指定して VM を起動してみてください。RAM が足りなくなると上記のような問題が発生することがあります。
Windows 7 ゲストの音質が酷い
Windows 7 ゲストで hda
オーディオドライバーを使用すると音質に問題が発生することがあります。QEMU の引数に -soundhw ac97
を指定してオーディオドライバーを ac97
に変更し、ゲストに Realtek AC'97 Audio Codecs の ac97 ドライバーをインストールすることで問題は解決します。詳しくは Red Hat Bugzilla – Bug 1176761 を参照してください。
ユーザーネットワークでインターネットに接続できない
ユーザーモードネットワークを使用している場合でゲストからインターネットに接続できない場合、ホストの resolv.conf にネームサーバーが定義されていないことが原因である可能性があります。
参照
- QEMU 公式ウェブサイト
- KVM 公式ウェブサイト
- QEMU エミュレータユーザードキュメント
- QEMU Wikibook
- Hardware virtualization with QEMU by AlienBOB
- Building a Virtual Army by Falconindy
- Lastest docs
- QEMU on Windows
- Wikipedia
- QEMU - Debian Wiki
- QEMU Networking on gnome.org
- Networking QEMU Virtual BSD Systems
- QEMU on gnu.org
- QEMU on FreeBSD as host