20.April 2024    
   homeProjekteLinuxQEMU

 

Hobby 234x60
reichelt elektronik – Elektronik und PC-Technik
Seite zuletzt geändert: 04.11.2012 16:11

Qemu im Test

Intention

Getestet werden sollte qemu als freie Virtualisierungssoftware unter Linux.

Warum jetzt noch qemu? Weil sich die erzeugten Gast-Images unmittelbar in KVM einsetzen lassen - aber gerade kein freier Rechner zur Verfügung stand, der die Hardware-Anforderungen von KVM erfüllt (da KVM einen neueren Intel-/AMD-Prozessor benötigt, der über Virtualisierungsfähigkeiten verfügt).

Und um die Zukunft von XEN im Zusammenhang mit dem Linux-Kernel scheint es derzeit etwas Querelen zu geben (http://www.heise.de/open/Kernel-Log-Morton-stellt-Aufnahme-des-Xen-Dom0-Codes-in-Frage-Dateisysteme-fuer-SSDs--/artikel/134016).

Der Text im weiteren ist noch nicht fertig, es handelt sich derzeit nur um unvollständige Notizen. Daher erhebt er weder Anspruch auf Vollständig- noch auf Richtigkeit.

Installation

Günstig ist die Benutzung der Debian-Netinstall-CD. Diese ist relativ klein (für Debian 5.0 ca. 130MB in der i386-Version). Man kann das Image sie unter http://www.debian.org/distrib/netinst herunterladen und mit vermutlich jedem aktuellen CD-Brennprogramm auf CD bannen. Voraussetzung für die weitere Installation ist natürlich dann ein Zugriff auf ein Debian-Repository über das Netzwerk, wer also nur eine langsame oder gar keine Verbindung dorthin hat, muss sich eine Debian-Komplett-DVD besorgen und damit die Installation durchführen.

Mit dieser CD starten wir den blanken Rechner und installieren erst mal alles mit den Standard-Einstellungen (sofern nicht individuelle Anpassungen z.B. fürs Netzwerk nötig sind). Nur die tasksel-Konfiguration machen wir komplett leer (per default ist dort "Standard" angekreuzt, auch das nehmen wir heraus).

Die Plattenaufteilung ist Geschmackssache, spielt für den weiteren Betrieb auch keine besondere Rolle, da qemu ohnehin mit ganz normalen Dateien im Filesystem arbeitet. Es sollte nur auf der Partition, die das Start-Betriebssystem enthält, ausreichend Platz sein, um dieses und spätere Aktualisierungen ordentlich unterzubringen. Da bei heutigen Plattengrößen das nicht mehr wirklich eine Rolle spielt, kann man z.B. mit 10 oder 20GB (oder mehr) arbeiten. Man kann auch die Option "Guided Partioning" wählen, da wird im wesentlichen alles automatisch ausgewählt.

Im Ergebnis haben wir jetzt eine ziemlich kleine Debian-Installation.

Zu dieser Installation fügen wir jetzt noch hinzu:

  • wenn wir Installation und Konfiguration über den Rechner selbst machen wollen: ein X mit den erforderlichen Softwarepaketen (hier im Beispiel: kde mit allen Abhängigkeiten)
  • das Paket qemu
  • empfehlenswert, aber für die Installation nicht relevant: smartmontools

Die Pakete können bei Debian über

apt-get install kde qemu

installiert werden. Wenn wir NICHT über X arbeiten wollen, sondern über VNC, dann genügt uns das SDL-Paket

Jetzt haben wir alles, was wir für qemu brauchen. Ein Neustart zum Abschluss zeigt uns dann noch, ob wirklich alles funktioniert und führt uns, wenn alles in Ordnung ist, ins KDE, bei welchem wir uns mit dem Nicht-root-Benutzer, der bei der Installation angelegt wurde, anmelden können. Falls wir uns auch als root anmelden dürfen wollen, müssen wir die Datei /etc/kde3/kdm/kdmrc editieren und dort die Zeile

AllowRootLogin=False

in

AllowRootLogin=True

ändern.

Erster Test von qemu

Nachdem wir alles installiert haben, testen wir die Sache einfach mal. Wir definieren uns ein Verzeichnis, in welches wir die Gast-Images legen. Im folgenden ist das einfach /var/local

Mit dem Befehl

qemu-img create -f qcow2 /var/local/debian1.img 4000M

erzeugen wir ein Harddisk-Image mit einer Größe von 4000 MBytes im Format qcow2. Mit qcow2 wird versucht, die Imagegröße immer möglichst klein zu halten. Nicht wundern also, wenn nach dem o.g. Befehl nur ein Image von ein paar KBytes entsteht. Dementsprechend schnell ist das Image auch erzeugt. 

Mit

qemu -hda /var/local/debian1.img -cdrom /dev/cdrom -boot d -no-acpi

starten wir unser neues Image in einem neuen Fenster, das von qemu geöffnet wird. Beim Start des Images sehen wir den virtuellen PC, welcher dann (aufgrund des Parameters -boot d) versucht, vom CD-Laufwerk zu booten. Liegt im CD-Laufwerk unsere ganz am Anfang erstellte Debian-Netinstall-CD, wird die Installation auf genau die gleiche Weise gestartet, wie wir es zu Beginn erlebt haben. Im weiteren Verlauf sollten wir eigentlich in der Lage sein, in der virtuellen Umgebung eine komplette Debian-Installation durchzuführen.

Der Parameter "-no-acpi" ist für einige Gastsysteme erforderlich, hier muss man ggf. experimentieren. Ich habe es z.B. nicht geschafft, Openfiler von der Original-CD zu installieren, ohne "-no-acpi" gesetzt zu haben.

Wer es ganz eilig hat oder sofort sehen will, ob seine qemu-Installation funktioniert, kann auch fertige Disk-Images erhalten, und zwar über den Link http://www.nongnu.org/qemu/download.html. Dort findet sich unter anderem auch ein i386-Linux-Image. Das kann man sich einfach z.B. auch unter /var/local ablegen und aufrufen, dann allerdings NICHT mit der oben genannten Kommandozeile, sondern über

qemu -hda /var/local/<imagename> -cdrom /dev/cdrom -no-acpi

wobei <imagename> durch den Namen des heruntergeladenen Images zu ersetzen ist.

Diese Zeile gilt natürlich auch für den Einsatz unseres selbst erzeugten Images debian1.img.

Auf keinen Fall darf hier natürlich noch das "-boot d" enthalten sein, allenfalls ein "-boot a" (das aber dem Default entspricht), denn sonst versucht unser Image wieder von CD zu booten. Wenn keine CD eingelegt ist, dann kann auch nicht gebootet werden.

Die weiteren Parameter für den qemu-Aufruf finden sich in der qemu-Dokumentation unter http://www.nongnu.org/qemu/qemu-doc.html#SEC10.

Vereinfachen lässt sich die Bedienung mit Programmen wie qtemu und qemu-launcher. qtemu hat allerdings die Nachteile:

  • man kann in der Konfiguration nur neue Images erstellen, aber keine vorhandenen einbinden. Das geht nur manuell "hintenherum".
  • erstellte Images sind immer im raw-Format, es besteht keine Auswahl z.B. von qcow2
  • kqemu wird nicht berücksichtigt
  • eine Bedienung des qemu-Monitors von qtemu aus ist nicht möglich

qemu-launcher bietet im Zusammenspiel mit qemuctl eine recht gute Möglichkeit für den Start/Stop/Suspend/Resume und die Konfiguration von Gast-Images.

Qemu im Netzwerk

Die Konfiguration von qemu fürs Netzwerk ist eigentlich simpel, da es sich selbst mit internen IP-Adressen versorgt. Mit dem Parameter "-net nic,vlan=0" wird dem Gast eine Netzwerkkarte (NE2000 PCI) zugewiesen.

Häufig wird es aber so sein, dass man mehrere qemu-Session gleichzeitig betreibt und diese jeweils IP-Adressen bekommen sollen, unter denen die Gäste dann auch erreichbar sein sollen. Das funktioniert am besten über Bridging des Netzwerkinterfaces des Hosts zu den virtuellen Netzwerkkarten sowie zur physischen Netzwerkkarte. Dazu ist zunächst in der Datei /etc/network/interfaces die physische Netzwerkkarte auszukommentieren. Anstelle der physischen Netzwerkkarte wird ein Bridge-Interface eingeführt, welches per default erst einmal die physische Netzwerkkarte bedient.

#auto eth0
#iface eth0 inet static
#  address 10.1.1.2
#   network 10.1.1.0
#   netmask 255.255.255.0
#   broadcast 10.1.1.255
#   gateway 10.1.1.1

auto br0
iface br0 inet static
   address 10.1.1.2
   network 10.1.1.0
   netmask 255.255.255.0
   broadcast 10.1.1.255
   gateway 10.1.1.1
   bridge_ports eth0
   bridge_fd 9
   bridge_hello 2
   bridge_maxage 12
   bridge_stp off

Bei einem Neustart des Rechners sehen wir, dass das Bridge-Interface initialisiert wird. Mit ifconfig sieht man die neue Konfiguration des Netzwerks:

qemutest:/var/local# ifconfig
br0       Link encap:Ethernet  HWaddr 00:60:08:6a:33:4d
          inet addr:10.1.1.2  Bcast:10.1.1.255  Mask:255.255.255.0
          UP BROADCAST RUNNING MULTICAST  MTU:1500  Metric:1
          RX packets:2835176 errors:0 dropped:0 overruns:0 frame:0
          TX packets:4239402 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:0
          RX bytes:447734595 (426.9 MiB)  TX bytes:1151708996 (1.0 GiB)

eth0      Link encap:Ethernet  HWaddr 00:60:08:6a:33:4d
          UP BROADCAST RUNNING MULTICAST  MTU:1500  Metric:1
          RX packets:2835074 errors:0 dropped:0 overruns:0 frame:0
          TX packets:4240094 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:1000
          RX bytes:487438184 (464.8 MiB)  TX bytes:1151765134 (1.0 GiB)
          Interrupt:11 Base address:0xb000

lo        Link encap:Local Loopback
          inet addr:127.0.0.1  Mask:255.0.0.0
          UP LOOPBACK RUNNING  MTU:16436  Metric:1
          RX packets:149 errors:0 dropped:0 overruns:0 frame:0
          TX packets:149 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:0
          RX bytes:8676 (8.4 KiB)  TX bytes:8676 (8.4 KiB)

Jetzt müssen wir noch qemu diese Änderungen beibringen. Dazu ändern wir die Datei /etc/qemu-ifup folgendermaßen:

#!/bin/sh
#sudo -p "Password for $0:" /sbin/ifconfig $1 172.20.0.1

sudo -p "Password for $0:" /sbin/ifconfig $1 0.0.0.0 promisc up
sudo -p "Password for $0:" /usr/sbin/brctl addif br0 $1

Das Programm /usr/sbin/brctl bekommen wir aus dem Paket bridge-utils, welches wir uns wieder mit "apt-get install bridge-utils" installieren.

Beim Aufrufen der Gäste ist es jetzt wichtig, dass diese separate virtuelle Netzwerkkarten bekommen, damit sie im Netzwerk auch wirklich unterscheidbar sind. Das geschieht durch die Benutzung des "macaddr"-Parameters, bei welchem dem Aufrufparameter "-net nic,..." gesagt wird, welche MAC-Adresse (also welche physische Kartenadresse) der Netzwerkkarte zugewiesen wird. Normalerweise sollen MAC-Adressen nur ein einziges Mal in der Welt existieren - da die MAC-Adresse aber ohnehin nur bis zum nächsten Router benutzt wird, genügt es im Normalfall, wenn wir uns unsere eigene Liste verwendeter MAC-Adressen merken. Wichtig: Die ersten Stellen sollten nicht verändert werden, da sie den Hersteller der Karte angeben. Wenn wir für die ersten Stellen z.B. "00:60" benutzen, könnte es sein (auch wenn es unwahrscheinlich ist), dass wir in Konflikt mit einer 3COM-Netzwerkkarte geraten, die die gleiche MAC-Adresse besitzt.

Von qemu wird als Standard-MAC-Adresse benutzt: 52:54:00:12:34:56. Diese können wir unserem ersten qemu-Gast zuweisen. Dem nächsten können wir z.B. die MAC-Adresse 52:54:00:12:34:57 geben. Die MAC-Adressen werden übrigens hexadezimal notiert, nach der 59 kommt also nicht die 60, sondern die 6A.

Dementsprechend lautet der Aufruf für unseren ersten qemu-Gast:

qemu -hda /var/local/<imagename> -cdrom /dev/cdrom -net nic,vlan=0 -net tap,vlan=0,ifname=tap0 -no-acpi

für unseren zweiten Gast dann:

qemu -hda /var/local/<imagename> -cdrom /dev/cdrom -net nic,vlan=0,macaddr=52:54:00:12:34:57 -net tap,vlan=0,ifname=tap1 -no-acpi

Das Gastsystem kann jetzt jeweils separat konfiguriert werden - ebenso wie für die MAC-Adresse gilt aber natürlich auch für die IP-Adressen, dass man sich hier eine Liste machen muss, um Überschneidungen zu verhindern.

Beispiel für zwei Openfiler-Gastsysteme, hier erfolgt die IP-Konfiguration in der Datei /etc/sysconfig/network-scripts/ifcfg-eth0:

Gast 1:

DEVICE=eth0
IPADDR=10.1.1.2
NETMASK=255.255.255.0
NETWORK=10.1.1.0
BROADCAST=255.255.255.255
GATEWAY=10.1.1.1
ONBOOT=yes
TYPE=Ethernet
HWADDR=52:54:00:12:34:56

Gast 2:

DEVICE=eth0
IPADDR=10.1.1.3
NETMASK=255.255.255.0
NETWORK=10.1.1.0
BROADCAST=255.255.255.255
GATEWAY=10.1.1.1
ONBOOT=yes
TYPE=Ethernet
HWADDR=52:54:00:12:34:57

Sobald die Gastsysteme mit dieser Konfiguration gestartet wurden, können wir sie von irgendeinem anderen Rechner im Netzwerk anpingen. Auf diesem Rechner können wir dann auch gleich anhand der ARP-Tabelle sehen, dass die MAC-Adressen passend zugeordnet wurden:

remotehost:~#arp -a
? (10.1.1.2) at 52:54:00:12:34:56 [ether] on eth0
? (10.1.1.3) at 52:54:00:12:34:57 [ether] on eth0
? (10.1.1.5) at 00:60:08:6A:33:4D [ether] on eth0

Die letzte Zeile gehört dabei zu unserem Host, hier sehen wir die MAC-Adresse der physischen Netzwerkkarte (eine 3COM 3c905 Boomerang), diese haben wir bereits weiter oben beim "ifconfig" gesehen.

Fazit 

Man sollte keine Wunder von der Virtualisierung erwarten. Ein virtueller Rechner kann nie so schnell laufen wie sein Host.

Insgesamt läuft qemu ordentlich, benötigt allerdings auch etliches an CPU-Leistung. Eine Installation eines Debian-Systems in einem qemu-PC benötigt das Mehrfache an Zeit gegenüber der Installation auf seinem Host.

Auch Plattenzugriffe sind deutlich langsamer.

Auf dem Testsystem brachte hdparm auf dem Hostsystem auf einer nicht mehr ganz taufrischen PATA-Platte eine Übertragungsrate von 28,3 MB/s.

Das Debian-Gastsystem brachte es nur noch auf ca. 3,8 MB/s.

Beschleunigung mit kqemu

Die Geschwindigkeit von qemu ohne Beschleuniger ist, mit Verlaub, nicht erträglich. Ein 386er erscheint einem da als Rennpferd.

Abhilfe verschafft kqemu. Nachteil: kqemu ist ein Kernel-Modul, welches standardmäßig nicht im Kernel enthalten ist - und damit auch nicht in den fertigen Kernel-Paketen von Debian. Damit muss man sich einen eigenen Kernel nebst kqemu-Modul übersetzen. Kenntnisse im Konfigurieren, Übersetzen und Einbinden eigener Kernel sind damit auf jeden Fall erforderlich.

Problem ist, dass sich der kqemu-Source zwar unter der stable Release problemlos übersetzen und das Modul sich auch ohne weiteres laden lässt. Das böse Erwachen gibt es, wenn qemu zum ersten Mal mit dem Parameter "-kernel-kqemu" aufgerufen wird. Das Gastsystem beginnt nämlich zu booten, nach kurzer Zeit endet das aber mit einem Kernel-panic-Error des Gastsystems. Ursache ist offenbar, dass sich das fertige qemu und das selbst übersetzte kqemu nicht miteinander vertragen. Man würde jetzt zwar normalerweise einfach aus den qemu-Sourcen ein neues qemu übersetzen, aber das scheitert daran, dass sich diese mit dem gcc aus der stable Release nicht übersetzen lassen - mindestens die Version 0.9x von qemu lässt sich nämlich nicht mit dem gcc 4.x übersetzen.

Auch hier gibt es Abhilfe - nämlich die Benutzung der unstable Release. Dazu ändern wir in der Datei /etc/apt/sources.list bei den beiden Zeilen für das main-Paket den "lenny" durch "unstable" und führen danach ein

apt-get update

aus.

Was brauchen wir jetzt? Neben den Kernel-Sourcen, den Übersetzungswerkzeugen und den kqemu-Sourcen brauchen wir noch einige Hilfsprogramme, die in unserer bisherigen Installation nicht enthalten sind. Wir können das erledigen mit:

apt-get install linux-source-2.6.28 kernel-package bzip2 libncurses-dev ncurses-dev zlib1g-dev kqemu-common kqemu-source

Die Sources sind damit zwar auf der Platte, aber noch in gepackter Form. Wir entpacken sie mit

cd /usr/src
tar -xjvf linux-source-2.6.28.tar.bz2
tar -xjvf kqemu.tar.bz2
ln -s linux-source-2.6.28 linux

Wenn wir die config-Datei unseres aktuellen Kernels aus dem /boot-Verzeichnis hernehmen und als .config nach /usr/src/linux kopieren, können wir normalerweise anschließend gleich mit

cd /usr/src/linux
make-kpkg kernel-image
make-kpkg modules-image

alles übersetzen. Wenn alles fehlerfrei gelaufen ist, haben wir dann unter /usr/src zwei neue .deb-Pakete liegen. Diese können wir dann mit

dpkg -i linux<version>.deb
dpkg -i kqemu<version>.deb

installieren. Bitte jetzt aber noch nicht einfach neu booten. Der Kernel hat nämlich selber quasi kaum Treiber eingebaut, diese liegen meist als Module vor, die dann in eine initramfs-Datei gepackt werden müssen. Dazu erst einmal aufrufen

update-initramfs -k 2.6.28 -c

und dann in der Datei /boot/grub/menu.lst bei den beiden bereits von der erfolgten Installation vorgenommenen neuen Einträgen jeweils noch die Zeile

initrd /boot/initrd.img-2.6.28

einfügen (als Beispiel kann man sich die alten Einträge in der gleichen Datei anschauen und vielleicht einfach kopieren und anpassen).

Damit kqemu gleich als Modul geladen wird, tragen wir es einfach mit in die Datei /etc/modules ein.

JETZT können wir damit neu booten und anschließend können wir zu unseren oben aufgeführten Kommandozeilen noch den Parameter "-kernel-kqemu" anhängen.

Resultat: Die Geschwindigkeit des Gastsystems wird mit kqemu - zumindest was die CPU betrifft - endlich an die des Hosts angenähert. Ein Test mit openssl-Berechnungen ("openssel speed rsa4096"; jeweils 10 Sekunden langer Test mit der Berechnung von 4096bit RSA-Keys (private und public)) erbringt die Werte:

16 private RSA's auf dem Host vs. 13 private RSA's auf dem Gastsystem
1100 public RSA's auf dem Host vs. 894 public RSA's auf dem Gastsystem

Die Plattengeschwindigkeit allerdings ist sogar noch etwas geringer als bei qemu ohne Beschleuniger - hier wurde noch mal etwas weniger Durchsatz gemessen (ca. 2,8 MB/s).

KVM

Mit KVM sieht alles deutlich anders aus. Durch die direkte Unterstützung der Virtualisierung durch die CPUs ist die Performance mit dem normalen qemu und auch mit kqemu nicht mehr vergleichbar.

KVM läuft auf vorhandenen Kernels ohne dass diese gepatcht werden müssen. Allerdings benötigt man Module, die vom Kernel geladen werden können. Das sind die Module kvm.ko und kvm-intel.ko bzw. kvm-amd.ko. Die Module stehen entweder fertig für fixe Kernel (wie sie z.B. bei den Distributionen fertig geliefert werden) zur Verfügung oder, wenn man einen selbstgebauten Kernel benutzt, per Übersetzung der entsprechenden Modul-Sourcen. Letzteres läuft unter Debian einfach so ab wie bereits oben für das kqemu-Modul beschrieben:

  • Download der Sourcen mit "apt-get install kvm-source" und entpacken der Datei /usr/src/kvm.tar.bz2
  • Wechsel nach /usr/src/linux und Übersetzen der Module mit "make-kpkg modules-image"
  • unter /usr/src liegt jetzt das fertige .deb-Paket für die KVM-Module, die dann nur noch installiert werden müssen

 

libvirt und kvm

Keine Kommentare
Kommentar hinzufügen

* - Pflichtfeld

*



*
Copyright © 2008-2017