KVMの使い方

Linuxの調査向けの用途ですが、KVMの使い方をまとめました。

1 ホストマシン上での設定

3 仮想マシンのクローン

クローンを用いた運用をお勧めします。virt-cloneを用いることで、スクリプト化が容易になります。

$ # virt-clone -o <src_vmname> -n <dst_vmname> -f <imgname>
$ virt-clone -o ubuntu-16.04 -n ubuntu-16.04-clone -f ubuntu-16.04-clone.img

virt-managerでクローンした場合と同様になるように、/var/lib/libvirt/imagesに格納しても良いでしょう。

$ sudo virt-clone -o ubuntu-16.04 -n ubuntu-16.04-clone \
-f /var/lib/libvirt/images/ubuntu-16.04-clone.img

3.1 クローンを用いた仮想マシンの運用例

筆者はLinuxについて調べる際に、以下の様な運用をしています。

  • OSインストールとopenssh-server等の設定を終えたベースとなる仮想マシンを用意する(仮想マシンイメージのサイズは80GByte)
  • ベースとなる仮想マシンをクローンする
  • bindサーバ、dhcpサーバに登録する
  • ベースとなる仮想マシンはLVMを用いており、必要に応じてボリュームを追加してLVMとファイルシステムを拡張する
  • クローンした仮想マシン上で実験的な作業を実行する
  • 作業を終えたらクローンした仮想マシンを削除する
  • bindサーバ、dhcpサーバから削除する

80GByteのボリュームを用いておりますが、ボリューム内部で使用されている領域分(4BGyte程度)のコピー時間しか発生しません。筆者の環境であるHDDを用いたホストマシンだと3分ほどでクローンされます。SSDやRAIDのストライピングを利用すれば1分以内でクローンできるでしょう。

また、スナップショットを用いるのは、ベースとなる仮想マシンをアップデートする場合です。アップデートが失敗したら元に戻し、アップデートが成功したらスナップショットを削除します。

4 仮想マシンの削除

仮想マシンを削除するにはvirshとrmを用います。

$ virsh undefine ubuntu-16.04-clone
$ rm ubuntu-16.04-clone.img # /var/lib/libvirt/images/ubuntu-16.04-clone.img

5 仮想マシンのシリアルに接続する

予め仮想マシンでGRUBとLinuxをシリアルコンソールで操作できるようにしておきます。

$ virsh console <vmname>

virshはSSH経由で実行できるのでSSH経由のシリアルコンソールで仮想マシンを操作できます。

$ ssh -q -t <server> virsh console <vmanme>

6 仮想マシンのディスプレイにVNC接続する

VNCサーバの場合はディスプレイにQXLを使えないので、VGAを使います。

0001_VGA.png

VNCサーバを使用します。

0002_VNC.png

virsh vncdisplayで仮想マシンのディスプレイ番号が分かります。

$ sudo virsh vncdisplay <vmname>
:1

$

OSXの場合は以下の様なスクリプトを用いればVNC接続できます。適時SERVERの値を変えてください。

#!/bin/sh

SERVER=acer.hiroom2.com
VIRSH="ssh -q -t ${SERVER} sudo virsh"

display=`${VIRSH} vncdisplay ${1} | sed -e 's/://g' -e 's/[ \r\n]//g'`
port=`expr 5900 + ${display}`
open vnc://${SERVER}:${port}

virt-cloneで仮想マシンをクローンした場合はVNCのパスワードが引き継がれません。XMLファイルにpasswd='password'を追加する必要があります。'password'は適時変更してください。

$ sudo virt-clone -o <src_vmname> -n <dst_vmname> -f <imgname>
$ sudo sed -i "s/keymap='ja'/keymap='ja' passwd='password'/g" \
/etc/libvirt/qemu/<dst_vmname>.xml
$ sudo systemctl restart libvirtd

7 仮想マシンの一覧を表示する

virsh listで仮想マシンの一覧を表示します。–nameオプションを用いると仮想マシンの名前のみが表示されるのでスクリプトで扱いやすいです。

$ sudo virsh list --name            # Print active domain
$ sudo virsh list --name --inactive # Print inactive domain
$ sudo virsh list --name --all      # Print all domain

例えば、全てのVMをサスペンドするのに使うことが出来ます。

$ for vm in `sudo virsh list --name --all`; do
  sleep 30;                # wait VM
  sudo virsh suspend ${vm} # Suspend VM
done

8 仮想マシンのMACアドレスを取得する

virsh dumpxmlから取り出します。

#!/bin/sh

VIRSH="sudo virsh"

mac=`${VIRSH} dumpxml ${1} | grep "mac address"`
mac=`echo ${mac} | sed s/\ *\<mac\ address=\'//g | sed s:\'/\>::g`
echo "${mac}"

9 ホストマシンの再起動時に仮想マシンをsuspend/resumeする

セキュリティアップデートやシステムバックアップの為に、ホストマシンを再起動する必要が出てきます。libvirt-guestsサービスを利用することで、ホストマシンのシャットダウン時にゲストマシンをsuspendし、ホストマシンの起動時にゲストマシンをresumeすることができます。

$ sudo systemctl enable libvirt-guests
$ sudo systemctl restart libvirt-guests

CentOS 7は以下のとおりです。

$ diff -uprN /etc/sysconfig/libvirt-guests{.org,}
--- /etc/sysconfig/libvirt-guests.org   2016-07-12 21:39:20.801212101 +0900
+++ /etc/sysconfig/libvirt-guests       2016-07-12 21:39:45.574005615 +0900
@@ -9,6 +9,7 @@
 #           guests marked as autostart will still be automatically started by
 #           libvirtd
 #ON_BOOT=start
+ON_BOOT=start

 # Number of seconds to wait between each guest start. Set to 0 to allow
 # parallel startup.
@@ -23,6 +24,7 @@
 #             ON_SHUTDOWN=shutdown, you must also set SHUTDOWN_TIMEOUT to a
 #             value suitable for your guests.
 #ON_SHUTDOWN=suspend
+ON_SHUTDOWN=suspend

 # If set to non-zero, shutdown will suspend guests concurrently. Number of
 # guests on shutdown at any time will not exceed number set in this variable.

Ubuntu 16.04は以下のとおりです。

$ diff -uprN /etc/default/libvirt-guests{.org,}
--- /etc/default/libvirt-guests.org     2016-07-12 13:23:54.793891291 +0900
+++ /etc/default/libvirt-guests 2016-07-12 13:27:00.748614276 +0900
@@ -9,6 +9,7 @@
 #           guests marked as autostart will still be automatically started by
 #           libvirtd
 #ON_BOOT=ignore
+ON_BOOT=start

 # Number of seconds to wait between each guest start. Set to 0 to allow
 # parallel startup.
@@ -23,6 +24,7 @@
 #             ON_SHUTDOWN=shutdown, you must also set SHUTDOWN_TIMEOUT to a
 #             value suitable for your guests.
 #ON_SHUTDOWN=shutdown
+ON_SHUTDOWN=suspend

 # If set to non-zero, shutdown will suspend guests concurrently. Number of
 # guests on shutdown at any time will not exceed number set in this variable.