| Version 50 (modified by yuna, 12 years ago) (diff) |
|---|
KVMメモ
このページは、kvmをlibvirt(virsh)で使いたい人向けのメモです。簡単に使いたい人は、virt-managerを使ってください。
準備
Fedora13
kvmを利用するのに、libvirtを利用します。libvirtをインストールしておきます。virt-managerをインストールすると必要なパッケージが一通り入って便利です。また、kvmで仮想マシンを実行するのに必要なqemu-kvmもインストールしておきます。
# yum install virt-manager # yum install qemu-kvm
次に、kvmのモジュールをカーネルにロードします。AMDの場合は、kvm_intelの代わりにkvm_amdを使ってください。
# modprobe kvm # modprobe kvm_intel
libvirtを利用するには、libvirtdの起動が必要です。libvirtdを起動しておきます。
# /etc/init.d/libvirtd start
その他、下記のパッケージを入れておくとよいかもしれません。
# yum install virt-top # yum install qemu-kvm-tools
Ubuntu 10.10
# apt-get install qemu-kvm virt-manager # apt-get install virt-top
virshを利用したKVM仮想マシンの作り方
イメージ作成
# qemu-img create -f raw ubuntu.img 10G
libvirt XMLファイルの作成方法
下記のXMLを適当に編集。特に、
- name(他の仮想マシンとユニークな名前になるように)
- memory(メモリ容量)
- vcpu(CPUの数)
- diskとcdromのsource file
- acpiを有効にしないと、virshからshutdownコマンドでシャットダウンできない。
- mac addressを他と被らないように
辺りに注意しておく。下記は、Fedora13の例。
<domain type='kvm' id='3'>
<name>UbuntuVM</name>
<memory>524288</memory>
<currentMemory>524288</currentMemory>
<vcpu>1</vcpu>
<os>
<type arch='x86_64' machine='pc'>hvm</type>
<boot dev='hd'/>
<boot dev='cdrom'/>
</os>
<features>
<acpi />
</features>
<clock offset='utc'/>
<devices>
<emulator>/usr/bin/qemu-kvm</emulator>
<!-- DISKの定義 -->
<disk type='file' device='disk'>
<driver name='qemu' type='raw'io='native'/>
<source file='/mnt/sda5/ubuntu.img'/>
<target dev='hda' bus='ide'/>
</disk>
<!-- CDROMの定義 -->
<disk type='file' device='cdrom'>
<driver name='qemu'/>
<source file='/mnt/sda5/iso/ubuntu-ja-10.04-desktop-i386-20100512.iso'/>
<target dev='hdc' bus='ide'/>
<readonly/>
</disk>
<!-- ネットワークインタフェースの定義 -->
<interface type='network'>
<mac address='52:54:00:1d:18:5e'/>
<source network='default'/>
<target dev='vnet0'/>
</interface>
<input type='mouse' bus='ps2'/>
<graphics type='vnc' port='5902' keymap='ja'/>
</devices>
</domain>
Ubuntuの場合は、typeタグのmachineをpcなどにする。
... <type arch='x86-64' machine='pc'>hvm</type> ...
virshに登録して起動
# virsh (virsh実行。以下、virshのコンソールで実行) virsh # define virt-kvm.xml
defineで仮想マシンを定義したXMLを登録すると、/etc/libvirt/qemuディレクトリにDomain名のファイルで定義ファイルが作られる。
# ls /etc/libvirt/qemu UbuntuVM.xml networks
起動と起動状態の確認は、次の通りです。
virsh # start UbuntuVM virsh # list Id 名前 状態 ---------------------------------- 1 UbuntuVM 実行中
VNCクライアントのスクリーン1で接続可能(vnc://localhost:1)です。vncのポートなどは、次の行で設定します。
<graphics type='vnc' port='5902' keymap='ja'/>
デフォルトでは、仮想マシンを起動したホスト以外からのVNCクライアントの接続を受け付けないようになっています。ホストマシンとは別のマシンからvncで接続するには、/etc/libvirt/qemu.confに次の設定を追加します。
vnc_listen = "0.0.0.0"
Windowsでvncを利用する場合カーソルがずれます。inputデバイスの設定を次のように変更してください。
<!-- <input type='mouse' bus='ps2'/>-->
<input type='tablet' bus='usb'/>
停止はshutdownを使います。
virsh # shutdown UbuntuVM
acpiが有効になっていないと、virshからのシャットダウンを受け付けないので注意してください。また、linuxの場合、acpidをインストール/起動しておく必要があります。ubuntu serverの場合デフォルトではインストールされないので、
# apt-get install acpid
としてacpidをインストールします。
ハイバネートとレジューム
virsh # save UbuntuVM UbuntuVM.mem virsh # restore UbuntuVM UbuntuVM.mem
Windows利用時に注意
libvirt xmlを記述するときの注意
- clock offsetをlocaltimeにしないと時間がずれます。
- acpiを有効にしないと、Windows7以降でインストールできません。
- inputデバイスをtabletにしないと、VNCで接続したときにカーソルの動きが変になります。
Windowsゲストドライバ
Windowsゲストドライバを利用すると、ネットワークI/OやディスクI/Oが速くなります。 ゲストドライバの取得とインストール方法は下記のURLを参照。
ネットワーク接続
ルーティングして接続
仮想マシンのIPアドレスから、ホストOSのNICにルーティングして接続します。
- ゲスト側のネットワークを適当設定(例えば192.168.100.2,GWを192.168.100.1)。ネットワークセグメントはホストと別にする。
- ホスト側のネットワークを設定する。
# ifconfig vnet0 192.168.100.1 netmask 255.255.255.0
IPフォワードの設定をしていなければ、IPフォワードの設定を行う。
# echo 1 > /proc/sys/net/ipv4/ip_forward
図で説明すると、上記の設定で次のようなネットワークが構築できる。
eth0:10.9.123.3
+--------------+ +---------------+
+--+-+ +-+---+ +--+-+ |
LAN---|eth0| ホストOS |vnet0|-----|eth0| 仮想マシン |
+--+-+ +-+---+ +--+-+ |
+--------------+ +---------------+
vnet0:192.168.100.1 eth0:192.168.100.2
NATによるLAN上のIPからの接続
プライベートIPをeth0に割り振り、NATで接続します。
eth0:10.8.99.6,10.8.99.7(NATで192.168.100.2に接続)
+--------------+ +---------------+
+--+-+ +-+---+ +--+-+ |
LAN---|eth0| ホストOS |vnet0|-----|eth0| 仮想マシン |
+--+-+ +-+---+ +--+-+ |
+--------------+ +---------------+
vnet0:192.168.100.1 eth0:192.168.100.2
- eth0に10.8.99.6でアクセスするとホストOSに接続。
- eth0に10.8.99.7でアクセスすると仮想マシン(192.168.100.2)に接続。
するように設定してみる。普通にeth0に10.8.99.6を設定しておく。 次に10.8.99.7へのアクセスを192.168.100.2に転送するNAT用のnat.iptファイルを用意する。
*nat :PREROUTING ACCEPT [5318:237514] :POSTROUTING ACCEPT [162:9112] :OUTPUT ACCEPT [14132:847744] -A PREROUTING -d 10.8.99.7 -j DNAT --to-destination 192.168.100.2 -A POSTROUTING -d ! 192.168.100.0/255.255.255.0 -j MASQUERADE -A POSTROUTING -s 192.168.100.2 -j SNAT --to-source 10.8.99.7 -A OUTPUT -d 10.8.99.7 -j DNAT --to-destination 192.168.100.2 COMMIT
NATを読み込む。
# cat nat.ipt | iptables-restore
eth0に10.8.99.7を割り振らないとLAN上のマシンからアクセスできないので、ipコマンドでNICにIPを割り振っておきます。
# ip addr add 10.8.99.7 dev eth0
ブリッジによるホストのNICと同じセグメントへの設定
ホストIPアドレスが192.168.1.5で、仮想マシンのIPアドレスを192.168.1.6のようにホストのNICと同じセグメントのネットワークに仮想マシンを所属させたい場合は、ブリッジを利用します。
virbr0:192.168.1.5
+--------------+ +---------------+
| +-virbr0+ + |
| |+-+---+| +--+-+ |
| ホストOS ||vnet0||-----|eth0| 仮想マシン |
| |+-+---+| +--+-+ |
| | + | | |
| |+-+---+| | |
| ||eth0 || | |
| |+-+--++| | |
| +-----|-+ | |
+--------------+ | +---------------+
| eth0:192.168.1.6
LAN
※ブリッジを使うのでvnet0とeth0にはIPは振りません。 まず、/etc/network/interfacesに次のように記述し、ブリッジを有効にする。
auto virbr0
iface virbr0 inet static
address 192.168.1.5
netmask 255.255.255.0
network 192.168.1.0
broadcast 192.168.1.255
gateway 192.168.1.1
bridge_ports eth0
eth0を無効にし、ブリッジを有効にする。
# ifdown eth0 # ifup virbr0
libvirt.xmlのinterface定義にブリッジに含めるように定義
<interface type='bridge'>
<source bridge='virbr0' />
<mac address='02:00:00:21:11:01'/>
<target dev='vnet0' />
</interface>
仮想マシンを起動すると、ブリッジに含まれた形で起動してくる。
# brctl show
bridge name bridge id STP enabled interfaces
virbr0 8000.0016d32ff458 no eth0
vnet0
下記のようにすると、interfacesに書くことなくテストすることができる。
# brctl addbr virbr0 # brctl addif virbr0 eth0 # ifconfig virbr0 192.168.1.5 netmask 255.255.255.0
あとは、仮想マシン側のeth0でifconfigでIPアドレスを指定するなどすればok。
ポートフォワードによる仮想マシンIPを利用したルートコンソールの接続
仮想マシンのIPでVNCに接続すると、ブレードサーバのOAのようにルートコンソールが取得できると嬉しくありませんか? ポートフォワードを使うと実現することができます。
例えば、ゲストOSの5900番(VNCのデフォルトポート)をホストOS上の仮想マシンのコンソールのポートに転送するようにすれば、VNCで仮想マシンに接続するとルートコンソールが取れるようになります。
*nat :PREROUTING ACCEPT [5318:237514] :POSTROUTING ACCEPT [162:9112] :OUTPUT ACCEPT [14132:847744] -A PREROUTING -d 10.8.99.7 -p tcp --dport 5900 -j DNAT --to-destination 10.8.99.6:5900 -A PREROUTING -d 10.8.99.7 -j DNAT --to-destination 192.168.100.2 -A POSTROUTING -d ! 192.168.100.0/255.255.255.0 -j MASQUERADE -A POSTROUTING -s 192.168.100.2 -j SNAT --to-source 10.8.99.7 -A OUTPUT -d 10.8.99.7 -j DNAT --to-destination 192.168.100.2 COMMIT
DHCPでIPを付与
DHCPでIPを付与するようにするには、/var/lib/libvirt/network/default.xmlを次のように編集します。
<network>
<name>default</name>
<uuid>631f86c8-5469-468a-a361-3a91d4b99a35</uuid>
<forward mode='nat'/>
<bridge name='virbr0' stp='on' delay='0' />
<ip address='192.168.122.1' netmask='255.255.255.0'>
<dhcp>
<range start='192.168.122.100' end='192.168.122.254' />
<host mac='52:54:00:1d:18:5e' name='foo.com' ip='192.168.122.28' />
</dhcp>
</ip>
</network>
上記のネットワーク設定ファイルを再設定して、ネットワークを再起動(net-destroy,net-start)します。
virsh # net-define /var/lib/libvirt/network/default.xml ネットワーク default が /var/lib/libvirt/network/default.xml から定義されました virsh # net-destroy default ネットワーク default は停止されました virsh # net-start default ネットワーク default が起動されました
メモリバルーンニング
メモリバルーニングは、仮想マシンのメモリを動的に増減させます。setmemコマンドで、メモリを変更できます。
ゲスト
$ free
total used free shared buffers cached
Mem: 485656 229632 256024 0 49528 81960
-/+ buffers/cache: 98144 387512
Swap: 524284 58200 466084
この状態で、ホスト上で下記のコマンドを実行してみます。
ホスト
# virsh setmem DOMNAME 1000000
ゲスト上でfreeを実行すると、メモリが増えているのが分かります。
ゲスト
$ free
total used free shared buffers cached
Mem: 973656 229792 743864 0 49532 81984
-/+ buffers/cache: 98276 875380
Swap: 524284 58200 466084
メモリを減らすこともできます。
libvirtから仮想マシンへのルートログイン
libvirtでは、仮想マシンの実際に利用しているメモリなど、細かい情報が取れません。シリアルコンソールでルートログインできるように設定しておくと、ホストOSから状態の監視に使えます。
※言うまでもないことですが、仮想マシンのユーザがルートコンソールを管理者に取られるのが嫌な場合は、この方法は利用しないでください。
まず、libvirtのXMLファイルを定義して、ゲストのシリアルコンソールを有効にします。
...
<serial type='pty'>
<target port='0' />
</serial>
<console type='pty'>
<target port='0' />
</console>
</devices>
ゲスト側の設定
grub.cfgを設定
/boot/grub/grub.cfgに下記のようにシリアルコンソールの設定(console...115200n8を追加)
linux /boot/vmlinuz-3.2.0-40-generic \
root=UUID=187b5cde-ed09-4d02-93c3-9c2fc162a97d ro quiet\
console=tty0 console=ttyS0,115200n8
パスワードなしでシリアルログインできるように設定
mingettyをインストール
# apt-get install mingetty
/etc/init/ttyS0.confに下記のように設定
start on stopped rc RUNLEVEL=[2345] and (
not-container or
container CONTAINER=lxc or
container CONTAINER=lxc-libvirt)
stop on runlevel [!2345]
respawn
exec /sbin/mingetty --autologin root ttyS0
ホスト側から接続
ゲストを再起動すると、ホスト側から
$ virsh DOMAINNAME console
でルートログインできる。
ネットワーク帯域制限
ネットワークインタフェース定義の部分で、bandwidthを定義すれば、帯域制限をかけることができる。単位はaverage/peakはkbyte/s。burstはkbyte。
<interface type='...'>
...
<model type='virtio' />
<bandwidth>
<inbound average='128' peak='256' burst='256'/>
<outbound average='128' peak='256' burst='256'/>
</bandwidth>
Ubuntuだと、kernel 3.5.0にしないと動作しない。RHEL6などでは多分利用できない。
QMP
KVM(というかqemu)には、ハイパーバイザからVMのイベントや情報を取得するQMP(Qemu Messaging Protocol)が提供されています。QMPを利用することにより、様々な情報を取得することができます。下記は利用例です。
# virsh qemu-monitor-command DOMNAME '{"execute":"query-blockstats"}' |python -mjson.tool
{
"id": "libvirt-27",
"return": [
{
"device": "drive-virtio-disk0",
"parent": {
"stats": {
"flush_operations": 0,
"flush_total_time_ns": 0,
"rd_bytes": 0,
"rd_operations": 0,
"rd_total_time_ns": 0,
"wr_bytes": 0,
"wr_highest_offset": 3860278784,
"wr_operations": 0,
"wr_total_time_ns": 0
}
},
"stats": {
"flush_operations": 0,
"flush_total_time_ns": 0,
"rd_bytes": 163434496,
"rd_operations": 9976,
"rd_total_time_ns": 8262845363,
"wr_bytes": 13394944,
"wr_highest_offset": 10235260416,
"wr_operations": 1439,
"wr_total_time_ns": 147967748900
}
},
{
"device": "drive-ide0-1-0",
"parent": {
"stats": {
"flush_operations": 0,
"flush_total_time_ns": 0,
"rd_bytes": 0,
"rd_operations": 0,
"rd_total_time_ns": 0,
"wr_bytes": 0,
"wr_highest_offset": 0,
"wr_operations": 0,
"wr_total_time_ns": 0
}
},
"stats": {
"flush_operations": 0,
"flush_total_time_ns": 0,
"rd_bytes": 49218,
"rd_operations": 15,
"rd_total_time_ns": 1671233,
"wr_bytes": 0,
"wr_highest_offset": 0,
"wr_operations": 0,
"wr_total_time_ns": 0
}
}
]
}
QMPについては、あまりドキュメントが整備されていません。QMPの詳細は、下記のスキーマに記載されています
リソース取得
下記のvirt-xxxコマンドにより、CPU、メモリ、ディスクのリソースを取得することができます。
| コマンド | 説明 |
| virt-top | 仮想マシンのCPU使用率、メモリの使用率を表示 |
| virt-df | 仮想マシンのディスクの使用量を表示(Ubuntuではlibguestfs-toolsパッケージを利用) |
| virt-dmesg | ??? |
KVMのもうちょっと高度な使い方
そのうち書く予定
- リソースの取得方法
- iscsiのDISKから起動
- ライブマイグレーション
- block migration
- pythonからの操作
