前の記事
前回はKVM, QEMU, libvirt の概要について紹介しました。
お伝えしたいこと
本記事では、KVM+QEMUによる仮想化システムのインストール手順と、libvirt CLI (virt-install, virsh) によるVM作成手順を紹介します。
その後、KVMが本当に正しく構成されているのかを確認する手順と、正しく構成されていなかった場合の対処法について紹介します。
libvirtベースのCLI/GUIツールの概要については、前の記事のlibvirt を利用している製品を先にお読みください。
libvirt ベースのGUIツールについては、次の記事で紹介します。
QEMU、KVM、libvirt のインストールは非常に簡単です。
ただ、libvirtの初期設定、使い方、KVMが動かない時のトラブルシューティングを含めた結果、記事が長くなってしまいました。
手順上読まなくても問題ない部分には (参考) をつけましたので、不要と感じたら読み飛ばしてください。
本記事の末尾にオススメの解説動画も貼りました。
Arch Linux をモデルとした内容ですが、本記事と同様の紹介がされています。
文字よりも動画がお好みの方は、ぜひチェックしてみてください。
動画中の解説は英語です。
日本語がお好みでしたら、やはり私の記事を読んでください!
- 前の記事
- お伝えしたいこと
- QEMUのインストール手順
- KVMのインストール手順
- KVMの動作確認 (1/2)
- コンソール接続用アプリケーションのインストール
- libvirtの初期設定
- ISOファイルの準備
- ディレクトリの権限を設定する
- VMの作成
- VMの起動確認
- KVMの動作確認 (2/2)
- (参考) VMへのコンソール接続
- VMの削除
- (参考) virt-install コマンドの WARNING/ERROR 対策
- (参考) KVMが動作しない場合のトラブルシューティング
- (参考) qemu:///system と qemu:///session の違い
- (参考) libvirt (virsh) の用語
- (参考) 仮想NICの設定変更
- (参考) おすすめの動画 / 記事
- まとめ
- Linux PC 構築関連リンク集
- 次の記事
QEMUのインストール手順
以下のコマンドで、KVMに対応したCPUアーキテクチャ (x86) に対応するQEMUをインストールします。
sudo dnf install qemu-kvm
KVMのインストール手順
KVMはLinuxのカーネルモジュールとして初めから組み込まれているので、インストールは不要です。
KVMの動作確認 (1/2)
さて、ここでKVMの動作確認をします。
KVMの動作確認は2段階に分けて行います。
まず、ここではKVMとCPUの仮想化支援機能に関わるカーネルモジュールがそれぞれロードされていることを確認します。
以下のコマンドを実行してください。
lsmod | grep kvm # kvm_intel 319488 0 # kvm 823296 1 kvm_intel # irqbypass 16384 1 kvm
上述のように、kvm
とkvm_intel
、またはkvm
とkvm_amd
のいずれかが表示されれば、まず問題ありません。
もしkvm
やkvm_intel
が表示されない場合は、(参考) KVMが動作しない場合のトラブルシューティングにて問題を解消してください。
その上で、VMを1つも起動していないときはkvm_intel
、またはkvm_amd
の行の一番右の列が 0 であることを確認してください。
これは、kvm_intel
、またはkvm_amd
モジュールが他のプログラムによって利用されていないことを表しています。
この後、VMを実際に作成・起動した上でもう一度lsmod
コマンドを実行します。
その状態で、kvm_intel
、またはkvm_amd
行に対応する数値が1以上の値になっていれば、KVMは正しく動作していることになります。
VM起動後に行うKVMの動作確認は、KVMの動作確認 (2/2)にて実施します。
コンソール接続用アプリケーションのインストール
VMにコンソール接続するためのアプリケーションをインストールします。
アプリケーションはGUIのプログラムであるため、Linux上で使う場合はGUI (デスクトップ環境やWindow Manager) が必要です。
KVMをLinuxで動作させつつリモートのWindowsからコンソール接続する構成であれば、Windows側にRemote Viewerを入れるのに特に制限はありません。
ここでインストールしたアプリケーションは、後に#(参考) VMへのコンソール接続で使うことになります。
Virtual Machine Viewer のインストール
Virtual Machine Viewerは、VMにコンソール接続して画面表示するGUIツールです。
従って、GUI環境がなければ起動できません。
KVM仮想化を提供しているマシンがローカルで動作している場合には導入を推奨します。
または、libvirtのconnectionでネットワーク越しにKVMサーバに接続している構成でも、Virtual Machine Viewerを使えます。
以下のコマンドでインストールします。
sudo dnf install virt-viewer
Remote Viewer のインストール
アクセス元のLinuxから見てKVM仮想マシンがリモートで起動している場合は、Remote Viewerで接続します。
SPICEやVNCなどのプロトコルにより、ネットワーク越しにコンソール接続します。
Remote Viewerを使う際もGUI環境が必要です。
余談ですが、Cockpitをお使いの方もGUI操作でコンソール接続する際、Remote Viewerがあると便利です。
localhostを指定することでローカルの仮想マシンにも接続できますが、ローカルの場合はVirtual Machine Viewerの方が使い勝手が上です。
以下のコマンドでRemote Viewerをインストールします。
sudo dnf install remote-viewer
アクセス元がWindowsの場合は、Windows版のRemote Viewer を以下の公式サイトからダウンロード、インストールします。
virt-viewerと記載がありますが、これをインストールすると実際にはRemote Viewerもインストールされます。
https://virt-manager.org/download/
libvirtの初期設定
CLIでVMを作成する
今回は、デスクトップ環境がなくても動作するCLIにて今回は進めたいと思います。
必要に応じて、GUIツールを後から追加インストールすることも可能です。
どのGUIツールをインストールしたとしても、必ず依存関係でCLIツールもインストールされます。
一旦GUIツールのことは気にしないこととして、先に進みましょう。
libvirtのインストール
以下のコマンドでlibvirtをインストールします。
libvirt
とvirt-install
は導入必須です。
virt-top
は任意なので、不要と感じたらスキップしても問題ありません。
# 必須 sudo dnf install libvirt virt-install # 任意 sudo dnf install virt-top
インストールの内訳は以下の通りです。
パッケージ名 | 中身 |
---|---|
libvirt |
・libvirtd がCLI/GUIツールからハイパーバイザー (QEMU+KVM) にAPI連携する・ virsh コマンドにより、Disk,仮想NWを作成する・同コマンドでVMを起動・停止・削除する |
virt-install |
・virt-install コマンドにより、VMを新規作成する・ virt-clone コマンドでVMをクローンする |
virt-top |
・virt-top コマンドにより、VMのCPU,RAM,Disk利用状況を可視化する |
libvirtdの起動
以下のコマンドでlibvirtd の自動起動を有効化しつつ、今すぐ起動します。
libvirtベースのツールは、libvirtdを介してハイパーバイザーを操作するので、libvirtdの起動は必須です。
sudo systemctl enable --now libvirtd.service
ユーザーグループの設定
libvirtをqemu:///system
セッションで使うにあたり、libvirtを利用するユーザーをlibvirtグループに所属させる必要があります。
qemu:///system の意味については(参考) qemu:///system と qemu:///session の違いで、グループ設定が必要な理由は1. libvirtグループへの所属で補足します。
以下のコマンドによって、現在のユーザーがlibvirtd特権プロセスにアクセスするための権限を付与します。
sudo usermod -aG libvirt "$USER"
(任意) qemu:///system をデフォルトにする
デフォルトでは、virsh uri
を実行するとqemu:///session
と表示されます。
これはvirsh
などのlibvirt関連コマンドを実行したときにqemu:///session
、つまり「一般ユーザー権限でローカルホストに接続している」ことを表しています。
このデフォルト挙動を上書きするためには、virsh --connect qemu:///system uri
のようにコマンドラインオプションを指定する必要があります。
しかし毎回 --connect
を指定するのは面倒なので、設定ファイルでデフォルト挙動を上書きしちゃいましょう。
~/.config/libvirt/libvirt.conf
を作成し、設定情報を記述します。
mkdir -p ~/.config/libvirt/ echo 'uri_default = "qemu:///system"' > ~/.config/libvirt/libvirt.conf
以下のコマンドにより、QEMUが接続するハイパーバイザーのURIがデフォルトでqemu:///system
になっていることを確認します。
virsh uri
# qemu:///system
以下のようにエラーが出た場合、#libvirtdの起動の手順を忘れている可能性があります。
リンク先を参照して対処してください。
virsh uri # error: failed to connect to the hypervisor # error: Failed to connect socket to '/var/run/libvirt/virtqemud-sock': No such file or directory
最後に補足しますが、Virtual Machine Managerのデフォルト値はqemu:///system
です。
Virtual Machine Managerとvirshで見えるVMやpoolなどが異なる場合は、利用しているConnectionが異なる可能性があるので注意してください。
このあたりは最初にハマりがちな罠だったりします。
あまり本質ではないかもしれませんが、こういった罠を回避するためにも、qemu:///system
にデフォルト値を寄せるとわかりやすくて良いかなと個人的に思います。
Virtual Machine Manager側の設定方法については、Virtual Machine Manager GUI によるKVM操作 #URIの指定を参照してください。
(参考) デフォルトURI決定の優先順位
- 環境変数:
LIBVIRT_DEFAULT_URI
- クライアント設定ファイル:
uri_default = "qemu:///system"
- 応答があるまで、各種ハイパーバイザーを順に試す
ここでは、「2. クライアント設定ファイル」によって指定します。
クライアント設定ファイルは、以下の2箇所に配置します。
- rootユーザ用:
/etc/libvirt/libvirt.conf
- 一般ユーザ用:
$XDG_CONFIG_HOME/libvirt/libvirt.conf
→~/.config/libvirt/libvirt.conf
man libvirtd
によると、$XDG_CONFIG_HOME
が未定義の場合は、$HOME/.config/
になるようです。
従って、今回更新すべきファイルは~/.config/libvirt/libvirt.conf
ということになります。
pool作成の事前準備
VMを作成する前に、poolの設定を変更します。
poolには、VMのディスクイメージファイル (*.qcow2) や、ISOイメージファイルの保管場所を設定します。
本来はstorage poolが正しい呼び方なのですが、本記事においては省略してpoolと呼ぶことにします (man virsh
でもしばしばpoolと省略表記されます)。
さて、poolを作成する事前準備として、まずディレクトリをどこにするか決めます。
詳細は2. イメージファイルのパーミッションに後述しますが、VM作成に必要なISOイメージファイルや、VMのディスクイメージファイルはqemu
ユーザーによってアクセスできるようパーミッションを設定する必要があります。
それを踏まえて、事前に保存先のディレクトリをどこにするか決めておいてください。
今回は、/home/shared/libvirt/disks/
にディスクイメージファイルを、/home/shared/libvirt/isos/
にISOイメージファイルを保存します。
/home/shared/libvirt/isos/
配下は、rhel
やubuntu
などのOS/ディストリビューション名でフォルダ分けする想定です。
/home/shared
は、shared
グループに属するユーザーであれば誰でもアクセス可能なディレクトリとして作成します。
(※) 私の環境はパソコン用途を想定しているため、/home
のファイルシステム容量を大きくしています。したがって、/home
配下にイメージファイルやVMDKファイルなどの大容量ファイルを置くために、今回のようなフォルダ構成としました。なおご参考までに、libvirt-daemon
RPMパッケージをインストールすると/var/lib/libvirt/images
をデフォルトで生成します。今回のフォルダ構成は自分なりにアレンジを加えたものの、libvirt/images/
というフォルダの切り方はデフォルト構成を踏襲しました。ファイルシステムの設計は皆様それぞれだと思いますので、自分の環境にあった置き場所をご検討ください。
以下のコマンドで上述の構成にできますので、よろしければそのままご利用ください。
# sharedグループを作成し、qemuと一般ユーザーを加える sudo groupadd shared sudo usermod -aG shared "$USER" # ディレクトリを作成する sudo mkdir -p /home/shared/libvirt/disks sudo mkdir -p /home/shared/libvirt/isos # 最低限の権限設定 sudo chown -R root:shared /home/shared sudo chmod -R ug+rw /home/shared
pool作成
pool作成に先立ち、既存のpoolを確認します。
既存でdefault
というpoolがある場合、これから行うpool作成コマンドは失敗します (同名のpoolは複数作成できないため)。
# show pool list virsh pool-list # show pool configuration virsh pool-dumpxml default | grep path # <path>XXX</path>
ということで、必要に応じてdefault
poolを先に消しておきましょう。
# stop the pool virsh pool-destroy default # delete the pool virsh pool-undefine default
続いてpoolを定義 (define) します。
このコマンドによりpoolの構成情報を記述したXMLファイルが生成し、libvirtによって管理されるようになります。
本記事はvirshの紹介記事なのでCLIで実施していますが、GUI環境があればvirt-managerやcockpitからもpoolの作成は可能です。
virsh \ pool-define-as default dir \ --target /home/shared/libvirt/disks/
defineやdestroyなどのlibvirt用語について知りたい方は、(参考) libvirt (virsh) の用語も参照してください。
(参考) pool作成コマンドの補足
コマンドの意味について補足します。
不要な方は読み飛ばしてください。
まず、syntax は以下のようになります。
virsh \ pool-define-as <pool-name> <type> \ --target <target-path>
各キーワードの意味は、以下のようになります。
<pool-name>
は、poolの名前です。
KVMのイメージファイルを格納するpoolとして、default
を作成することをお勧めします。
その理由は、2つあります。
- Virtual Machine Manager (GUI)が起動時に
default
というプールを勝手に作ってしまうため - 他のvirshコマンドでも、pool名の指定を省略した場合に
default
を自動的に指定するものがあるため
<type>
は、ファイルの置き場所によって変わります。
ローカルの特定ディレクトリをpoolとして使用し、ディレクトリ配下にイメージファイルを格納する場合はdir
を指定します。
その他の type に関する情報は、libvirt公式サイトに情報がありますが、dir
以外はあまり使わない印象です。
--target
は、type=dir
の場合に使用するオプションで、poolと対応するディレクトリパスを指定します。
--type
に指定する値によって指定すべきオプションが変わるので、CLIだと結構わかりづらいです。
Cockpit操作であればGUIの選択肢がtype
に応じて良い具合に切り替わるので、このあたりが直感的に操作できて便利です。
poolの起動・自動起動設定
virsh pool-define-as
はpoolを作成しただけで起動はしていません。
poolの起動、及びOSと共に自動起動する設定も必要です。
Linuxのデーモンに対して systemctl enable
や systemctl start
するのと似たような考え方ですね。
virsh pool-start default virsh pool-autostart default
poolの確認
最後に、作成したpoolを確認します。
poolを一覧表示するには、pool-list
を使います。
デフォルトでは起動していないpoolが表示されないので、全て表示したい時は --all
もつけます。
--details
で詳細表示できます。
poolの完全な設定情報を確認したい場合は、pool-dumpxml
を使います。
virsh pool-list virsh pool-dumpxml default
(参考) poolの停止・削除
この手順は基本実施不要です。
もしpoolを間違えて作ってしまい、削除したくなったときは以下の流れで実施します。
- poolの停止 (destroy)
- poolの削除 (undefine)
補足ですが、VMの通常停止を shutdown、強制停止(VMのプロセス kill) をdestroyと呼びます。
poolの停止の場合は、常に destroy と呼ばれます。
VM/poolの削除は undefine と呼びます。
pool作成時に実施した define の反対で、XMLファイルを削除します。
削除操作は、対象を停止させた上で実施する必要があります。
コマンドとしては、以下のようになります。
# virsh pool-destroy <pool-name> # virsh pool-undefine <pool-name>
ISOファイルの準備
VMを作成するのに必要なISOファイルをダウンロードし、/home/shared/libvirt/isos/
配下に格納してください。
個人的には、/home/shared/libvirt/isos/fedora/xxx.iso
のようにOS/ディストリビューション名でフォルダを分けて整理するのが好きです。
ディレクトリの権限を設定する
ここで/home/shared/libvirt/
配下に格納したファイルやディレクトリの権限設定を一括で書き換えます。
後続のセクションではvirt-install
コマンドによりVMを作成します。
virt-install
コマンドを実行すると、libvirtd
を介してqemu系のコマンドが実行されます (qemu-kvm
やqemu-system-x86_64
など)。
そしてqemuコマンドが正しく動作するためには、VMを構成する各種ファイルに対してqemu
ユーザーがアクセスできる必要があります。
では、必要な設定を以下に示します。
sudo chown -R root:shared /home/shared sudo chmod -R ug+rw,o-rwx /home/shared find /home/shared -type d | sudo xargs -I{} chmod ug+x {} sudo setfacl -Pm u:qemu:rwx /home/shared sudo setfacl -PRm u:qemu:rw /home/shared/libvirt/ find /home/shared/libvirt/ -type d | sudo xargs setfacl -Pm user:qemu:rwx
こちらの設定により、以下のように権限設定されます。
/home/shared/
ディレクトリ配下はuserとgroupに対して読み書き権限が付与されるqemu
ユーザーは/home/shared/libvirt/
配下にアクセスできる。/home/shared/
配下のその他共有ファイルにはアクセスできない
chown
やchmod
ではこのような権限構成を表現しきれないので、今回はsetfacl
コマンドを活用しました。
setfacl
は、いわゆるLinux ACLを設定するコマンドです。
詳しくは@ITの【 setfacl 】コマンド(応用編その1)――デフォルトのアクセス制御リスト(ACL)を設定するが参考になります。
/home/shared/
配下にファイルを配置するたびに毎回コマンドを実行するのは大変なので、私は/home/shared/set_permissions.sh
に以下のシェルスクリプトを配置しています。
ファイルを配置するたびにシェルスクリプトを実行すれば良くなるので楽だと思います。
よろしければご活用ください。
#!/bin/bash # Try to cache sudo credentials first if ! sudo true; then echo 'Failed to obtain root priviledges.' exit 1 fi sudo chown -R root:shared /home/shared sudo chmod -R ug+rw,o-rwx /home/shared find /home/shared -type d | sudo xargs -I{} chmod ug+x {} sudo setfacl -Pm u:qemu:rwx /home/shared sudo setfacl -PRm u:qemu:rw /home/shared/libvirt/ find /home/shared/libvirt/ -type d | sudo xargs setfacl -Pm user:qemu:rwx
VMの作成
VMを作成するには、以下のコマンドを実行します。
紹介しているコマンドは例ですので、環境によって一部変更してください。
virt-install \ --name test \ --memory 1024 \ --vcpus 2 \ --disk size=8 \ --graphics spice \ --graphics vnc \ --cdrom /home/shared/libvirt/isos/fedora/Fedora-Server-dvd-x86_64-32-1.6.iso \ --os-variant fedora32 \ --noautoconsole
コマンドラインオプションの意味については、次の(参考) VM作成コマンドの補足を参照してください。
VMの作成コマンド実行時に警告やエラーが出た場合は、(参考) virt-install コマンドの WARNING/ERROR 対策を参照してください。
(参考) VM作成コマンドの補足
virt-install
のオプションの意味を補足します。
補足が不要な方は読み飛ばしてください。
情報源はman virt-install
です。
オプション | 意味 |
---|---|
--name VM_NAME |
作成するVMの名前を指定する |
--memory MEM_SIZE |
VMのメモリサイズをMiB単位で指定する |
--vcpus CPU# |
仮想CPUコア数を指定する |
--disk size=VOL_SIZE |
仮想ディスクのサイズをGiB単位で指定する |
--graphics spice |
仮想コンソールを作成し、VMにSPICEプロトコル用のポート番号をlistenさせる (※) |
--graphics vnc |
仮想コンソールを作成し、VMにVNCプロトコル用のポート番号をlistenさせる (※) |
--cdrom PATH_TO_ISO |
VMのOSをインストールするためのイメージファイル (ISO) へのフルパスを指定する |
--os-variant |
OS (Distribution) の名前と紐づく値をセットする。 指定することで、libvirtdが指定したOSに最適な仮想ハードウェア (特にvirtio) を選択する このパラメータは必須ではないが、正しく設定することで性能が著しく向上する。 指定を省略した場合、ISOファイルをURL指定で取ってくる場合のみ自動認識される。 --os-variant に指定可能な文字列は、osinfo-query os コマンドにより確認可能 |
--noautoconsole |
VM作成直後にVirtual Machine Viewer (virt-viewer) のコンソールを自動的に開かないようにする。 このオプションを入れない場合、コマンド末尾に & を付けてバックグラウンド実行とすることで、Virtual Machine Viewerが起動した後にプロンプトが戻ってくるようにするのが良い |
(※) virt-viewer
でローカルコンソール接続する場合は不要ですが、remote-viewer
によってリモートからコンソール接続する場合はSPICEかVNCが必要です。今回は別に指定する必要はないのですが、ユースケースによっては利用することもあり得るので敢えて含めておきました
VMの起動確認
VMが起動していることを確認します。
--all
オプションをつけると停止しているVMも含めて表示されます。
virsh list
KVMの動作確認 (2/2)
ここまでの手順でVMが起動できているはずですので、KVMの動作確認をします。
KVMの動作確認 (1/2)でも触れたとおり、KVMが正しく動作していれば、kvm_intel
、またはkvm_amd
カーネルモジュールの利用回数の部分が1以上の値になっているはずです。
以下のコマンドを実行してください。
kvm_intel
に対応する一番右の値が 4 になっています。
この数字が1以上なので、KVMは正しく動作しています。
lsmod | grep kvm # kvm_intel 319488 4 # kvm 823296 1 kvm_intel # irqbypass 16384 1 kvm
本セクションでKVMの動作確認ができたら、VMの削除を参照しつつ、動作確認用のVMを削除します。
ここまで問題なく完了したら、KVMのセットアップは完了です。
お疲れ様でした。
【重要】動作確認時の注意
KVMが正しく動作して作成したVMと、KVM利用に失敗してQEMU (TCG: Tiny Code Generator) にフォールバックして作成されたVMは、完全に別物と理解してください。
実際に試してみたところ、以下のような挙動になりました。
特に重要なのは前半の事実で、トラブルシューティングが完了してKVMが利用可能となった後に、QEMUベースで作成したVMを起動しても、kvm_intel、またはkvm_amdの使われている数は0のままということです。
KVMのトラブルシューティングをした後は、必ずVMを作り直した上で動作確認してください。
(参考) VMへのコンソール接続
この手順は、LinuxにGUI環境 (≒デスクトップ環境) をインストールした方のみが実行可能な手順です。
CLI、またはGUIによってVirtual Machine Viewerを起動し、コンソールログインします。
Virtual Machine Viewerは、基本的にlibvirtで接続したサーバー (--connect qemu:///system
) に対してローカルな接続を提供します。
言い換えると、基本的にlocalhostに対するコンソール接続に使います。
リモートで実行しているKVM仮想マシンにコンソール接続したい場合は、Remote Viewerを使用します。
Virtual Machine Viewer (CLIから起動)
まずはCLIからの起動手順を紹介します。
以下のコマンドを実行するだけです。
virt-viewer &
すると、以下の画面から起動中のVMが表示されるので、選択して接続します。
成功すれば、コンソール画面が表示されます。
以下のように、VM名を引数として指定することでVMを明示的に指定することも可能です。
virt-viewer test &
普段CLIでKVMを操作する方は、virsh start
でVMを起動した後、virt-viewer &
でコンソール接続する使い方が動線としてはスムーズかなと思います。
なお、多くのLinuxデスクトップ環境ではAlt+F2
でコマンド実行できるショートカットキーがあるのではないかと思います。
もしその機能が使える場合、GUIからvirt-viewer
やvirt-viewer test
と実行する方がおすすめです。
その場合、ターミナルで実行するのと比べて余計なコンソールログが表示されない分見た目がきれいになります。
Virtual Machine Viewer (GUIから起動)
GUIのMenuからVirtual Machine Viewerを起動して接続することもできます。
以下のように、Menuから検索して起動するだけです。
環境によっては、検索してもヒットしないこともあります。
多くのGUIアプリケーションは、Menuから起動するために必要なDesktop Entry (*.desktop
ファイル) を/usr/share/applications/
配下などに自動配置するため、Menuから問題なく起動できます。
しかし、私の環境 (Fedora35 + Cinnamon Desktop) ではVirtual Machine Viewerのdesktopファイルが自動配置されなかったので、手動で作成します。
以下のテキストファイルを~/.local/share/applications/virt-viewer.desktop
に配置してください。
そうすれば、デスクトップ環境のMenuからVirtual Machine Managerを開けるようになるはずです。
再ログインする必要はありません。
[Desktop Entry] Name=Virtual Machine Viewer Exec=virt-viewer Comment=Display the graphical console Terminal=false Icon=virt-viewer Type=Application
Desktop Entryについてより詳細を知りたい方は、以下の記事を参照してください。
(参考) Remote Viewer
Remote Viewerとは、Remote Desktopのようなリモート接続のウィンドウを出すプログラムです。
KVMをリモートサーバーで動かしているときに使うことがあるので、参考までにやり方を書いておきます。
今回の例では私の環境の都合でlocalhostにRemote Viewerで接続していますが、基本的な考え方は同じです。
まず、Remote Viewerを使いたい場合は以下のコマンドでRemote Viewerをインストールしておきます。
sudo dnf install remote-viewer
そして、以下の手順で接続します。
まず、コンソールアクセスするためのURLを先に確認します。
1台目の起動であれば、spice://127.0.0.1:5900
と表示されます。
2台目であれば、spice://127.0.0.1:5901
とポート番号が1刻みで増えます。
慣れれば確認するまでもなくポート番号が予想できます。
virsh domdisplay test # spice://127.0.0.1:5900
デスクトップのメニューから "Remote Viewer" で検索し、Remote Viewerを起動します。
そして、出てきたウィンドウに上記URLを入力して接続します。
成功すれば、コンソール画面が表示されます。
以下のようにCLIからRemote Viewerを起動することも可能です。
remote-viewer
# または
remote-viewer spice://localhost:5900
ポート番号の指定など面倒なので、ローカル接続にはVirtual Machine Viewerを使うことをおすすめします。
(参考) Cockpit からの起動
Cockpitの画面でVM名をクリックし、「Launch Remote Viewer」を選択するとdownload
という名前のファイルがダウンロードされます。
このファイルをクリックして開けば、Remote Viewerが開きます。
download
ファイルは、開いた直後に自動的に削除されるので、基本的にフォルダが汚れることはありません。
とても優秀です。
詳しくは、次の記事で紹介します。
VMの削除
まず、削除対象のVMを停止します。
VMの停止は、以下の2種類があります。
強制停止は、何らかの理由で (※) 通常停止ができない場合のみ使うイメージです。
経験上、作成したばかりのVMでOSが未インストールの場合はshutdownを受け付けないので、destroyで強制停止します。
これから削除するVMに対しては、気軽に強制停止しても問題ありません。
(※) VMが無応答だったり、KVMではなくQEMU単体で動作している場合はshutdownできないこともあります
virsh shutdown test # または、virsh destroy test
VMが停止したことを以下のコマンドで確認します。
virsh list test
VMを削除する時に気をつけたいのは、オプションを指定しない限り、VMに紐づくディスクファイルは削除されないことです。
オプションを指定するために、まずは以下のコマンドでブロックデバイス名を調べます。
ちなみに、VMのことをlibvirt用語でdomainとも呼びます。
domblklist
は、"list domain's block files" という意味になります。
virt-install
に --os-variants
を指定した場合は、最適な仮想ハードウェアとしてvda (virtio) が選択されているはずです。
逆に--os-variants
を指定しなかった場合は、低速なhda (仮想IDE) が選択されます。
virsh domblklist test
続いて、以下の手順では、--storage
オプションを指定することで、VMに紐づくディスクファイル(qcow2) も一緒に削除するようにしています。
--snapshots-metadata
と --managed-save
は、関連するスナップショットや保存データも削除するオプションです。
スナップショット作成やVMの保存をしていなければ特に意味はありませんが、不要データを綺麗に削除するために指定しても損はないと思います。
--remove-all-storage
は、virsh domblklist
でISOファイルが表示されていた場合、ISOファイルまで削除されてしまうので、このオプションはあまり使いません。
# "vda" の部分は、virsh domblklist の出力によっては "hda" に変更する virsh \ undefine \ --domain test \ --storage vda \ --snapshots-metadata \ --managed-save
(参考) virt-install コマンドの WARNING/ERROR 対策
virt-install コマンド実行時、警告メッセージが出ることがあります。
ここでは、警告のメッセージについて対処法を補足します。
警告が出なかった場合は読み飛ばして結構です。
WARNING KVM acceleration not available, using 'qemu'
このメッセージが出たら、KVMが正しく動作していません。
KVMの動作確認 (2/2)からKVMが動作していないことを確認できたら、(参考) KVMが動作しない場合のトラブルシューティングで原因調査の上、対処してください。
XXX may not be accessible by the hypervisor.
具体的には、以下のようなメッセージです。
WARNING /home/shared/libvirt/isos/fedora/Fedora-Server-dvd-x86_64-32-1.6.iso may not be accessible by the hypervisor. You will need to grant the 'qemu' user search permissions for the following directories: ['/home/shared']
このメッセージが出た場合、その下のメッセージを確認してください。
以下のメッセージが続いていたら、VMは作成できているので無視しても問題ありません。
Starting install... Allocating 'test.qcow2' Domain installation still in progress. You can reconnect to the console to complete the installation process.
このメッセージは、libvirt側でイメージファイル(iso)、またはディスクファイル(qcow2) へのアクセス権限があると断定できない場合に発生します。
#ディレクトリの権限を設定するを再度実行することで対処ください。
なお上述の手順を実行せずともqemu
ユーザーをshared
グループに所属させることでも楽に権限を与えることはできるのですが、グループではなくユーザーに権限がないとエラーメッセージが発生してしまいます。
エラーメッセージが発生してもVMは作成できるのですが、なんだかもやもやしますよね。
なので私はACLによってユーザーに権限を与えるようにしています。
ERROR Guest name 'test' is already in use.
既に 'test' という名前のVMが存在しています。
virsh list --all
で確認できます。
対処方法はVMの名前を被らないようにするか、VMを削除することが挙げられます。
VMを削除する場合は、事前にブロックデバイス名を確認します (vda/hda)。
# ディスクファイル (qcow2) がhdaかvdaかを確認する virsh domblklist test
続いて、VMを削除します。
その際、--storage
オプションで一緒に削除したいブロックデバイス名を指定します(vda/hda)。
# "vda" の部分は、必要に応じて "hda" に変更する virsh destroy test virsh undefine --storage vda test
(参考) KVMが動作しない場合のトラブルシューティング
本記事の手順を実施してもKVMが動作しなかった場合は、以下の情報を参考にしてみてください。
私の環境 (NUC10+Fedora32) では運良く全くトラブルが発生しなかったので、紹介する内容は全て未検証であり、机上で調査した情報になります。
KVMの動作要件
KVMを利用するには、以下の条件を満たしている必要があります。
上記動作要件それぞれについて、以下で確認方法と対処法を紹介します。
(参考) まずは確認ツールを実行してみる
libvirtに同梱される確認ツールを実行することで、QEMU (+KVM) の動作要件を満たしているか確認できます。
- PASSがついていれば問題なし。
- WARNがついていても、恐らく動作します
- FAILがついている場合は、恐らく正しく動作しません
WARNとFAILの解釈は、私の推測です。
確認ツールの動作について、manを確認したり、libvirt.org内を検索したのですが、情報は得られませんでした。
とはいえ、libvirt公式のvalidation tool ですし、ツールを実行するだけで問題解決のヒントを得られるので気軽に実行してみるのが良いと思います。
確認ツールの実行
確認ツールを実行します。
私の環境 (Fedora32) の出力も貼っておきます。
いくつかWARNがあるものの、FAILが一つもないので問題無さそうです。
※実際、KVMの動作確認 (2/2)でKVMが動作していることを私の環境で検証済みです
virt-host-validate qemu # QEMU: Checking for hardware virtualization : PASS # QEMU: Checking if device /dev/kvm exists : PASS # QEMU: Checking if device /dev/kvm is accessible : PASS # QEMU: Checking if device /dev/vhost-net exists : PASS # QEMU: Checking if device /dev/net/tun exists : PASS # QEMU: Checking for cgroup 'cpu' controller support : WARN (Enable 'cpu' in kernel Kconfig file or mount/enable cgroup controller in your system) # QEMU: Checking for cgroup 'cpuacct' controller support : PASS # QEMU: Checking for cgroup 'cpuset' controller support : WARN (Enable 'cpuset' in kernel Kconfig file or mount/enable cgroup controller in your system) # QEMU: Checking for cgroup 'memory' controller support : PASS # QEMU: Checking for cgroup 'devices' controller support : WARN (Enable 'devices' in kernel Kconfig file or mount/enable cgroup controller in your system) # QEMU: Checking for cgroup 'blkio' controller support : WARN (Enable 'blkio' in kernel Kconfig file or mount/enable cgroup controller in your system) # QEMU: Checking for device assignment IOMMU support : PASS # QEMU: Checking if IOMMU is enabled by kernel : PASS
WARNの解消については現在のところ特に調べていませんが、libvirt.orgでcgroupを検索すると、cgroupに関するページがヒットしました。
ここを読めば、何かがわかるかもしれません。
CPUが仮想化支援機能をサポートしていること
確認手順
以下のコマンドを実行して文字列が表示されれば、CPUが仮想化支援機能をサポートしているので問題ありません。
VMXはIntel VT-x、SVMはAMD-V と紐づく言葉であり、どちらもCPUの仮想化支援機能を表す言葉です。
egrep -o '(vmx|svm)' /proc/cpuinfo # vmx # vmx # vmx # vmx # vmx # vmx # vmx # vmx # vmx # vmx # vmx # vmx # vmx # vmx # vmx # vmx
対処法
もし上記フラグが出てこなかった場合、以下も併せてご確認ください。
上記を確認してもおかしいと感じた場合は、後述のBIOSが仮想化支援機能を無効化していないことをご確認ください。
または、CPUの型番から仮想化支援機能のサポート有無を改めてご確認ください。
BIOSが仮想化支援機能を無効化していないこと
確認手順
以下のコマンドを実行し、何も表示されなければ問題ありません。
もし、"KVM: disabled by BIOS" というメッセージが出てきた場合は、BIOSによってCPUの仮想化支援機能が無効化されている可能性があります。
dmesg | grep -i kvm
対処法
BIOS設定画面を表示し、仮想化支援機能を有効化する必要があります。
BIOS設定画面の表示方法、そもそも設定変更できるのか否かは、BIOSのマニュアルをご確認ください。
ちなみに、私が使っているNUC10のBIOSの場合は設定項目自体ありませんでしたが、特に仮想化支援機能は使えていたので問題なしです。
KVMカーネルモジュールがロードされていること
確認手順
以下のコマンドを実行し、kvmとkvm_intel、またはkvmとkvm_amd が表示されれば正常です。
非常にレアケースだと思いますが、何も表示されなかったり、kvmしか表示されない場合は対処が必要な可能性があります。
lsmod | grep kvm # kvm_intel 319488 0 # kvm 823296 1 kvm_intel # irqbypass 16384 1 kvm
対処法
まず、IntelかAMDのCPUを使っていない場合には、kvmしか表示されなくても問題ない可能性があります。
IBM POWER8 か IBM POWER9 の場合はこちらをご確認ください。
(無いと信じたいですが) Intel、AMDのCPUを使っていても表示が想定外になった場合は、手動でのモジュールロードを試してみると良いかもしれません。
まずは設定ファイルを変更せず、起動時のみに影響を与える方法でカーネルモジュールをロードしてみます (OSが起動しなくなったら怖いので)。
※Intel製ではなくAMD製CPUを利用している場合は、kvm_intelをkvm_amdに読み替えてください
sudo modprobe kvm_intel
もう一度確認してみます。
lsmod | grep kvm
この方法で解決できる場合、OS起動時にモジュールを自動的にロードするよう設定すれば解決できるはずです。
これは未検証なのですが、設定ファイル (/etc/modules-load.d/kvm.confなど) に以下のように記述してOSを再起動すれば、恐らく直ります。 (情報元:man modules-loaded.d
)。
kvm_intel
再起動後にもう一度確認し、カーネルモジュールがロードできていれば対処完了です。
蛇足ですが、正常に動作している環境においてもVMを起動していなければsudo modprobe -r kvm_intel
でkvm_intel
カーネルモジュールを除外すれば、不具合の発生している状況を再現できます。
/dev/kvm の権限が正しいこと
確認手順
公式にも切り分け方法として書いてあったので、稀にこの不具合にあたるケースがあるようです。
参考情報として、KVMを問題なく利用できている私の環境における出力を貼ります。
/dev/kvmはkvmグループから参照できるようになっており、kvmグループにはqemuユーザーが所属する構成でした (Fedora32の場合)。
/dev/kvmはQEMUとKVMに連携する時に利用されるKVMのインターフェース部分なので、qemuユーザーがアクセスできれば問題ないと考えています。
ls -l /dev/kvm # crw-rw-rw-. 1 root kvm 10, 232 Nov 23 19:27 /dev/kvm # grep kvm /etc/group # kvm:x:36:qemu
なお、kvmカーネルモジュールがロードされていない場合は、/dev/kvm がそもそも生成していませんでした。
/dev/kvmが存在しない場合には、KVMカーネルモジュールがロードされていることも改めてご確認ください。
対処法
軽く検索したところ、Ubuntu 18.04 ではこのトラブルが発生するケースがあるようです。
2つの情報ソースを確認したところそれぞれ別の対象法を取っていますが、最終的にqemuユーザーが/dev/kvm にアクセスできるよう構成することで不具合を回避しているようです。
デバイスファイルの場合はOS再起動するたびに権限やオーナー設定がリセットされるので、chownやchmodで変更しても一時的にしか対処できないようです。
ちなみにFedoraの場合は、KVM公式ページに書いてあるようにudevで/dev/kvmの権限を変更していました。
以下の出力のうち、1行目が該当します。
記載内容の意味は、man udev
を読めば確認できます。
grep -r kvm /etc/udev/rules.d/ /usr/lib/udev/rules.d # /usr/lib/udev/rules.d/50-udev-default.rules:KERNEL=="kvm", GROUP="kvm", MODE="0666", OPTIONS+="static_node=kvm" # /usr/lib/udev/rules.d/50-udev-default.rules:KERNEL=="udmabuf", GROUP="kvm"
言い換えると、/usr/lib/udev/rules.d/50-udev-default.rules
に以下の行を追記すれば直ると思われます。
KERNEL=="kvm", GROUP="kvm", MODE="0666", OPTIONS+="static_node=kvm" KERNEL=="udmabuf", GROUP="kvm"
(参考) qemu:///system と qemu:///session の違い
libvirtには、connection
というオプションがあります。
libvirtを使う際、connection
にURI
を指定することで、制御対象の仮想化製品を示す必要があります。
QEMU+KVM (またはQEMU単体) を操作する場合は、以下のいずれかのURIを使用します。
qemu:///system
qemu:///session
本記事ではqemu:///system
を使う前提で手順を紹介しました。
qemu:///system
は公式で推奨されていますし、こちらのほうがトラブルを踏みにくいと感じたためです。
次のセクションで両者の違いを簡単に紹介します。
両者の違いを紹介するにあたり、以下の記事を参考にしました。
- libvirt FAQ: What is the difference between qemu:///system and qemu:///session? Which one should I use?
- Cole Robinson氏のブログ (libvirtのメンテナ): qemu:///system vs qemu:///session
qemu:///system
rootユーザによって起動されたlibvirtdデーモンを介してVMを操作します。
libvirtがシステムのリソースにアクセスするために必要な権限を一通り持つため、基本的には何でもできます。
ちなみに、qemu:///system
は、rootユーザーのユーザーセッションでもあります。
すなわち、sudo virsh --connect qemu:///session list
と仮に実行したとしても、sudo virsh list
と同じ意味になります。
このことからもqemu:///system
は特権と同等であるということがわかります。
qemu:///system
を利用するには、必要な設定が2つあります。
1. libvirtグループへの所属
libvirtはPolkitと連携しています。
Polkitは、非特権のプロセスが特権を持つプロセスにアクセスする仕組みを提供するツールキットです。
Polkitで適切なポリシーを定めて適用することで、セキュリティリスクを最小限に抑えつつ、非特権プロセスから特権プロセスへのアクセス権限を付与できます。
sudo
に似たような仕組みと思えば理解しやすいと思います。
普段virshやVirtual Machine ManagerによってVMを作る際、一般ユーザーで作業します。
つまり、上記操作によって発行されるのは非特権プロセスです。
一方で、qemu:///system
というURIでアクセスするのは、rootユーザーによって起動されたlibvirtd (即ち特権プロセス) ですので、Polkitの影響を受けます。
具体的には、virshやVirtual Machine Managerを操作するたびに毎回パスワードを求められるようになります。
これは非常に面倒です。
幸い、こちらのブログに記載されているように回避策はあります。
VMを操作する一般ユーザーから以下のコマンドを発行し、libvirtグループに所属させることでパスワードを求められなくなります。
これに相当するPolkitのルールは、/usr/share/polkit-1/rules.d/50-libvirt.rules
に記載がありました。
sudo usermod --append --groups libvirt $(whoami)
この操作は初回のみ実施すれば、その後意識する必要はなくなります。
2. イメージファイルのパーミッション
2つ目の注意点として、イメージファイルのパーミッションが挙げられます。
VMをインストールする際、ISOファイルが必要となります。
ISOファイルの多くは、インターネットからダウンロードすることで入手します。
例えば、ダウンロードしたISOファイルを$HOME/Downloads
に格納したとします。
このディレクトリは、通常ダウンロードしたユーザーにしかアクセスできません。
一方で、QEMU/KVMがVMを作成する際にISOファイルをマウントするよう操作した場合、このISOファイルにqemu
ユーザーが読み取りアクセスします。
面倒なことに、この時ISOファイルが先ほどの$HOME/Downloads
に置かれていると、パーミッションエラーによってVMの起動に失敗してしまいます。
同じことがVMのディスクイメージファイル (qcow2) についても当てはまります。
対策としては、イメージファイルへのアクセス権限をqemuユーザーに持たせる ことが必要です。
具体的な実装例は、pool作成の事前準備を参照してください。
別の回避策として、FAT32でマウントしたUSBにISOやqcow2ファイルを配置する方法も提案されていました。
FAT32にはパーミッションの概念がないらしいので、ここに配置するだけでパーミッションを意識する必要がなくなるという原理です。
qemu:///session
現在のログインユーザーによって起動されたlibvirtdデーモンを介してVMを操作します。
libvirtdは非特権プロセスですので、Polkit周りの意識は不要です。
また、未検証ですがqemuユーザー周りの権限で悩むこともなくなるようです。
しかしながら、libvirt公式のFAQでは、基本的にqemu:///session
の利用を推奨していません。
なぜなら、qemu:///session
を使った場合、特権を必要とする操作ができなくなってしまうためです。
具体的にできなくなることはこちらのブログに譲ります。
必要な設定を入れれば qemu:///system
でも問題なく動作するため、基本的にはqemu:///session
を利用するメリットは少ないと考えます。
しかしながら、セキュリティなどの都合でqemu:///session
を使う必要がある場合は、本記事の--connect qemu:///system
を--connect qemu:///session
に読み替えればそのまま使えます。
(参考) libvirt (virsh) の用語
virshコマンドを使うにあたり、知っておくと便利な用語を紹介します。
libvirt公式のTerminology and goalsを元にしています。
用語 | 意味 |
---|---|
node | 物理サーバ |
hypervisor | ハイパーバイザー役のソフトウェア。本記事の文脈ではQEMU+KVMのこと。 |
domain | 仮想マシンやコンテナ |
pool | VMのディスク(qcow2)、ISOファイルを格納先を示す設定オブジェクト |
特にdomainはvirshのサブコマンドで出てくるので、知っておくと便利です。
また、domainやpoolの状態遷移図もざっくり頭に入れておくとvirshを理解しやすくなります。
公式の図が非常にわかりやすいです。
特に、以下の用語を抑えておくことがvirshを理解する上で重要となります。
用語 | 意味 |
---|---|
define | XMLファイルを生成し、libvirt管理下にする |
undefine | XMLファイルを削除し、libvirt管理から外す |
destroy | domainの強制終了 (= SIGKILL)、またはpoolの停止 |
shutdown | domainの停止 (VM上でshutdown実行) |
start | domain/pool の起動 |
(参考) 仮想NICの設定変更
デフォルトの設定では、default
という仮想NICが設定されています。
このインターフェースは、VirtualBox でいうNATとホストオンリーに近い性質です。
VMからホスト外部と通信するときは、ホストのIPアドレスにNATされます (≒NAT)。
ただし、ホスト-VM間、VM同士の通信も可能です (≒ホストオンリー)。
仮想NICは、以下のコマンドで一覧表示できます。
virsh net-list # Name State Autostart Persistent # -------------------------------------------- # default active yes yes
仮想NICの設定は、以下のコマンドで表示・編集できます。
virsh net-edit default # <network> # <name>default</name> # <uuid>b130cf72-a5eb-4414-9fd8-7d1182f2b50b</uuid> # <forward mode='nat'/> # <bridge name='virbr0' stp='on' delay='0'/> # <mac address='52:54:00:96:e6:67'/> # <ip address='192.168.122.1' netmask='255.255.255.0'> # <dhcp> # <range start='192.168.122.2' end='192.168.122.254'/> # </dhcp> # </ip> # </network>
この先はお好みですが、私の環境では上記 virsh net-edit
コマンドから、以下の設定のみ変更しました。
これにより、192.168.122.2〜192.168.122.100
は静的なIPアドレスをアサインできるようになります。
<range start='192.168.122.101' end='192.168.122.254'/>
変更した場合、設定を反映するためにNICを再起動します。
virsh net-destroy default virsh net-start default
(参考) おすすめの動画 / 記事
前の記事にも貼りましたが、オススメの動画を紹介させてください。
内容は英語でArch Linuxをベースとした解説ですが、テンポ良く進むので眠くならずに見れると思います。
紹介されている内容は、本記事とほぼ同様です。
(本記事を書き上げて2ヶ月後に以下の動画を見つけました。もっと早く観ていれば私も楽にKVMを理解できたと思うと悔やまれます...。そのぐらい良い動画です)
動画とブログはどちらも同じ作者によるものです。
ブログはこちら:Linux Hypervisor Setup (libvirt/qemu/kvm)
まとめ
本記事では、QEMU+KVMのインストール方法、libvirt CLI (virsh, virt-install) によるVMの作成、KVMの動作確認の手順を紹介しました。
QEMUやlibvirtのインストールコマンドはほんの数行です。
ただ、KVMベースのVMが動作するための条件は複数あり、条件を満たすための初期設定やトラブル切り分けは長く、複雑です。
Linux PC 構築関連リンク集
次の記事
libvirtベースのGUIの一つであるCockpitのインストール方法と画面構成について紹介します。
Cockpit は機能拡充中のステータスであるものの、使い勝手がよいのでオススメできます。
デスクトップ環境がある場合は、Virtual Machine Managerも多機能でオススメです。
virshと遜色ない機能性を誇ります。
VM作成/削除、CMROM挿入、起動順序設定などの基本操作のまとめは、以下の記事を参照ください。
CLI/GUIの両方についてまとめてあります。