Remote-Virtualisierung: KVM kann…

Oh Mann, QEMU, bzw. KVM ist die reinste Wissenschaft. So viele Optionen, so viele Fähigkeiten, die bei den dreißigtausend Einstellungsmöglichkeiten in VirtualBox irgendwie nicht so zahlreich vorhanden sind.

Abgesehen davon, dass KVM ganze Architekturen emulieren kann, können z.B. auch mehrere Graka-Typen virtualisiert werden. Und so viel Anderes, was ich bis jetzt noch gar nicht in der Breite entdecken konnte.

Komme ich also einfach mal zu den Punkten, die QEMU/KVM kann und dazu motivieren, benutzt zu werden.

Da wäre zunächst Unity, was ootB läuft. Schon mal schön, auch wenn mich Ubuntu an sich nicht wirklich interessiert und ich Unity für ziemlichen Dummfug halte. Aber dass es läuft, ist auf jeden Fall ein gutes Zeichen, was QEMU angeht.

Ich hab es jetzt auch geschafft, Netzwerkbrücken zu erstellen. Also, da ist VirtualBox eindeutig komfortabler! Eine Einstellung, fertig. Bei QEMU ist es ein elendes Gebastel, bei dem ich mir nicht mal ganz sicher bin, ob ich mit dem Ergebnis, bzgl. Sicherheit so wirklich einverstanden bin.

Aber um das mal kurz zu dokumentieren:

1. VMs nummerieren

Aus organisatorischen Gründen (genauer gesagt, um in Remmina jede VM eindeutig speichern zu können) bekommt jede eine Nummer von 1 aufwärts, die bisher nur als Port diente, aber jetzt bei den Netzwerkbrücken in mehrfacher Hinsicht ebenfalls nützlich ist, zum einen zur Generierung der MAC-Adressen, zum anderen zur fortlaufenden Vergabe der IP-Adressen im LAN.

2. Mac-Adressen-Dummy erstellen

Wir benötigen beliebige MAC-Adressen. Hier ist die Nummerierung von Vorteil, weil die Nummern der VMs einfach als letztes Byte in eine Standardvorlage eingefügt werden können. Diese Vorlage lässt sich bequem per Befehl zufällig generieren:

tr -dc 'A-F0-9' </dev/urandom | fold -w 10 | sed 's/\(..\)/\1:/g' | head -n1

Das Ergebnis sieht dann z.B. so aus:

6A:65:7F:C0:E7:

Die ersten fünf Bytes einer MAC-Adresse.

3. Netzwerkbrücke einrichten

Jetzt lesen wir diese Anleitung und richten danach eine Netzwerkbrücke ein (wie gut das Script da drin funktioniert, weiß ich nicht; ich bin an der Stelle erst mit Lesen angekommen, als ich mein eigenes schon fertig hatte).

4. VM-Manager erstellen

Damit man nicht jedes Mal kilometerlange Befehle abtippen muss, um eine VM zu starten, schreiben wir uns einen kleinen VM-Manager, der VMs aus Config-Dateien erstellt und für temporäre VMs ein paar Parameter entgegen nimmt und den Rest mit Standardwerten auffüllt. Auch das manuelle Erstellen und Löschen der tap-Brücken kann man sich sparen, weil das Script sich auch darum kümmert.

Wir erstellen also eine Datei ~/bin/vm-go mit folgendem Inhalt:

#!/bin/bash

qemu_dir="<Verzeichnis, wo die virtuellen Festplatten liegen>"
cdrom_dir="$qemu_dir/CD-ROMs"
config_dir="$qemu_dir/config"
def_mac="<Oben erstellter MAC-Adressen-Dummy>"
def_password="<Standardpasswort>"

[ "$2" != "-" ] && hda="$2"	# -hda nüscht
[[ "$3" && "$3" != "-" ]] && cdrom="$3"	# -cdrom nüscht
[[ "$4" && "$4" != "-" ]] && boot="$4" || boot="c"	# -boot c
[[ "$5" && "$5" != "-" ]] && memory="$5" || memory="512"	# -m 512
[[ "$6" == "1" ]] && bridge=1 || bridge="nein"	# keine Netzwerkbrücke
[[ "$7" && "$7" != "-" ]] && port="$7" || port="50"	# -vnc :50,password
[[ "$8" && "$8" != "-" ]] && password="$8" || password="$def_password"	# Passwort, das übergeben wird: <Standardpasswort>

[[ "$1" != "-c" && "$1" != "-t" ]] && {
	echo -n "Usage: vm-go [-c für Config, -t für temporäre Konfiguration] [Festplatte] [CD-ROM]"
	echo " [Boot (c oder d)] [RAM in MB] [Netzwerkbrücke (1 oder 0)] [VNC-Port minus 5900 (1-99)] [Passwort]"    
	echo "Fehlende Angaben sind mit \"-\" zu ersetzen, wenn danach noch welche kommen."
	echo "Standard: vm-go (-t) HDD=leer CD-ROM=leer Boot=c RAM=512 Brücke=0 Port=50 Passwort=<Standardpasswort>"
	exit
}

