引用元:linux-kvm.org
前の記事
前回はKVM , QEMU , libvirt の概要について紹介しました。
endy-tech.hatenablog.jp
お伝えしたいこと
本記事では、KVM +QEMU による仮想化システムのインストール手順と、libvirt CLI (virt-install , virsh) によるVM 作成手順を紹介します。
その後、KVM が本当に正しく構成されているのかを確認する手順と、正しく構成されていなかった場合の対処法について紹介します。
libvirt ベースのCLI /GUI ツールの概要については、前の記事のlibvirt を利用している製品 を先にお読みください。
libvirt ベースのGUI ツールについては、次の記事で紹介します。
QEMU 、KVM 、libvirt のインストールは非常に簡単です。
ただ、libvirt の初期設定、使い方、KVM が動かない時のトラブルシューティング を含めた結果、記事が長くなってしまいました。
手順上読まなくても問題ない部分には (参考) をつけましたので、不要と感じたら読み飛ばしてください。
本記事の末尾 にオススメの解説動画も貼りました。
Arch Linux をモデルとした内容ですが、本記事と同様の紹介がされています。
文字よりも動画がお好みの方は、ぜひチェックしてみてください。
動画中の解説は英語です。
日本語がお好みでしたら、やはり私の記事を読んでください!
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
と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/
今回は、デスクトップ環境がなくても動作するCLI にて今回は進めたいと思います。
必要に応じて、GUI ツールを後から追加インストールすることも可能です。
どのGUI ツールをインストールしたとしても、必ず依存関係でCLI ツールもインストールされます。
一旦GUI ツールのことは気にしないこととして、先に進みましょう。
以下のコマンドで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
ユーザーグループの設定
libvirt をqemu:///system
セッションで使うにあたり、libvirt を利用するユーザーをlibvirt グループに所属させる必要があります。
qemu :///system の意味については(参考) qemu:///system と qemu:///session の違い で、グループ設定が必要な理由は1. libvirtグループへの所属 で補足します。
以下のコマンドによって、現在のユーザーがlibvirtd特権プロセスにアクセスするための権限を付与します。
usermod --append --groups libvirt `whoami`
(任意) qemu :///system をデフォルトにする
毎回 --connect
を指定するのは面倒なので、デフォルト値を指定します。
この手順は必須ではありません。
qemu:///system
を使っている方のみ任意で実施してください。
qemu:///session
を使っている方は、既にqemu:///session
が一般ユーザーのデフォルト値なので、本セクションの手順は実施不要です。
~/.config/libvirt/libvirt.conf
を作成し、以下のように記述します。
uri_default = " qemu:///system "
以下のコマンドにより、QEMU が接続するハイパーバイザーのURI を確認します。
virsh uri
以下のようにエラーが出た場合、#libvirtdの起動 の手順を忘れている可能性があります。
リンク先を参照して対処してください。
virsh uri
ここで設定を入れた方は、以降の手順で--connect qemu:///system
オプションを省略しても問題ありません。
本記事の解説においても、以降は--connect qemu:///system
の記載は省略します。
ちなみに、Virtual Machine Managerのデフォルト値はqemu:///system
です。
Virtual Machine Managerとvirshで見えるVM やpoolなどが異なる場合は、利用しているConnectionが異なる可能性があるので注意してください。
このあたりは最初にハマりがちな罠だったりします。
Virtual Machine Manager側の設定方法は、Virtual Machine Manager GUI によるKVM操作 #URIの指定 を参照してください。
(参考) デフォルト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/images/
にディスクイメージファイルを、/home/shared/libvirt/images/isos/
にISOイメージファイルを保存します。
/home/shared/images/isos/
配下は、rhel
やubuntu
などお好みでフォルダ分けします。
/home/shared
は、shared
グループに属するユーザーであれば誰でもアクセス可能なディレクト リとして作成します。
qemu
ユーザーもshared
グループに属すように設定します。
(※) 私の環境はパソコン用途を想定しているため、/home
のファイルシステム 容量を大きくしています。したがって、/home
配下にイメージファイルやVMDKファイルなどの大容量ファイルを置くために、今回のようなフォルダ構成としました。なおご参考までに、libvirt-daemon
RPM パッケージをインストールすると/var/lib/libvirt/images
をデフォルトで生成します。今回のフォルダ構成は自分なりにアレンジを加えたものの、libvirt/images/
というフォルダの切り方はデフォルト構成を踏襲しました。ファイルシステム の設計は皆様それぞれだと思いますので、自分の環境にあった置き場所をご検討ください。
以下のコマンドで上述の構成にできますので、よろしければそのままご利用ください。
sudo groupadd shared
sudo usermod --append --groups shared $( whoami )
sudo usermod --append --groups shared qemu
sudo mkdir -p /home/shared/libvirt/images/iso
sudo chown -R root:shared /home/shared/
sudo chmod -R o-rwx /home/shared/
pool 作成
まず、pool を定義 (define) します。
このコマンドにより pool の構成情報を記述したXML ファイルが生成し、libvirt によって管理されるようになります。
本記事はvirshの紹介記事なのでCLI で実施していますが、GUI 環境があればvirt-manager やcockpitからもpoolの作成は可能です。
virsh \
pool-define-as default dir \
--target /home/shared/images/
defineなどの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-start images
virsh pool-auto-start default
virsh pool-auto-start images
pool の確認
最後に、作成したpool を確認します。
pool を一覧表示するには、pool-list
を使います。
デフォルトでは起動していない pool が表示されないので、全て表示したい時は --all
もつけます。
--details
で詳細表示できます。
pool の完全な設定情報を確認したい場合は、 pool-edit
を実行します。
pool-edit
は構成情報のXML を開くので、ステータスは確認できませんが設定情報は全て確認できます。
XML を編集して保存すると設定が書き換わるので、注意してください。
virsh pool-list
virsh pool-edit default
virsh pool-edit images
(参考) pool の停止・削除
この手順は基本実施不要です。
もしpool を間違えて作ってしまい、削除したくなったときは以下の流れで実施します。
pool の停止 (destroy)
pool の削除 (undefine)
補足ですが、VM の通常停止を shutdown 、強制停止(VM のプロセス kill) をdestroy と呼びます。
pool の停止の場合は、常に destroy と呼ばれます。
VM /pool の削除は undefine と呼びます。
pool 作成時に実施した define の反対で、XML ファイルを削除します。
削除操作は、対象を停止させた上で実施する必要があります。
コマンドとしては、以下のようになります。
ISOファイルの準備
VM を作成するのに必要なISOファイルをダウンロードし、上記の手順で作成した pool の target directory に格納してください。
その際、ISOファイルのパーミッション に注意してください。
ISOファイルは、qemu ユーザーによってアクセスできる必要があります。
本ブログに従ってディレクト リを構成した場合は、以下の2コマンドを実行することで適切に権限設定できます。
sudo chown -R root:shared /home/shared/
sudo chmod -R o-rwx /home/shared/
VM を作成するには、以下のコマンドを実行します。
紹介しているコマンドは例ですので、環境によって一部変更してください。
virt-install \
--name test \
--memory 1024 \
--vcpus 2 \
--disk size =8 \
--cdrom /home/shared/libvirt/images/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単位で指定する
--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が起動した後にプロンプトが戻ってくるようにするのが良い
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 の動作確認ができたら、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 &
でコンソール接続する使い方が動線 としてはスムーズかなと思います。
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についてより詳細を知りたい方は、以下の記事を参照してください。
endy-tech.hatenablog.jp
(参考) 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
デスクトップのメニューから "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 の停止は、以下の2種類があります。
通常停止(shutdown): VM にshutdown するよう命令を送る
強制停止(destroy): VM プロセスを kill する (≒電源長押しによる停止)
強制停止は、何らかの理由で (※) 通常停止ができない場合のみ使うイメージです。
経験上、作成したばかりのVM でOSが未インストールの場合はshutdownを受け付けないので、destroyで強制停止します。
これから削除するVM に対しては、気軽に強制停止しても問題ありません。
(※) VM が無応答だったり、KVM ではなくQEMU 単体で動作している場合はshutdownできないこともあります
virsh shutdown 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ファイルまで削除されてしまうので、このオプションはあまり使いません。
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/images/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) へのアクセス権限があると断定できない場合に発生します。
今回の構成ではshared
グループによってqemu に権限を与えているのですが、どうやらlibvirt はグループの中身までは見てくれないようです。
対応策は、考えうる限り3案あります。
私は案1で対処しました。
案1. ACL によって明示的にqemu ユーザーに権限を割り当てる
ACL については、@ITの記事 がわかりやすかったです。
以下のように、ISOファイルとディスクファイルを格納している各ディレクト リの中身が見えるように権限設定すれば、警告は回避できます。
1行目と3行目ではディレクト リの場合のみ、qemu ユーザに対してrwx
権限を与えています。
2行目では全ファイルにおいて、qemu ユーザに対してrw
権限を与えています。
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
以下のコマンドで設定内容を確認します。
ls -ld
は、+
フラグがつくところが確認ポイントです。
ls -ld /home/shared/
getfacl /home/shared/
getfacl /home/shared/libvirt/
操作を取り消したい場合は、以下のコマンドでACL を削除できます。
ACL の弱点は、chmodの実装よりもわかりづらくなるところですね。
この操作は該当のディレクト リにファイルを配置する度に実行する必要があるので、私の環境では/home/shared/set_permissions.sh
に以下のスクリプト を配置しています。
ファイルを配置する度にシェルスクリプト を実行すれば、いい感じに権限が付与されます。
ご利用の際は、事前に中身を理解するようにしてください。
set -o errexit
set -o nounset
set -o pipefail
sudo chown -R root:shared /home/shared/
sudo chmod -R g+rw,o-rwx /home/shared/
sudo setfacl -Pm u:qemu:rwx /home/shared/
sudo setfacl -PRm user:qemu:rw /home/shared/libvirt/
find /home/shared/libvirt/ -type d | sudo xargs setfacl -Pm user:qemu:rwx
ACL を使わず、chown でqemu ユーザーをディレクト リのオーナーにすることでも回避できます。
私の場合は、以下の理由で案2は不採用としました。
共有ディレクト リ /home/shared
にファイルを置きたい
/home/shared
のオーナーを qemu:shared
にするのは少し抵抗があった。root:shared
にしておきたい
案3. 無視する
悪影響のないメッセージなので単純に無視するのも一つの手です。
virshとVirtual Machine Manager では警告が出ますが、Cockpit の場合は警告は出ません。
正直、案3. でも全く問題ありません。
グループによって権限を与えているのであれば、本来は警告メッセージが出る方がおかしいのですから。
ERROR Guest name 'test' is already in use.
既に 'test' という名前のVM が存在しています。
virsh list --all
で確認できます。
対処方法はVM の名前を被らないようにするか、VM を削除することが挙げられます。
VM を削除する場合は、事前にブロックデバイス 名を確認します (vda/hda)。
virsh domblklist test
続いて、VM を削除します。
その際、--storage
オプションで一緒に削除したいブロックデバイス 名を指定します(vda/hda)。
virsh destroy test
virsh undefine --storage vda test
本記事の手順を実施してもKVM が動作しなかった場合は、以下の情報を参考にしてみてください。
私の環境 (NUC10 +Fedora32) では運良く全くトラブルが発生しなかったので、紹介する内容は全て未検証であり、机上で調査した情報になります。
KVMを利用するには、以下の条件を満たしている必要があります。
CPUが仮想化支援機能をサポートしていること
BIOS が仮想化支援機能を無効化していないこと
KVM カーネル モジュールがロードされていること
/dev/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
WARNの解消については現在のところ特に調べていませんが、libvirt.orgでcgroupを検索すると 、cgroupに関するページ がヒットしました。
ここを読めば、何かがわかるかもしれません。
CPUが仮想化支援機能をサポートしていること
確認手順
以下のコマンドを実行して文字列が表示されれば、CPUが仮想化支援機能をサポートしているので問題ありません。
VMXはIntel VT-x、SVM はAMD -V と紐づく言葉であり、どちらもCPUの仮想化支援機能を表す言葉です。
egrep -o ' (vmx|svm) ' /proc/cpuinfo
対処法
もし上記フラグが出てこなかった場合、以下 も併せてご確認ください。
uname -r
からカーネル バージョンを確認する
Intel 製CPUの場合は 2.6.15以上、AMD 製CPUの場合は 2.6.16 以上でないと、/proc/cpuinfo にフラグが出ない仕様
Xen カーネル を使っている場合は、仮想化支援機能が無効化される仕様
上記を確認してもおかしいと感じた場合は、後述の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
対処法
まず、Intel かAMD のCPUを使っていない場合には、kvm しか表示されなくても問題ない可能性があります。
IBM POWER8 か IBM POWER9 の場合はこちら をご確認ください。
IBM Zの場合はこちら をご確認ください。
(無いと信じたいですが) 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
grep kvm /etc/group
なお、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 "
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
は公式で推奨されていますし、こちらのほうがトラブルを踏みにくいと感じたためです。
次のセクションで両者の違いを簡単に紹介します。
両者の違いを紹介するにあたり、以下の記事を参考にしました。
qemu :///system
rootユーザによって起動されたlibvirtdデーモンを介してVM を操作します。
libvirt がシステムのリソースにアクセスするために必要な権限を一通り持つため、基本的には何でもできます。
ちなみに、qemu:///system
は、rootユーザーのユーザーセッションでもあります。
すなわち、sudo virsh --connect qemu:///session list
と仮に実行したとしても、sudo virsh list
と同じ意味になります。
このことからもqemu:///system
は特権と同等であるということがわかります。
qemu:///system
を利用するには、必要な設定が2つあります。
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つ目の注意点として、イメージファイルのパーミッション が挙げられます。
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を理解しやすくなります。
公式の図 が非常にわかりやすいです。
引用元:libvirt.org: States that a guest domain can be in
特に、以下の用語を抑えておくことが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
仮想NIC の設定は、以下のコマンドで表示・編集できます。
virsh net-edit default
この先はお好みですが、私の環境では上記 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 を理解できたと思うと悔やまれます...。そのぐらい良い動画です)
動画とブログはどちらも同じ作者によるものです。
VIDEO
ブログはこちら:Linux Hypervisor Setup (libvirt/qemu/kvm)
まとめ
本記事では、QEMU +KVM のインストール方法、libvirt CLI (virsh, virt-install ) によるVM の作成、KVM の動作確認の手順を紹介しました。
QEMU やlibvirt のインストールコマンドはほんの数行です。
ただ、KVM ベースのVM が動作するための条件は複数あり、条件を満たすための初期設定やトラブル切り分けは長く、複雑です。
Linux PC 構築関連リンク集
endy-tech.hatenablog.jp
次の記事
libvirt ベースのGUI の一つであるCockpitのインストール方法と画面構成について紹介します。
Cockpit は機能拡充中のステータスであるものの、使い勝手がよいのでオススメできます。
endy-tech.hatenablog.jp
デスクトップ環境がある場合は、Virtual Machine Managerも多機能でオススメです。
virshと遜色ない機能性を誇ります。
endy-tech.hatenablog.jp
VM 作成/削除、CMROM挿入、起動順序設定などの基本操作のまとめは、以下の記事を参照ください。
CLI /GUI の両方についてまとめてあります。
endy-tech.hatenablog.jp