TT Lab
はじめる
学ぶ 学習パス コース

仮想化とQEMU/KVM

QEMUコマンドラインの読み方

TT Labで続きを見る

一言でいうと

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を使います。

起動の初期に見えるものの順序を知っておくと、どこまで進んだかが分かります。

  1. SeaBIOS (version ...): ファームウェアが起動しました
  2. Booting from Hard Disk...: ブートローダーに渡りました
  3. Linux version ...: カーネルが開始しました
  4. ログインプロンプト: ユーザー空間まで来ました

1つ目は、QEMUが起動するとすぐに出ます。TCGなので3つ目まで長くかかっても、1つ目と2つ目が見えれば、ディスクとブートローダーは正常だという意味です。

現場での姿

ps aux | grep qemuで実際の引数を確認します。libvirtのXMLと実際の実行引数が異なる場合があります(キャッシュされたドメイン定義、ホットプラグされたデバイス)。本物は、プロセスのコマンドラインにあります。

format=を省略して生じる問題。QEMUがファイルの内容を見てフォーマットを推測しますが、ゲストがディスクの先頭部分にqcow2ヘッダーに見えるデータを書くと、次の起動で誤認することがあります。常に明示します。

次のラボですること

/opt/vm/のイメージをバッキングにオーバーレイを作成し、実行スクリプトを正確なフラグで書き、実際に起動して、シリアルログ・モニターの応答・hostfwdのリッスンソケットの3つを確認します。