前の記事
本記事では、KVMの初期設定が完了していることを前提としています。
初期設定手順に興味のある方は、以下の記事もご参照ください。
virt-manager、Cockpitのセットアップについては、以下の記事をご参照ください。
お伝えしたいこと
KVMの基本操作をケース別に紹介します。
基本はCLIの手順紹介がメインです。
virt-managerとCockpitのスクリーンショットも載せていますが、今後画面のデザインが変わっても原則更新しません。
GUIの手順については、雰囲気を掴むためのおまけと思っていただければ幸いです。
- 前の記事
- お伝えしたいこと
- VMの作成
- VMの削除
- VMの起動
- VMの停止
- VMのクローン
- CDドライブにISOファイルをセットする
- 起動順序の設定
- 仮想ネットワークの作成
- ストレージプールの作成
- 仮想ディスクイメージファイルの拡張
- (参考) DHCPで割り当てているIPアドレスの一覧表示
- まとめ
VMの作成
virt-installで行う場合
過去記事を参照してください。
virt-managerで行う場合
過去記事を参照してください。
Cockpitで行う場合
過去記事を参照してください。
VMの削除
virshで行う場合
過去記事を参照してください。
virt-managerで行う場合
VMを右クリックして "Delete" します。
Cockpitで行う場合
仮想マシン一覧の画面で … をクリックして "Delete" します。
VMの起動
virshで行う場合
VMの起動にはvirsh start
を使います。
コマンドがわかりやすいので、普段GUIを使っていてもvirsh start
だけはCLIといった使い方ができるかなと思います。
virsh start vm_name
以下に具体例を示します。
# VMの一覧を表示 virsh list --all # - fedora33 shut off virsh start fedora33 # Domain 'fedora33' started
virt-managerで行う場合
トップ画面で対象のVMを右クリック → Runで起動します。
Cockpitで行う場合
仮想マシン一覧の画面で対象のVMを探し、"Run"をクリックします。
VMの停止
virshで行う場合
VMの停止にはvirsh shutdown
を使います。
このコマンドはshutdownシーケンスがちゃんと走るので、VMに優しいです。
VMがハングしている場合や、OSインストール画面などOS起動前の状態など、shutdownを受け付けないケースもありえます。
そんなときは、virsh destroy
を使います。
destroy
というとVMを破壊しそうですが、実際にはVMの強制終了を意味します。
ニュアンスとしては「VMプロセスをdestroy (kill) する」のであって、VMのXML定義ファイルには触れません。
virsh shutdown fedora33
virsh destroy fedora33
virt-managerで行う場合
トップ画面で対象のVMを右クリック → Shut Down → Shut Down でシャットダウンします。
右クリック → Shut Down → Forced Off で強制終了します。
Cockpitで行う場合
仮想マシン一覧の画面で対象のVMを探し、Shut downでVMをシャットダウンします。
… をクリックして "Force shut down" でVMを強制終了します。
VMのクローン
virt-cloneで行う場合
virt-clone
コマンドでクローンできます。
前提として、まずはVM名を調べておきます。
virsh list
はデフォルトで起動しているVMしか表示しませんが、--all
をつけることで全てのVMを表示できます。
virsh list --all # Id Name State # --------------------------- # - fedora33 shut off
fedora33
というVMをクローンします。
新しいVMの名前は、f33_new
とします。
virt-clone --original fedora33 --name f33_new --auto-clone # Allocating 'f33_new.qcow2' | 20 GB 00:00:05 # Clone 'f33_new' created successfully.
virt-clone
の主なオプションは以下のとおりです。
--original
でコピー元のVM名、--name
でコピー先のVM名、--file
でコピー先のVMイメージファイルのフルパスを指定するのが基本です。
個人的には、上記のように--name
と--auto-clone
を併用し、イメージファイル名を--name
で指定した文字列から自動生成させるのが便利に感じました。
オプション | 意味 |
---|---|
-o, --original |
コピー元のVM名を指定 |
-n, --name |
コピー先のVM名を指定 |
-f, --file |
コピー先のVMが利用するディスクイメージファイルのフルパスを指定 |
--auto-clone | --name 、--file の片方または両方を自動的に決定する。--name を自動生成するときは、fedora33-clone のように-clone をつける。更にクローンすると、 fedora33-clone-1 , fedora33-clone-2 , ... と連番をつける。--file を自動補完した場合、default プール配下にVM名.qcow2 が生成した(※)。--name のみ明示的に指定した場合は、イメージファイル名の自動補完には--name の文字列が使用された(※) |
(※) man virt-clone
にはこの仕様は書いていません。私の環境で実機検証した結果、このようになりました
virt-clone
はvirt-install
パッケージに同梱されています。
dnf provides virt-clone
や、dnf repoquery -l virt-install
などで確認できます。
virt-managerで行う場合
VM名を右クリックして "Clone" します。
Cockpitで行う場合
仮想マシン一覧の画面で … をクリックして "Clone" します。
CDドライブにISOファイルをセットする
virshで行う場合
まずはVM名を指定して、紐付いているデバイス名を確認します。
VM名を調べたい場合は、virsh list --all
を先に実行してください。
以下のコマンド出力から、sdaにCDドライブが存在することがわかりました。
virsh domblklist fedora33 --details # Type Device Target Source # ------------------------------------------------------------------- # file disk vda /home/shared/libvirt/disks/fedora33.qcow2 # file cdrom sda - # file cdrom sdb -
virsh change-media
コマンドにより、CDROMにISOファイルをセットします。
virsh change-media fedora33 sda /home/shared/isos/fedora/Fedora-Server-dvd-x86_64-33-1.2.iso # Successfully updated media.
もう一度確認コマンドを実行し、ISOファイルがセットされたことを確認します。
virsh domblklist fedora33 --details # Type Device Target Source # ----------------------------------------------------------------------------------------- # file disk vda /home/shared/libvirt/disks/fedora33.qcow2 # file cdrom sda /home/shared/isos/fedora/Fedora-Server-dvd-x86_64-33-1.2.iso # file cdrom sdb -
virsh change-media
の構文は以下のとおりです。
virsh change-media domain-name path [--eject|--insert|--update] [source]
キーワードの意味は下表のとおりです。
キーワード | 説明 |
---|---|
domain-name | domain、つまりVMの名前 |
path | 捜査対象のCDドライブのデバイス名。 sda, vda, hda などの文字列が入る |
--eject | CDドライブの中身を空にする。 sourceの指定は不要 |
--insert | CDドライブにISOファイルをセットする。 sourceの指定は必須 |
--update | sourceを指定した場合、--ejectしてから--insertする。 sourceを指定しなかった場合、--ejectのみ実行する。 --eject, --insert, --update をいずれも指定しなかった場合、デフォルトで--updateが選択される |
source | ISOファイルを指定する。 --ejectを指定した場合は、sourceの入力は不要。 --insertを指定した場合はsourceの入力は必須。 --updateを指定した場合は、sourceを入力するか否かで挙動が変わる |
virt-managerで行う場合
VMの詳細画面で、"SATA CDROM"からISOファイルのパスを指定します。
Cockpitで行う場合
仮想マシン一覧の画面で、捜査対象の仮想マシン名をクリックして詳細画面を開きます。
中段の "Disks" セクションの "Add disk" をクリックし、以下のように選択します。
設定項目 | 詳細 |
---|---|
Source | Custom path |
Custom path | (ISOファイルのパス) |
Device | CD/DVD dusk |
起動順序の設定
virshで行う場合
HDD、CDドライブなど複数のディスクを持ったVMを起動する際の起動順序の制御方法を紹介します。
起動順序を制御するためのvirshサブコマンドは、2021年時点では存在しないようです。
従って、virsh edit VM_NAME
でXMLファイルを直接編集します。
編集は以下のように行います。
<os>
セクション配下の<boot>
セクションを削除する<disk>
セクション配下に<boot order>
セクションを追加する
例えば、編集前のファイルが以下の状態だったとします。
(中略) <os> <type arch='x86_64' machine='pc-q35-5.1'>hvm</type> <boot dev='hd'/> </os> (中略) <devices> <emulator>/usr/bin/qemu-system-x86_64</emulator> <disk type='file' device='disk'> <driver name='qemu' type='qcow2'/> <source file='/home/shared/libvirt/disks/fedora33.qcow2'/> <backingStore/> <target dev='vda' bus='virtio'/> <address type='pci' domain='0x0000' bus='0x04' slot='0x00' function='0x0'/> </disk> <disk type='file' device='cdrom'> <driver name='qemu' type='raw'/> <target dev='sda' bus='sata'/> <readonly/> <address type='drive' controller='0' bus='0' target='0' unit='0'/> </disk> (中略)
編集後のファイルは、以下のようになります。
<os>
配下の<boot>
を削除し、<disk>
配下に<boot order>
を追加しました。
<boot order>
には'1'
以上の値を指定し、値が小さいほど優先順位が高くなります。
今回の場合は、device='disk'
が第一優先で、device='cdrom'
が第二優先になっています。
<boot order>
が付いていないデバイスは、そもそも起動デバイスの候補から外れます。
(中略) <os> <type arch='x86_64' machine='pc-q35-5.1'>hvm</type> </os> (中略) <devices> <emulator>/usr/bin/qemu-system-x86_64</emulator> <disk type='file' device='disk'> <driver name='qemu' type='qcow2'/> <source file='/home/shared/libvirt/disks/fedora33.qcow2'/> <backingStore/> <target dev='vda' bus='virtio'/> <address type='pci' domain='0x0000' bus='0x04' slot='0x00' function='0x0'/> <boot order='1'/> </disk> <disk type='file' device='cdrom'> <driver name='qemu' type='raw'/> <target dev='sda' bus='sata'/> <readonly/> <address type='drive' controller='0' bus='0' target='0' unit='0'/> <boot order='2'/> </disk>
手順としては以上です。
最後に、libvirt公式サイトのリンクを貼ります。
公式に書いてあるように、<boot order>
が使えるかどうかはハイパーバイザー次第のようです。
幸いにも、QEMUは<boot order>
に対応していました。
<boot order>
より以前にある指定方法として<boot>
もありますが、こちらは理由がなければ基本使いません。
Disk、CDといった粒度で起動の優先順位を指定することはできますが、Diskが2つ以上存在した時、どちらのDiskを使うかの挙動が複雑です。
可能な限り、DiskやCDが同種類で複数存在する場合でも優先順位を指定できる<boot order>
を使うようにしましょう。
<boot>
に関する情報は以下のリンクにあります。
virt-managerで行う場合
GUIを使えば、virshよりも簡単な操作で設定できます。
以下のVMの設定画面で、起動デバイスに設定したいデバイスにチェックを入れ、▲▼
で優先順位を指定するだけです。
※以下の画像は▲▼
が黒くて見えづらいので若干合成してあります
Cockpitで行う場合
仮想マシンの詳細画面を開き、"Boot order" の "edit" をクリックして編集するだけです。
こちらも簡単ですね。
仮想ネットワークの作成
概要
仮想ネットワークにはいくつかのタイプがあります。
私が使ったことがあるのは、以下の2種類です。
多くの場合はNATのみで事足りますが、VM間通信用のネットワークセグメントを複数作成したい場合はNoneのネットワークも1つ追加すると便利です。
また、仮想ネットワーク内でDHCPを使うことができます。
DHCPにより、作成したVMに自動的にIPアドレスやデフォルトゲートウェイの設定を配布できます。
ネットワークサイズが/24だとすると、DHCPアドレスを.101〜.254のようにしておくと、.2〜.100を静的に割り当てることもできるので便利です。
.1はゲートウェイのアドレスに使われるので、この部分は残しておきます。
さて、以降で具体的な手順に入ります。
virshで行う場合
CLIの手順はlibvirt wikiを参考にしました。
net-create
というコマンドがありますが、xmlファイルを指定することでしか作成できません。
従って、基本的には既存のXMLファイルを雛形にして編集することになると思います。
まず、virsh net-list --all
で仮想ネットワーク名を確認します。
--all
をつけることで、起動していない仮想ネットワークも表示します。
virsh net-list --all # Name State Autostart Persistent # ---------------------------------------------- # default active yes yes # internal1 active yes yes
新規の仮想ネットワークを作る場合は、/usr/share/libvirt/networks/default.xml
を雛形にすると便利です。
以下のようにXMLファイルをコピーします。
cp /usr/share/libvirt/networks/default.xml tmp.xml cat tmp.xml # <network> # <name>default</name> # <bridge name="virbr0"/> # <forward/> # <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-dumpxml
で既存の仮想ネットワークのXMLファイルをtmp.xml
として保存しておきます。
virsh net-dumpxml default | tee tmp.xml # <network connections='1'> # <name>default</name> # <uuid>b130cf72-a5eb-4414-9fd8-7d1182f2b50b</uuid> # <forward mode='nat'> # <nat> # <port start='1024' end='65535'/> # </nat> # </forward> # <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.101' end='192.168.122.254'/> # </dhcp> # </ip> # </network>
<name>
と<domain name
を仮想ネットワーク名に変更します。
(※) domain name
の行は、場合によっては存在しないこともあります
<uuid>
、<bridge name
、<mac address
の行を削除します。
これらの値はlibvirtによって重複しない値を自動生成させます。
書き換え後の例を以下に示します。
ちなみにlibvirt wikiによると、<forward/>
の部分は<forward mode='nat'/>
がデフォルト値となります。
NATモードではなく、None (Isolated) モードにしたい場合は、<forward/>
行を削除してください。
cat tmp.xml # <network> # <name>tmp</name> # <forward/> # <ip address="192.168.200.1" netmask="255.255.255.0"> # <dhcp> # <range start="192.168.200.101" end="192.168.200.254"/> # </dhcp> # </ip> # </network>
以下のコマンドにより、仮想ネットワークを作成します。
net-define
コマンドの場合は、XMLファイルとして構成を保持します。
net-define
をnet-create
に置き換えることで、undefined状態 (メモリ上にしか存在せず、destroyすると直ちに消える) の仮想ネットワークを作成することもできます。
virsh net-define tmp.xml
# Network tmp defined from tmp.xml
作成したtmpの情報を表示します。
net-list
の出力より、tmpの定義直後はまだ起動しておらず、OSブート時に自動起動もしないことがわかります。
net-dumpxml
の出力より、UUIDやMACアドレスの値、NAT設定などが自動生成していることがわかります。
virsh net-list --all # Name State Autostart Persistent # ------------------------------------------------ # default active yes yes # internal1 active yes yes # tmp inactive no yes virsh net-info tmp # Name: tmp # UUID: 3bfd3e32-9531-4e67-a2b0-963df9f4cc85 # Active: yes # Persistent: yes # Autostart: no # Bridge: virbr2 virsh net-dumpxml tmp # <network> # <name>tmp</name> # <uuid>85a1cccf-dc54-4164-8e72-a6f020b4883c</uuid> # <forward mode='nat'/> # <bridge name='virbr2' stp='on' delay='0'/> # <mac address='52:54:00:55:21:d6'/> # <ip address='192.168.200.1' netmask='255.255.255.0'> # <dhcp> # <range start='192.168.200.101' end='192.168.200.254'/> # </dhcp> # </ip> # </network>
以下のコマンドによって仮想ネットワークを起動し、通信可能な状態にします。
更に、自動起動も有効化します。
virsh net-start tmp # Network tmp started virsh net-autostart tmp # Network tmp marked as autostarted
再び確認コマンドで表示します。
State=active, Autostart=yesとなりました。
virsh net-list --all # Name State Autostart Persistent # ---------------------------------------------- # default active yes yes # internal1 active yes yes # tmp active yes yes
仮想ネットワークを削除する際は、destroy (強制終了。startの反対) とundefine (設定削除。defineの反対) を行います。
virsh net-destroy tmp # Network tmp destroyed virsh net-undefine tmp # Network tmp has been undefined
削除後、tmpが表示されなくなることを確認します。
virsh net-list --all # Name State Autostart Persistent # ---------------------------------------------- # default active yes yes # internal1 active yes yes
virt-managerで行う場合
トップ画面において、コネクション、またはコネクション配下のVMを選択した状態で、上部メニューからEdit > Connection Details
を開きます。
または、下図赤枠部分のコネクション名の部分を右クリックして、Details
を選択します。
Virtual Networks
タブを開き、左下の+ボタンから仮想ネットワークを追加します。
※以下の画像は+-
が黒くて見えづらいので若干合成してあります
Cockpitで行う場合
仮想マシン一覧から、右上の"Networks"を選択します。
右上の"Create virtual network"を選択します。
必要事項を入力して、Createします。
Cockpit 249では、Forward modeがNAT、Open、None (isolated mode) の3種類しか選べませんでした。
将来的にアップデートされるとは思いますが、もし機能的に困る場合はvirshかvirt-managerを使うようにしてください。
私の検証用途では凝ったことはしないので、私としてはそれほど困りませんでした。
ストレージプールの作成
ストレージプールという言葉自体の解説は、KVMの初期設定、及びvirsh, virt-installによるVM作成 - pool作成の事前準備を参照してください。
virshで行う場合
以下のコマンドでPoolを定義します。
Pool名、Poolと紐付けるディレクトリパスは適宜変更してください。
virsh pool-define-as kickstart dir --target /home/shared/libvirt/kickstarts
virsh pool-define-as
のSyntaxは以下のとおりです。
パラメータ | 意味 |
---|---|
kickstart (第一引数) |
Pool名 |
dir (第二引数) |
Pool Type名。 他にも fs やdisk など多数あるが、本ブログで紹介したのはdir のみ (参考) |
--target .. |
dir Typeの場合は指定必須。Poolと紐付けるディレクトリパスを指定する |
作成したPoolを確認します。
作成直後のPoolは停止しているので、--all
オプションをつけることで停止中のPoolも含めて表示します。
virsh pool-list --all # Name State Autostart # --------------------------------- # default active yes # kickstart inactive no
Poolを今すぐ起動します。
また、Autostartを有効化することで、OS起動時にPoolも自動起動するように設定します。
virsh pool-start kickstart # Pool kickstart started virsh pool-autostart kickstart # Pool kickstart marked as autostarted
Poolの状態を再度確認します。
Poolが起動状態になり、Autostartも有効化されました。
virsh pool-list # Name State Autostart # --------------------------------- # default active yes # kickstart active yes
Poolの停止はvirsh pool-destroy kickstart
、Poolの定義削除はvirsh pool-undefine kickstart
コマンドにて行います。
virt-managerで行う場合
トップ画面において、コネクション、またはコネクション配下のVMを選択した状態で、上部メニューからEdit > Connection Details
を開きます。
または、下図赤枠部分のコネクション名の部分を右クリックして、Details
を選択します。
Storage
タブを開き、左下の+
マークを選択します。
必要なパラメータを入力し、Finish
を選択します。
Cockpitで行う場合
仮想マシン一覧の画面で、左上にあるStorage poolsのリンクをクリックし、Pool一覧の画面を開きます。
画面右上のCreate storage poolをクリックし、Pool作成画面を開きます。
必要なパラメータを指定してPoolを作成します。
以下は/home/shared/libvirt/kickstarts/
ディレクトリと紐づく、kickstart
という名前のPoolを作成する例です。
Activateボタンをクリックし、作成したPoolを起動します。
仮想ディスクイメージファイルの拡張
ディスクファイル (qcow2) のサイズ変更は、2021/11時点ではCLIでしかできないようです。
したがって、virshの手順のみ紹介します。
virshで行う場合
Linuxのディスク拡張手順 #qcow2ファイルの拡張を参照してください。
(参考) DHCPで割り当てているIPアドレスの一覧表示
virshで行う場合
virsh net-dhcp-leases <network-name>
でDHCPリースしているIPアドレスを一覧表示できます。
VMのIPアドレスをDHCPで設定しているとき、VMにSSHする前にIPアドレスを調べる際に便利です。
ネットワークの一覧はvirsh net-list
で確認できますが、多くの場合はdefault
を使っているのではないかと思います。
virsh net-dhcp-leases default # Expiry Time MAC address Protocol IP address Hostname Client ID or DUID # ------------------------------------------------------------------------------------------------------ # 2022-02-27 13:41:03 52:54:00:6c:54:c8 ipv4 192.168.122.127/24 stream9-1 01:52:54:00:6c:54:c8
よく使うコマンドなので、ワンライナーをaliasとして登録するのも便利かもしれません。
私の環境では、以下の内容を~/.bashrc
に登録しています。
alias ips=$'virsh net-dhcp-leases default | sed -ne \'3,$p\' | grep -v ^$ | awk \'gsub(/\/[0-9]+/, "", $0) { print $6,$5 }\''
実行すると以下のようになります。
短い入力でコピペしやすいシンプルな出力が得られます。
ips
# stream9-1 192.168.122.127
上記はANSI C Quoting ($' '
)を使っています。
通常のシングルクォーテーション (' '
)と比較して、シングルクォーテーション自体を \'
でエスケープできるのが便利なので使っています。
bash以外の環境ではANSI C Quotingが使えないかもしれないので、ダブルクォーテーションを使ったパターンも併記しておきます。
ダブルクォーテーションを使う場合は$"\
、そしてバックティックもエスケープ対象になるので、少々見づらくなります。
(参考: Double Quotes)
#alias ips="virsh net-dhcp-leases default | sed -ne '3,\$p' | grep -v ^\$ | awk 'gsub(/\/[0-9]+/, \"\", \$0) { print \$6,\$5 }'"
virt-managerで行う場合
virt-managerには、DHCPリースを一覧表示する機能は無いようです。
仮想マシンの詳細設定画面でNICの項目から読み取ることはできます。
しかし、仮想マシン1台分の情報しか確認できません。
Cockpitで行う場合
Cockpitには、DHCPリースを一覧表示する機能は無いようです。
仮想マシンの詳細設定画面でNetwork Interfacesの項目から読み取ることはできます。
しかし、仮想マシン1台分の情報しか確認できません。
まとめ
KVM周りの各種基本操作についてご紹介しました。
慣れないうちはGUIで、慣れてきたらVMの起動/停止など簡単な部分からCLIに移行し、徐々に作業効率を上げていきましょう。