Virtualisera med KVM i Ubuntu 9.10

Introduktion

Redan under 2001 upptäckte jag VMWare och hur behändigt det var att arbeta i en virtuell miljö till skillnad från en riktig. Man behövde inte oroa sig för att något skulle gå sönder i det “riktiga” systemet och man kunde enkelt ta en backup på en hel disk, för att sedan återställa den när man hade lyckats ha sönder det virtuella systemet. Idag finns det betydligt fler virtualiseringstekniker och många av dem används flitigt i olika produktionsmiljör världen över, då man sparar in på kostnaderna för både hårdvara, el och kylning. Personligen vill jag rekommendera KVM ihop med libvirt, vilket är riktigt smidigt att arbeta med. KVM har funnits med i standard-kärnan sedan 2.6.20 och man slipper därför ladda massa proprietära moduler. Medans libvirt är en library som går att använda till flertalet virtualiseringstekniker för att konfigurera och administrera virtuella maskiner.

Att argumentera för att någon av teknikerna är bättre eller sämre än någon annan är dock svårt, då många av dem fungerar på helt olika sätt, stödjer olika operativsystem, tillhandahåller olika verktyg för administration, osv. KVM är gratis, open-source och har support för de flesta operativsystem som gäst. Ihop med libvirt blir det dessutom riktigt enkelt att administrera och konfigurera.

Stöd för virtualisering?

Det första som är viktigt att kontrollera är om din processor har stöd för virtualisering. För att kunna använda KVM så måste din processor ha stöd för INTEL-VT eller AMD-V (beroende på om du har en Intel eller AMD processor). För att kontrollera detta, kör följande:

$ egrep '(vmx|svm)' --color=always /proc/cpuinfo

Om ingenting listas, så kan du tyvärr inte använda KVM.

64bit är att rekommendera

Om du planerar att använda mer än 2048MB minne i en virtuell maskin, så måste du använda med en 64bit kärna. Kontrollera att din processor stödjer 64bit:

$ grep ' lm ' /proc/cpuinfo

Återigen, om ingenting listas så har du inte stöd för 64bit. Om du har support för 64bit, använd:

$ uname -m

För att se om du kör en 64bit kärna eller inte. Om det står x86_64 så använder du redan en 64bits kärna, om det däremot står i386, i486, i586 eller i686, så har du en 32bit kärna och kan max använda 2048MB minne per virtuell maskin.

Installation

När du installerar Ubuntu 9.10 får du välja vad för roll din server ska ha. Om det ska vara en webserver, en mailserver, hosta virtuella maskiner, osv. Om du väljer att systemet ska vara host för virtuella maskiner, så kommer ditt system förinstalleras med både KVM och libvirt. Du kommer även ha ett virtuellt interface som heter virbr0 som används för att dina virtuella maskiner ska ha åtkomst till Internet.

$ ifconfig virbr0
virbr0    Link encap:Ethernet  HWaddr 24:4b:db:44:bd:c6
          inet addr:192.168.123.1  Bcast:192.168.123.255  Mask:255.255.255.0
          UP BROADCAST RUNNING MULTICAST  MTU:1500  Metric:1
          RX packets:117499 errors:0 dropped:0 overruns:0 frame:0
          TX packets:126108 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:0
          RX bytes:80806508 (80.8 MB)  TX bytes:108145501 (108.1 MB)

De maskiner som använder virbr0 kommer att ha en lokal IP-address och därmed ligga bakom det riktiga systemet. Detta kan vara bra om du vill testa hur en annan Linux distribution fungerar som inte bör/ska nås utifrån. Dock fungerar detta sämre om du till exempel planerar att använda den virtuella maskinen som server, eftersom man då inte kan nå den utifrån. För att detta ska fungera så måste du skapa en brygga (se nedan) och sen brygga anslutningen till din virtuella maskin. Det kräver också att din Internet-leverantör ger dig flera IP-addresser, då både din riktiga server och din virtuella server kommer få varsin IP-address.

Att brygga ett nätverkskort (bridged networking)

Det kanske låter krångligare än vad det är, men en brygga kan ses som en virtuell switch där du ansluter de virtuella maskinerna.  Då varje virtuell maskin får en egen MAC-address kan dom då även få en egen IP-address via din Internet-leverantörs DHCP-server. För att skapa denna brygga så ändrar du bara /etc/network/interfaces till följande:

# This file describes the network interfaces available on your system
# and how to activate them. For more information, see interfaces(5).
 
# The loopback network interface
auto lo
iface lo inet loopback
 
# The primary network interface
#auto eth0
#iface eth0 inet dhcp
 
# The bridge for virtual machines
auto br0
iface br0 inet dhcp
        bridge_ports eth0
        bridge_stp off
        bridge_fd 0
        bridge_maxwait 0

När detta är klart så startar du om nätverket:

$ /etc/init.d/networking restart

Detta kommer starta om nätverket på servern och lägga till br0, som nu är den bryggan du använder för att dela ut “riktigt” nät till dina virtuella maskiner.

Skapa en virtuell maskin

För att skapa en ny virtuell maskin där du planerar att köra FreeBSD med 5GB disk, 512MB minne och med bryggat nätverk, så kör vi följande:

$ sudo virt-install --name=freebsd --os-type=unix --os-variant=freebsd7 --ram=128 \
    --disk path=./freebsd.disk,device=disk,bus=ide,size=5,cache=none \
    --cdrom=./8.0-RELEASE-i386-bootonly.iso --vnc --noautoconsole \
    --network=bridge:br0 --accelerate --hvm