[ "$1" == "-c" ] && . "$config_dir/$2.conf"

echo
echo "HDD:      $hda"
echo "CD-ROM:   $cdrom"
echo "Boot:     $boot"
echo "RAM:      $memory MB"
echo "Bridge:   $([ "$bridge" == "1" ] && echo "ja" || echo "$bridge")"
echo "VNC-Port: $[port+5900]"
echo "Passwort: $password"
echo

[ "$hda" ] && hda=" -hda $qemu_dir/$hda"
[ "$cdrom" ] && cdrom=" -cdrom $cdrom_dir/$cdrom"
boot=" -boot $boot"
memory=" -m $memory"
vnc=" -vnc :$port,password"

[ "$bridge" == "1" ] && {
	tap=$(sudo /usr/sbin/tunctl -b -u $(whoami) -g kvm)
	macaddr="$def_mac$([ "$port" -lt "10" ] && echo "0$port" || echo "$port")"
	net=" -net nic,vlan=0,macaddr=$macaddr,model=virtio -net tap,vlan=0,ifname=$tap"
}

echo "change vnc password $password" | kvm$hda$cdrom$boot$memory$vnc$net -k de -monitor stdio

[ "$bridge" == "1" ] && {
	sudo /sbin/ifconfig $tap down
	/usr/sbin/tunctl -d $tap > /dev/null
}

Achtung! Das Script prüft nicht auf fehlerhafte Eingaben! Bestenfalls gibt es Beschwerden von den im Script aufgerufenen Befehlen.
Außerdem ist der QEMU-Monitor nicht zu gebrauchen, wenn die VM mit diesem Script gestartet wurde.
Und im Übrigen sollte beachtet werden, dass das Script sudo-Befehle ausführt. Da man aber dazu kein Passwort eingeben muss, werden darauf folgende sudo-Befehle weiterhin nach einem Passwort fragen (was gut ist).

5. Ordner und Dateien erstellen

Im Script ist ja z.B. die Angabe zu machen, wo die Festplatten liegen. Dieses Verzeichnis benötigt die Unterverzeichnisse CD-ROMs und config. Alle drei Verzeichnisse sind schnell angelegt:

mkdir -p <Festplattenverzeichnis>/CD-ROMs <Festplattenverzeichnis>/config

In das Config-Verzeichnis kann man nun – wer hätte das gedacht? – Config-Dateien für die VMs legen. Diese könnten z.B. so aussehen:

hda="Ubuntu.img"
memory=1024
port=5
bridge=1
password="neuesPW"

Die Festplatte heißt Ubuntu.img. Als Port ist die 5 eingestellt, was zur Folge hat, dass sie via VNC auf dem Port 5905 erreichbar ist. Außerdem wird eine Netzwerkbrücke verwendet, wobei das letzte Byte der MAC-Adresse „05“ lautet. Und um sich per VNC aufschalten zu können, muss man das eingetragene Passwort übergeben.

Man kann in den Config-Dateien beliebig Werte weglassen. Die Zeilen müssen dann aber auch ganz aus der Datei raus, da die Werte sonst leer sind und nicht mit Standardwerten gefüllt werden.

Gespeichert werden müssen die Dateien unter <Name der VM>.conf.

6. Festplatten- und CD-Images

Die Festplatten erstellt man auf herkömmliche Weise am besten mit:

qemu-img create -f qcow2 <Name der VM>.img 80G

(für eine Platte mit dynamischer Größe, die maximal 80 GB groß wird).

CD-Images legt man in den Ordner CD-ROMs.

Hab ich irgendwas vergessen?

Ach ja, wenn eine VM die Netzwerkbrücke nutzt, kann man ihr eine beliebige IP-Adresse im physischen LAN zuweisen oder das einfach dem DHCP-Server im Router überlassen.

Wie man ein internes Netzwerk aufbaut, das nicht nach außen kommunizieren kann, werde ich mir morgen oder so mal zu Gemüte führen.

Update (Fr, 01/27 12:50):

Eine wichtige Sache hab ich hier gestern noch vergessen. Man kann QEMU mit der Option -k de starten, womit das Tastaturproblem erledigt wäre.

Übrigens bin ich natürlich noch dabei, das obige Script weiter zu entwickeln. Eine Sache habe ich hier schon ausgebessert, der Rest kommt vielleicht in einem weiteren Artikel.

Und irgendwas war da doch noch ganz wichtig zu erwähnen… Ich denke immer wieder dran, aber wenn ich es schreiben will, ist es prompt wieder weg…

Dieser Beitrag wurde unter Allgemein, Linux, Netzwerk, Virtualisierung veröffentlicht. Setze ein Lesezeichen auf den Permalink.

Schreibe einen Kommentar

Deine E-Mail-Adresse wird nicht veröffentlicht. Erforderliche Felder sind mit * markiert.