OmniOS - KVM - Windows XP
OmniOS, podobnie jak system z którego się wywodzi, pozwala na tworzenie maszyn wirtualnych, na których możemy uruchamiać (prawie) dowolne inne systemy. Wspieranych jest parę metod wirtualizacji jednak w tym przykładzie skupimy się na KVM czyli na maszynach wirtualnych pracujących na poziomie kernela.
Każda maszyna wirtualna utworzona w systemie potrzebuje dedykowanego dysku, interfejsu sieciowego oraz portu VNC. Zacznijmy od dysku.
root@test-builder:~# zfs create tank/VM
root@test-builder:~# zfs create tank/VM/WinXP
root@test-builder:~# zfs list
NAME USED AVAIL REFER MOUNTPOINT
rpool 7,79G 46,8G 36K /rpool
rpool/ROOT 1,73G 46,8G 31K legacy
rpool/ROOT/omnios 1,72G 46,8G 1,41G /
rpool/ROOT/omnios-backup-1 10,4M 46,8G 1,41G /
rpool/ROOT/omniosvar 31K 46,8G 31K legacy
rpool/dump 4,00G 46,8G 4,00G -
rpool/export 76K 46,8G 32K /export
rpool/export/home 44K 46,8G 44K /export/home
rpool/swap 2,06G 48,9G 2,31M -
tank 262K 163G 44,9K /tank
tank/VM 86,8K 163G 43,4K /tank/VM
tank/VM/WinXP 43,4K 163G 43,4K /tank/VM/WinXP
root@test-builder:~# _
Utworzyłem osobne zasoby dyskowe dla VM oraz WinXP. Dlaczego nie zwykłe katalogi? Będzie nam to potrzebne by stworzyć w systemie dysk dedykowany dla instalowanego systemu.
Kolejnym krokiem jest skopiowanie obrazu płyty instalacyjnej wybranego systemu. Oczywiście system można instalować z dowolnego miejsca/napędu/płyty czy sieci.
root@test-builder:~# mount -F pcfs /dev/dsk/c2t0d0p1 /mnt
root@test-builder:~# cp /mnt/WINXP_PRO.iso /tank/VM/WinXP/
root@test-builder:~# umount /mnt
root@test-builder:~# ls -alF /tank/VM/WinXP/
total 515120
drwxr-xr-x 2 root root 3 mar 2 20:36 ./
drwxr-xr-x 3 root root 3 mar 2 20:34 ../
-rwxr-xr-x 1 root root 527411200 mar 2 20:38 WINXP_PRO.iso*
root@test-builder:~# _
Tworzę dedykowany dysk dla systemu Windows XP:
root@test-builder:~# zfs create -p -V 10G tank/VM/WinXP/disk0
root@test-builder:~# zfs list
NAME USED AVAIL REFER MOUNTPOINT
rpool 7,79G 46,8G 36K /rpool
rpool/ROOT 1,73G 46,8G 31K legacy
rpool/ROOT/omnios 1,72G 46,8G 1,41G /
rpool/ROOT/omnios-backup-1 10,4M 46,8G 1,41G /
rpool/ROOT/omniosvar 31K 46,8G 31K legacy
rpool/dump 4,00G 46,8G 4,00G -
rpool/export 76K 46,8G 32K /export
rpool/export/home 44K 46,8G 44K /export/home
rpool/swap 2,06G 48,9G 2,31M -
tank 10,8G 153G 44,9K /tank
tank/VM 10,8G 153G 44,9K /tank/VM
tank/VM/WinXP 10,8G 153G 503M /tank/VM/WinXP
tank/VM/WinXP/disk0 10,3G 163G 23,9K -
root@test-builder:~# _
Tym sposobem najtrudniejszą część związaną z przygotowaniem systemu plików mamy już za sobą.
Musimy utworzyć dedykowany interfejs sieciowy. Oczywiście marnotrawstwem byłoby wykorzystywanie w tym celu osobnej karty sieciowej, całkowicie wystarczy nam karta wirtualna.
Zaczynamy od przeglądu dostępnych interfejsów fizycznych w systemie:
root@test-builder:~# dladm show-phys
LINK MEDIA STATE SPEED DUPLEX DEVICE
rge0 Ethernet up 100 full rge0
root@test-builder:~# _
Używam interfejsu rge0 jako fizycznej bazy do utworzenia interfejsu wirtualnego:
root@test-builder:~# dladm show-vnic
root@test-builder:~# dladm create-vnic -l rge0 vnic0
root@test-builder:~# dladm show-vnic
LINK OVER SPEED MACADDRESS MACADDRTYPE VID
vnic0 rge0 100 2:8:20:dd:a5:25 random 0
root@test-builder:~# _
Skrypt startowy dla WinXP dla mojej konfiguracji wygląda następująco:
#!/usr/bin/bash
# configuration
VNIC=vnic0
HDD=/dev/zvol/rdsk/tank/VM/WinXP/disk0
CD=/tank/VM/WinXP/WINXP_PRO.iso
VNC=51
MEM=1024
mac=`dladm show-vnic -po macaddress $VNIC`
/usr/bin/qemu-system-x86_64 \
-name "$(basename $CD)" \
-boot cd \
-enable-kvm \
-vnc 0.0.0.0:$VNC \
-smp 2 \
-m $MEM \
-no-hpet \
-localtime \
-drive file=$HDD,if=ide,index=0 \
-drive file=$CD,media=cdrom,if=ide,index=2 \
-net nic,vlan=0,name=net0,model=rtl8139,macaddr=$mac \
-net vnic,vlan=0,name=net0,ifname=$VNIC,macaddr=$mac \
-vga std \
-daemonize
if [ $? -gt 0 ]; then
echo "Failed to start VM"
fi
port=`expr 5900 + $VNC`
public_nic=$(dladm show-vnic|grep vnic1|awk '{print $2}')
public_ip=$(ifconfig $public_nic|grep inet|awk '{print $2}')
echo "Started VM:"
echo "Public: ${public_ip}:${port}"
Zapisuję powyższy skrypt pod nazwą: /tank/VM/WinXP/start-xp.sh, nadaję mu uprawnienia do uruchomienia i uruchamiam:
root@test-builder:/tank/VM/WinXP# ./start-xp.sh
qemu-system-x86_64: -net vnic,vlan=0,name=net0,ifname=vnic0,macaddr=2:8:20:dd:a5:25: vnic dhcp disabled
Started VM:
Public: 127.0.0.1
192.168.88.10
::1/128
::/0:5901
root@test-builder:/tank/VM/WinXP# _
Od tego momentu używając klienta VNC możemy połączyć się z działającą maszyną wirtualną pod adresem: 192.168.88.10:51
Jeżeli do tej pory wszystko działa zgodnie z naszymi oczekiwaniami, możemy mieć potrzebę uruchamiania utworzonej maszyny wirtualnej jako usługi systemowej. W tym celu należy stworzyć manifest SMF, zaimportować go i uruchomić.
Szablonowy manifest dla powyższej usługi może wyglądać następująco:
<?xml version='1.0'?>
<!DOCTYPE service_bundle SYSTEM '/usr/share/lib/xml/dtd/service_bundle.dtd.1'>
<service_bundle type='manifest' name='export'>
<service name='kvm/Windows-XP' type='service' version='0'>
<create_default_instance enabled='true'/>
<single_instance/>
<dependency name='network' grouping='require_all' restart_on='none' type='service'>
<service_fmri value='svc:/milestone/network:default' />
</dependency>
<dependency name='filesystem' grouping='require_all' restart_on='none' type='service'>
<service_fmri value='svc:/system/filesystem/local:default' />
</dependency>
<exec_method name='start' type='method' exec='/tank/VM/WinXP/start-xp.sh' timeout_seconds='60'/>
<exec_method name='stop' type='method' exec=':kill' timeout_seconds='60'/>
<stability value='Unstable'/>
<template>
<common_name>
<loctext xml:lang='C'>KVM-Windows-XP</loctext>
</common_name>
</template>
</service>
</service_bundle>
Zapisujemy go do pliku i importujemy do systemowej bazy SMF:
root@test-builder:/tank/VM/WinXP# svccfg -v import ./manifest.xml
svccfg: Taking "initial" snapshot for svc:/kvm/Windows-XP:default.
svccfg: Taking "last-import" snapshot for svc:/kvm/Windows-XP:default.
svccfg: Refreshed svc:/kvm/Windows-XP:default.
svccfg: Successful import.
root@test-builder:/tank/VM/WinXP# _
Od tego momentu usługa już działa i będzie uruchamiana wraz z systemem.
root@test-builder:/tank/VM/WinXP# svcs -a | grep kvm
online 20:40:14 svc:/kvm/Windows-XP:default
root@test-builder:/tank/VM/WinXP# _