Настройка виртуализации Windows под KVM libvirt linux

Система будет тестовая и стабильность на ней не нужна, поэтому настраивать это все будем в дистрибутиве Debian jessie, который на данный момент является веткой testing.
Оригинальные и краткие руководства к действию можно найти на дебиане: KVM и QEMU. Ниже несколько подогнанная под мои задачи выжимка.

Шаблон

Если потребуется создавать много виртуальных машин или менять их параметры, очень удобно создать шаблон конфигурации виртуальных машин и скрипт её создания. Можно, конечно создавать командами вроде

virt-install --connect qemu:///system \
--name vm1 \
--ram 1024 \
--vcpus=1 \
--disk pool=storage,cache=none,size=40, format= qcow2\
--disk /vm/Win7.iso,device=cdrom \
--bridge=br0,model=e1000 \
--os-type=windows
--graphics vnc,port=5911,listen=0.0.0.0

но делать это постоянно очень неудобно. В качестве шаблона создаем конфиг вроде

<domain type='kvm'>
  <name>{name}</name>
  <memory>{ram}</memory>
  <currentMemory>{ram}</currentMemory>
  <vcpu>1</vcpu>
  <os>
    <type arch='x86_64' machine='pc-0.12'>hvm</type>
    <boot dev='cdrom'/>
    <boot dev='hd'/>
  </os>
  <features>
    <acpi/>
    <apic/>
    <pae/>
  </features>
  <clock offset='localtime'/>
  <on_poweroff>destroy</on_poweroff>
  <on_reboot>restart</on_reboot>
  <on_crash>restart</on_crash>
  <devices>
    <emulator>/usr/bin/kvm</emulator>
    <disk type='file' device='disk'>
      <driver name='qemu' type='raw' cache='none'/>
      <source file='/vm/{name}.img'/>
      <target dev='vda' bus='virtio'/>
      <address type='pci' domain='0x0000' bus='0x00' slot='0x04' function='0x0'/>
    </disk>
    <disk type='file' device='disk'>
      <driver name='qemu' type='raw' cache='none'/>
      <source file='/vm/virtio.img'/>
      <target dev='hda' bus='ide'/>
      <address type='drive' controller='0' bus='0' unit='0'/>
    </disk>
    <disk type='file' device='cdrom'>
      <driver name='qemu' type='raw'/>
      <source file='/vm/iso/ru_windows_8.1_professional_vl_with_update_x64_dvd_4050520.iso'/>
      <target dev='hdc' bus='ide'/>
      <readonly/>
      <address type='drive' controller='0' bus='1' unit='0'/>
    </disk>
    <disk type='file' device='cdrom'>
      <driver name='qemu' type='raw'/>
      <source file='/vm/virtio-win-0.1-30.iso'/>
      <target dev='hdc' bus='ide'/>
      <readonly/>
      <address type='drive' controller='0' bus='1' unit='1'/>
    </disk>
    <controller type='ide' index='0'>
      <address type='pci' domain='0x0000' bus='0x00' slot='0x01' function='0x1'/>
    </controller>
    <interface type='bridge'>
      <mac address='52:54:00:9d:be:d9'/>
      <source bridge='br0'/>
      <model type='virtio'/>
      <address type='pci' domain='0x0000' bus='0x00' slot='0x03' function='0x0'/>
    </interface>
    <serial type='pty'>
      <target port='0'/>
    </serial>
    <console type='pty'>
      <target type='serial' port='0'/>
    </console>
    <input type='tablet' bus='usb'/>
    <input type='mouse' bus='ps2'/>
    <graphics type='vnc' port='{port}' autoport='no' listen='0.0.0.0' keymap='en-us' passwd='{passwd}'/>
    <video>
      <model type='vga' vram='9216' heads='1'/>
      <address type='pci' domain='0x0000' bus='0x00' slot='0x02' function='0x0'/>
    </video>
    <memballoon model='virtio'>
      <address type='pci' domain='0x0000' bus='0x00' slot='0x05' function='0x0'/>
    </memballoon>
  </devices>
</domain>

Типовые шаблоны можно найти в документации, идущей вместе с пакетами. Также создаём устанавливающий скрипт vmcreate.sh:

#!/bin/sh

template=template.xml
path=/vm

while true; do
	read -p "VM name: " name
	if [ "$name" ]; then
		break
	fi
done


while true; do
	read -p "VNC port: " port
	case $port in
		[0-9]* ) break;;
	esac
done

while true; do
	read -p "VNC password: " password
	if [ "$password" ]; then
		break
	fi
done

while true; do
	read -p "HDD size in Gb [50]: " hdd
	case $hdd in
		[0-9]* ) break;;
		* )	hdd=50
			break;;
	esac
done

while true; do
	read -p "RAM in Mb [1536]: " ram
	case $ram in
		[0-9]* ) break;;
		* )	ram=1536
			break;;
	esac
