Система будет тестовая и стабильность на ней не нужна, поэтому настраивать это все будем в дистрибутиве 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
Хотелось бы понять как можно использовать технологию KSM (чтобы на 32ГБ ОЗУ иметь возможность запустить 100 машин с 256МБ ОЗУ). Можете рассказать об этой технологии?
100 машин для KVM слишком много. Это аппаратная виртуализация, в ней каждому контейнеру потребуется как минимум 1 ядро, что ограничивает количество контейнеров. Задача может быть решена с помощью паравиртуализации (неэффективно) или (эффективно) с помощью виртуализации уровня операционной системы. Если в контейнерах планируется одно ядро и ОС — рассмотрите виртуализацию уровня ОС.