QEMUコマンドラインの読み方
一言でいうと
QEMUのコマンドラインは、仮想ハードウェアの部品リストです。フラグ1つ1つが、ゲストが見ることになるデバイスを決めます。
なぜ必要なのか
実務では、ほとんどの場合、libvirtやクラウドコンソールを使います。ところが、問題が起きると、結局はその下のQEMUのコマンドラインを読む必要があります。libvirtのXMLも、結局はこのコマンドラインに変換されるので、ps aux | grep qemuで実際の実行引数を確認するのが、診断の第一歩です。
どう動くのか
最小限のVMは、次のような形です。
qemu-system-x86_64 \
-accel tcg \
-m 512 \
-smp 2 \
-drive file=/root/vm/vm01.qcow2,if=virtio,format=qcow2 \
-netdev user,id=n0,hostfwd=tcp::12222-:22 \
-device virtio-net-pci,netdev=n0 \
-nographic \
-serial mon:stdio
各フラグの意味です。
| フラグ | 意味 | 実務のポイント |
|---|---|---|
-accel kvm / tcg |
アクセラレーターの選択 | -accel helpで使えるものを確認 |
-m 512 |
メモリ(MB) | 単位を省略するとMB |
-smp 2 |
vCPUの数 | -smp 2,sockets=1,cores=2でトポロジーを指定できます |
-drive ...,if=virtio |
ディスク + インターフェース | format=を明示しないと危険 |
-netdev / -device |
バックエンド / フロントエンド | 2つは常にペアです |
-nographic |
グラフィックなし | サーバー環境の既定 |
-serial mon:stdio |
シリアルをstdioに、モニターと兼用 | Ctrl-a cで切り替え |
-monitor unix:<경로>,server,nowait |
モニターをUNIXソケットで(プレースホルダーはパスです) | 自動化に適している |
-netdevと-deviceの分離が、最初は紛らわしいです。-netdevはホスト側のバックエンド(パケットがどこへ行くか)、-deviceはゲストが見るNIC(どんなカードに見えるか)です。2つをid=で結びます。
ネットワークモード
| モード | 特徴 | いつ使うか |
|---|---|---|
user (SLIRP) |
ユーザー空間のNAT。特権不要 | 開発/テスト。このラボ環境の唯一の選択 |
tap |
カーネルのTAPデバイス | 本番。特権が必要 |
bridge |
TAPをブリッジに接続 | VM間の通信、外部への公開 |
vhost-net |
リングの処理をカーネルで行う | 高性能 |
userモードは、ゲストから外に出ることはできますが、外からゲストに入ることはできません。そのため、hostfwdでポートを開けます。
-netdev user,id=n0,hostfwd=tcp::12222-:22
ホストの12222に入ってきたTCPを、ゲストの22に送ります。このリッスンソケットは、QEMUが起動した直後に開きます。ゲストがまだ起動中でも、ss -ltnに見えます。ゲストが立ち上がっていなければ、接続が拒否されるだけです。
モニター
QEMUモニターは、実行中のVMに話しかけるコンソールです。
-monitor unix:/root/vm/mon.sock,server,nowait
echo 'info status' | nc -U /root/vm/mon.sock
echo 'info block' | nc -U /root/vm/mon.sock
info status(実行/停止)、info block(ディスク)、info network、system_powerdown(ACPIシャットダウン要求)、savevm/loadvm(実行中のスナップショット)のようなコマンドがあります。自動化では、ソケットでつなぐのが標準です。
コンソール
-nographicと-serialの組み合わせで、シリアルコンソールを使います。ゲストカーネルにconsole=ttyS0を渡さないと、カーネルメッセージがシリアルに出ません。ログをファイルに残すには、-serial file:/root/vm/console.logを使います。
起動の初期に見えるものの順序を知っておくと、どこまで進んだかが分かります。
SeaBIOS (version ...): ファームウェアが起動しましたBooting from Hard Disk...: ブートローダーに渡りましたLinux version ...: カーネルが開始しました- ログインプロンプト: ユーザー空間まで来ました
1つ目は、QEMUが起動するとすぐに出ます。TCGなので3つ目まで長くかかっても、1つ目と2つ目が見えれば、ディスクとブートローダーは正常だという意味です。
現場での姿
ps aux | grep qemuで実際の引数を確認します。libvirtのXMLと実際の実行引数が異なる場合があります(キャッシュされたドメイン定義、ホットプラグされたデバイス)。本物は、プロセスのコマンドラインにあります。
format=を省略して生じる問題。QEMUがファイルの内容を見てフォーマットを推測しますが、ゲストがディスクの先頭部分にqcow2ヘッダーに見えるデータを書くと、次の起動で誤認することがあります。常に明示します。
次のラボですること
/opt/vm/のイメージをバッキングにオーバーレイを作成し、実行スクリプトを正確なフラグで書き、実際に起動して、シリアルログ・モニターの応答・hostfwdのリッスンソケットの3つを確認します。