Detta kommer automatiskt skapa, spara och starta maskinen. När maskinen väl är igång, så kan du ansluta till den med VNC för att nå installationen. Som standard så accepterar VNC anslutningar på alla kort och kräver heller inget lösenord, vilket man självklart kan ändra på senare. När installationen väl är klar, så kommer maskinen stänga ner sig automatiskt. För att starta maskinen igen så använder vi virsh:

$ virsh start freebsd

För att kontrollera om maskinen fortfarande är igång eller inte så använder vi återigen virsh:

$ virsh list

Konfigurera och ändra på en virtuell maskin

När maskinen väl är installerad och klar så kanske du inser att 128MB minne inte var så mycket att hurra för och du vill nu tilldela mer minne till den. Enklast är att först stänga av maskinen med:

$ virsh shutdown freebsd

När maskinen väl är avstängd, dumpa konfigurationen till en fil på följande sätt:

$ virsh dumpxml freebsd > freebsd.xml

Som du ser på både virsh-kommandot och filnamnet, så är konfigurationen i XML-format. Detta betyder att du måste ändra filen manuellt. Så, för att tilldela 512MB minne till får maskin istället för 128MB, så byt ut:

<memory>131072</memory>
<currentMemory>131072</currentMemory>

till följande:

<memory>524288</memory>
<currentMemory>524288</currentMemory>

Mer information om hur XML-filen är uppbyggd hittar du i dokumentationen på libvirt.org. När du gjort alla ändringar och är klar, ladda din nya konfiguration och starta maskinen:

$ virsh define freebsd.xml
$ virsh start freebsd

Om allt nu gått som planerat, så bör din virtuella maskin ha 512MB minne nu, istället för 128MB.

Ta bort eller stänga av en virtuell maskin

Om operativsystemet du kör i den virtuella maskinen har stöd för ACPI, samt att du har ACPI aktiverat i konfigurationen av den virtuella maskinen, så kommer maskinen automatiskt stängas av när du stänger av den. Om du nu inte har ACPI aktiverat eller om den av någon annan anledning inte skulle stänga av sig, då kan du använda dig av:

$ virsh destroy freebsd

Vilket är samma sak som om du skulle rycka ut strömkablen. Personligen tycker jag “destroy” låter som något helt annat, men det finns säkert en logisk förklaring varför dom döpt det som dom gjort.

För att däremot ta bort en virtuell maskin, så använder du “undefine”, motsatsen till när du laddar om din konfiguration:

$ virsh undefine freebsd

Detta tar bort konfigurationen från libvirt, men den tar inte bort din disk (freebsd.disk) eller datan som finns lagrad. Om du har kvar din freebsd.xml, så kan du enkelt ladda in den igen på samma sätt som du laddar om konfigurationen:

$ virsh define freebsd.xml

Att göra VNC lite säkrare

Som standard lyssnar VNC på alla interface och kräver inget lösenord. Detta innebär att om du är ansluten mot internet, kan vem som helst logga in och få “fysisk” tillgång till din virtuella server. Detta kan du ställa in per-server eller ändra i /etc/libvirt/qemu.conf för att ställa in default värdet för både lösenord och vilket interface VNC ska lyssna på.

Jag föredrar att ange ett lösenord per-maskin så jag enklare kan “dela ut” en virtuell maskin utan att ge tillgång till alla mina virtuella maskiner. För att ställa in detta, byt ut graphics-raden i din XML-fil:

<graphics type='vnc' port='-1' autoport='yes' keymap='en-us'/>

mot följande:

<graphics type='vnc' listen='192.168.1.10' port='10000' passwd='s3cr3t' keymap='sv'/>

Detta gör att VNC-servern nu lyssnar på addressen 192.168.1.10 och port 10000 istället. Detta förutsätter förstås att du har ett nätverkskort med IP-addressen 192.168.1.10 och att ingenting annat lyssnar på den porten. När du väl ansluter kommer du även behöva ange lösenordet “s3cr3t” för att logga in.
Notera dock att de flesta VNC klienter som är gratis inte stödjer kryptering, så ditt lösenord skickas i klartext om du skulle ansluta över Internet.

Avslut

Som ett exempel på virtualisering med KVM så hanteras allt som är relaterat till ifconfig.se på ett flertal olika virtuella system. Jag har delat upp det så att webserver, mailserver, databas server och dns server ligger på olika system och totalt körs 6st virtuella system på samma maskin. Hårdvaran som används för detta är inget märkvärdigt utan en helt vanlig stationär dator med lite extra disk i:

  • 3.0GHz Intel Core2 Duo med 6MB L2-cache (E8400)
  • 4GB RAM (DDR2 på 800MHz)
  • 1×750GB SATA2 disk med 32MB cache
  • 1×500GB SATA2 disk med 16MB cache
  • Intel PRO/1000 Gigabit Ethernet

Där maskinen som hanterar detta inte har några som helst problem med loaden:

$ uptime
 16:39:11 up 8 days, 12:30,  1 user,  load average: 0.00, 0.01, 0.00

Kommer förmodligen skriva en uppdatering av denna artikel senare gällande diskar i KVM. KVM hanterar ju allt från logiska volymer till en mängd olika format av filer på disk som agerar virtuell hårddisk, men mer om detta i en annan artikel.