done


echo "VM name: $name"
echo "VNC port: $port"
echo "Password: $password"
echo "HDD : $hdd Gb"
echo "RAM : $ram Mb"

while true; do
	read -p "Continue [y/N]? " yn
	case $yn in
		[Yy]* ) cont=1
			break;;
		* ) cont=0
			break;;
	esac
done

ramb=$((1024*$ram))

if [ -f "$path/$name.img" ]; then
#	cont=0
	echo "File $path/$name.img exist."
else
	qemu-img create -f raw "$path/$name.img" ${hdd}G
fi


if [ "$cont" -eq 1 ]; then
	sed "s/{name}/$name/g" $path/$template | sed "s/{port}/$port/g" | sed "s/{passwd}/$password/g" | sed "s/{hdd}/$hdd/g" | sed "s/{ram}/$ramb/g" > $path/$name.orig.xml
#	virsh create $name.orig.xml
	virsh define $name.orig.xml
	virsh start $name
else
	echo "Aborted."
fi

После такой подготовки виртуальная машина создается фактически запуском этого скрипта и ответом на вопросы. Конечную конфигурацию можно всегда поправить в XML-конфигах /etc/libvirt/qemu или с помощью утилиты virsh.

Типовая установка Windows в виртуалке

Драйвер от Win7 x64 вполне годится и для Windows 8.1, выбираем его при установке(Red Hat VirtIO SCSI controller, VIOSTOR.INF VirtIO Balloon Driver BALLOON.INF). Там же находим драйвер для сетевой карты, он пригодится позже. После этого виртуальный HDD находится системой, запускаем установку.
Уже на установленной системе ставим VirtIO-драйвер для Ethernet от Red Hat и настраиваем параметры сети.

Сеть

Для работы сети потребуется некоторая маршрутизация на самом хосте. Ниже представлен не самый оптимальный, но рабочий вариант для большинства (не-production) применений. А именно, разрешим forwarding на основной машине и явно пропишем пути из NAT-сети в интернет.
/etc/network/interfaces

up route add -host 10.0.5.2 dev br0

Также в местном фаерволле, т.е. скрипте, который настраивает iptables-правила, добавляем локальную сеть и нужные перенаправления:

IPTABLES=/sbin/iptables

echo 1 > /proc/sys/net/ipv4/ip_forward 2> /dev/null

ip addr add 10.0.6.1./24 dev br0
$IPTABLES -F -t nat
$IPTABLES -X -t nat

LAN="10.0.5.0/24"

$IPTABLES -A INPUT -s $LAN -j ACCEPT
$IPTABLES -A OUTPUT -s $LAN -j ACCEPT

$IPTABLES -t nat -A POSTROUTING -s $LAN -o br0 -j MASQUERADE

$IPTABLES -t nat -A PREROUTING -p tcp --dport 55003 -j DNAT --to-destination 10.0.5.3:3389

Управление с помощью утилиты virsh

Утилитой virsh совершаются штатно многие операции с вируалками. Наиболее часто используются старт, мягкая и жёсткая остановка

virsh start VMNAME
virsh shutdown VMNAME
virsh destroy VMNAME

Удалить существующую виртуальную машину (совсем!) также можно этой утилитой:

virsh undefine VMNAME

Как правило, виртуальная машина ставится надолго, поэтому её целесообразно стартовать при загрузке самой машины:

virsh autostart VMNAME

Завершающие дополнения

Конфиги виртуальных машин находятся в /etc/libvirt/qemu и могут быть исправлены до нужного состояния. В нём можно поменять физические параметры контейнера (объем ОЗУ, количество ядер и т.п.), также подключить/отключить образы жёстких дисков и CD/DVD.

На *nix-системах время обычно хранится в UTC, тогда как Windows его хранит в локальном часовом поясе. Проблему решает reg-файл следующего содержания:

Windows Registry Editor Version 5.00

[HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\TimeZoneInformation]
"RealTimeIsUniversal"=dword:00000001

2 Replies to “Настройка виртуализации Windows под KVM libvirt linux”

  1. Юрий Йосифович

    Хотелось бы понять как можно использовать технологию KSM (чтобы на 32ГБ ОЗУ иметь возможность запустить 100 машин с 256МБ ОЗУ). Можете рассказать об этой технологии?

    Reply
    • unixmin Post author

      100 машин для KVM слишком много. Это аппаратная виртуализация, в ней каждому контейнеру потребуется как минимум 1 ядро, что ограничивает количество контейнеров. Задача может быть решена с помощью паравиртуализации (неэффективно) или (эффективно) с помощью виртуализации уровня операционной системы. Если в контейнерах планируется одно ядро и ОС — рассмотрите виртуализацию уровня ОС.

      Reply

Добавить комментарий

Ваш e-mail не будет опубликован.