QEMU/KVM: 1 Woche Downtime

Der aufmerksame Leser wird es gemerkt haben, dckg.net war nun fast eine Woche nicht erreichbar.
Was war los? Ich wollte Virtualisierung nutzen, was sich doch als eine etwas langwierige Aktion herausstellte.

Es hat für mich nicht hinreichend funktioniert, trotzdem der Post, vielleicht bringt es dem einen oder anderen etwas:

------------------------------

Virtualisierung. Was bringt Virtualisierung, neben einem Haufen Aufwand?
Sicherheit. Skalierbarkeit. Integrität. Effizientere Ressourcennutzung.

Eine Rechnung: Bei Hetzner kostet ein 64GB RAM Server 50€ pro Monat. Setz man darauf nun 64 VMs mit je 1GB RAM auf, so hat man daraufhin 64 vServer zur Verfügung. Wollte ich diese Menge VMs direkt fertig mieten, wären das bei Hetzner wiederrum 5€ pro VM pro Monat, gesamt demzufolge 320€ jeden Monat.

Hier und dort mal etwas testen, anderen etwas zeigen, ohne gleich jedem root-Zugriff auf den Server selbst zu geben, es gibt viele Fälle, in denen sich die Möglichkeit, schnell auf eine kostenlose, öffentliche Test-VM zugreifen zu können, als nützlich erweisen könnte.
KVM bezeichnet Kernel-based Virtual Machine. Hierbei agiert KVM, welches standardmößig im Kernel verfügbar ist, als Hypervisor. Auf diese Weise ist eine Vollständige Virtualisierung möglich, z.B. könnte ich eine Windows Instanz in einer KVM VM laufen lassen, wie man es sowohl von VirtualBox, als auch von VMware ESXi gewohnt ist.

In Zeiten von Mehrkernprozessoren lohnt es besonders, Virtualisierung einzusetzen, um die CPU besser auszulasten.
Hardwarevoraussetzungen:
egrep -c '(vmx|svm)' /proc/cpuinfo
Muss ungleich 0 ergeben, insofern unterstützt die CPU Virtualisierung.

Mein aktuelles Setup sieht folgendermaßen aus:
Eine dedibox SC gen2 von online.net, 2GB RAM, VIA Nano processor U2250 (1.6GHz Capable),
1xIPv4
1xIPv6 /56 Subnet

Es gibt eine einzige öffentliche IPv4, bestimmte Dienste sollen bei Bedarf per Portweiterleitung unter dieser öffentlichen IPv4 erreichbar sein. Zusätzliche IPv4 sind zu teuer und ohnehin ein Auslaufmodell.
IPv6 hat die Maschine ein ganzes /56 Subnet zugeweisen bekommen, was ermöglicht es, jeder VM ihr eigenes, öffentliches IPv6 Subnet, zuzuweisen.

online.net spezifisch
Ich gehe davon aus, dass IPv6 via dhclient6 konfiguriert ist9.
Darüber hinaus ist Virtualisierung mit dem VIA NANO U2250 unter dem Linux Kernel 3.16+ nicht möglich. Mit Kernel 4.3 aufwärts (Debian unstable) hatte ich keine weniger Probleme mehr.

Falsche Änderungen an der Netzwerkkonfiguration (/etc/network/interfaces) können immer mit einem nicht mehr erreichbaren Server enden.
Das nur als Warnung.

Netzwerkkonfiguration Host
In cases where this configuration cannot be used (for instance if no public IP addresses can be assigned to the containers), a virtual tap interface will be created and connected to the bridge. The equivalent network topology then becomes that of a host with a second network card plugged into a separate switch, with the containers also plugged into that switch. The host must then act as a gateway for the containers if they are meant to communicate with the outside world. 2

Eine Bridge (IPv6) und ein tap-Adapter (IPv4) werden lt. der Quelle oben gebraucht. (Erfordert vde2 bridge-utils uml-utilities).
Eine Bridge ist vergleichbar mit einem Switch, an den die VMs angeschlossen werden, welcher selbst an eth0 angeschlossen ist.

Original:
# This file describes the network interfaces available on your system
# and how to activate them. For more information, see interfaces(5).
Blog
source /etc/network/interfaces.d/*

# The loopback network interface
auto lo
iface lo inet loopback

# The primary network interface
allow-hotplug eth0
iface eth0 inet dhcp

iface eth0 inet6 static
address 2001:xxx:xxxx💯:
netmask 56
accept_ra 1
pre-up dhclient -cf /etc/dhcp/dhclient6.conf -pf /run/dhclient6.br0.pid -6 -P eth0
pre-down dhclient -x -pf /run/dhclient6.br0.pid


Zehn Stunden später...
# This file describes the network interfaces available on your system
# and how to activate them. For more information, see interfaces(5).

source /etc/network/interfaces.d/*

# The loopback network interface
auto lo
iface lo inet loopback
iface lo inet6 loopback

# The primary network interface
allow-hotplug br0
auto br0
iface br0 inet dhcp
bridge_ports eth0
bridge_stop off
bridge_fd 0
bridge_maxwait 0

# IPv4 NAT
auto br1
iface br1 inet static
bridge_fd 0
bridge_waitport 0
bridge_ports none
address 172.16.0.1
netmask 255.240.0.0
network 172.16.0.0
broadcast 172.16.0.255
gateway 195.111.11.248

iface br0 inet6 static
address 2001:xxx:xxxx💯:
netmask 56
bridge_ports eth0
accept_ra 1
pre-up dhclient -cf /etc/dhcp/dhclient6.conf -pf /run/dhclient6.br0.pid -6 -P br0
pre-down dhclient -x -pf /run/dhclient6.br0.pid
up ifconfig br0 inet6 add 2001:0xxx:xxxx:0101::/64
up ifconfig br0 inet6 add 2001:0xxx:xxxx:0102::/64
down ifconfig br0 inet6 del 2001:0xxx:xxxx:0101::/64
down ifconfig br0 inet6 del 2001:0xxx:xxxx:0102::/64

Einer anderen Quelle14 zufolge, kann ein NAT IPv4 auch mit einer Bridge realisiert werden, hier br1.

Des weiteren muss in der /etc/dhcp/dhclient6.conf das Interface auf br0 geändert werden. (online.net spezifisch)

Anschließend
service networking restart

Oder besser einen reboot ausführen.

ifconfig
br0       Link encap:Ethernet  HWaddr xx:xx:xx:xx:xx:xx  
        inet addr:195.111.11.248 Bcast:195.111.11.255 Mask:255.255.255.0
        inet6 addr: 2001:xxx:xxxx:102::/64 Scope:Global
        inet6 addr: 2001:xxx:xxxx:101::/64 Scope:Global
        inet6 addr: 2001:xxx:xxxx💯:/56 Scope:Global
        inet6 addr: fe80::xxxx:xxxx:xxxx:xxxx/64 Scope:Link
        UP BROADCAST RUNNING MULTICAST MTU:1500 Metric:1
        RX packets:401 errors:0 dropped:0 overruns:0 frame:0
        TX packets:205 errors:0 dropped:0 overruns:0 carrier:0
        collisions:0 txqueuelen:0
        RX bytes:42292 (41.3 KiB) TX bytes:27105 (26.4 KiB)

br1 Link encap:Ethernet HWaddr xx:xx:xx:xx:xx:xx
        inet addr:172.16.0.1 Bcast:172.16.0.255 Mask:255.240.0.0
        inet6 addr: fe80::9cbe:c1ff:fe05:5525/64 Scope:Link
        UP BROADCAST RUNNING MULTICAST MTU:1500 Metric:1
        RX packets:0 errors:0 dropped:0 overruns:0 frame:0
        TX packets:8 errors:0 dropped:0 overruns:0 carrier:0
        collisions:0 txqueuelen:0
        RX bytes:0 (0.0 B) TX bytes:648 (648.0 B)

eth0 Link encap:Ethernet HWaddr xx:xx:xx:xx:xx:xx
        UP BROADCAST RUNNING MULTICAST MTU:1500 Metric:1
        RX packets:414 errors:0 dropped:0 overruns:0 frame:0
        TX packets:216 errors:0 dropped:0 overruns:0 carrier:0
        collisions:0 txqueuelen:1000
        RX bytes:50992 (49.7 KiB) TX bytes:29139 (28.4 KiB)
        Interrupt:28 Memory:feae0000-feb00000

lo Link encap:Local Loopback
        inet addr:127.0.0.1 Mask:255.0.0.0
        inet6 addr: ::1/128 Scope:Host
        UP LOOPBACK RUNNING MTU:65536 Metric:1
        RX packets:10 errors:0 dropped:0 overruns:0 frame:0
        TX packets:10 errors:0 dropped:0 overruns:0 carrier:0
        collisions:0 txqueuelen:0
        RX bytes:500 (500.0 B) TX bytes:500 (500.0 B)


Die Adresse unter br1 muss sich pingen lassen.
Zugleich hält eth0 keine IP-Adressen mehr.

NATting
sysctl net.ipv4.conf.br1.forwarding=1
sysctl net.ipv4.ip_forward=1

iptables -t nat -A PREROUTING -d ${Host_ipaddr} -p tcp --dport ${Host_port[$i]} -j DNAT --to ${Guest_ipaddr}:${Guest_port[$i]}
iptables -I FORWARD -d ${Guest_ipaddr}/32 -p tcp -m state --state NEW -m tcp --dport ${Guest_port[$i]} -j ACCEPT

iptables -t nat -A POSTROUTING -s 172.16.0.1/24 -j SNAT --to public_ipv4
16

Danach muss von der privaten IPv4 das öffentliche Internet erreichbar sein:
wget --bind 172.16.0.1 -qO- icanhazip.com


Setup Desktop
apt-get install qemu-kvm libvirt-bin virtinst virt-manager virt-viewer


Setup Server
apt-get install qemu-kvm libvirt-bin virtinst grml-debootstrap uuid vde2 bridge-utils libguestfs-tools


Installation des Gastsystems
VM mit Debian8 erstellen, hier ist mein Favorit erneut grml.
Mithilfe von grml, ist eine automatische Debian Installation möglich, ohne Benutzereingaben. Dauer ca. 20 Min bei meinem langsamen Prozessor.
grml-debootstrap --vmfile --hostname vm --password root -m http://mirrors.online.net/debian --target /var/lib/libvirt/images/debian8.img
Die default-Größe der Datei ist 2GB, welche hier noch nicht geändert werden sollte.

Darauffolgend sorgt eine Umwandlung ins effizientere, was Speicherbelegung angeht, qcow2 Format, für reduzierten Speicherverbrauch und das Nutzen von erweiterten Funktionen wie beispielsweise Snapshots.
qemu-img convert -f raw -O qcow2 /var/lib/libvirt/images/debian8.img /var/lib/libvirt/images/debian8.qcow2
rm /var/lib/libvirt/images/debian8.img
#qemu-img resize foo.qcow2 30G # Größe des Images anpassen


Alternativ per Kommandozeile mit dem Debian-Installer, für alle, die es Interaktiv mögen.

qemu-img create -f qcow2 /var/lib/libvirt/images/debian8.qcow2 10G
virt-install \
--name debian8 \
--ram 1024 \
--vcpus 1 \
--virt-type qemu \
--disk path=/var/lib/libvirt/images/debian8.qcow2,format=qcow2 \
--os-type linux \
--os-variant debianwheezy \
--network bridge=br0 \
--network bridge=br1 \
--graphics none \
--console pty,target_type=serial \
--location 'http://ftp.fr.debian.org/debian/dists/stable/main/installer-amd64/' \
--extra-args 'console=ttyS0,115200n8 serial'
18

Konfiguration des Gastsystems
virsh per Kommandozeile und von Hand xml Dateien Editieren sind eine Option, mir persönlich aber zu unbequem.
virt-manager ist eine Desktop GUI Applikation zum Verwalten von Virtuellen Maschinen. Wer schon einmal VirtualBox genutzt hat, wird sich damit schnell zurechtfinden.

Nachdem ich per Kommandozeile (virt-install) und dem 4er Kernel erfolgreich eine Debian Installation gestartet hatte, in der Konsole der Standard Debian Installer mit den ewig langen Ladebalken erschien, habe ich abgebrochen.
Ich möchte nämlich zwingend den Virtual Machine Manager verwenden.
Ergo mit grml eine virtuelle HDD inkl. System erstellt, um alsdann die Konfiguration mit dem VMM vorzunehmen.
Nichtsdestotrotz crasht der Server erneut (Reset nur noch über WebUI des Hosters Möglich), in dem Augenblick, als ich eine neue "Domain" erstelle, die initiale Konfiguration der VM abschließe. Selbes Problem mit dem 3.16er Kernel, plus, dass dort nicht einmal virt-install funktioniert.

KVM/QEMU ist höchstwahrscheinlich inkompatibel mit meiner Hardware. Sie ist ohnehin zu leistungsschwach.

Weiter mit LXC...

Quellen/Linkliste
1 Debian Handbuch - 12.2.3. Virtualization with KVM
2 Debian Handbuch - 12.2.2.2. Network Configuration
3 Debian Wiki - KVM
4 Debian Wiki - QEMU
5 QEMU - Creating an Image
6 KVM Networking
7 IPv6 Subnet Calculator
8 Debian Wiki - LibVirtDefaultNetwork
9 online.net IPv6 config
10 Debian Wiki - Bridges and VLANs
11 KVM Guest with NAT + Bridged networking
12 Proxmox Network Model
12 iptables masquerading
13 setting up qemu with a nat
14 Home Lab Project: Network Bridges for KVM - NAT, Host-only, Isolated
15 libvirt/qemu ipv4/ipv6 Dual Stack
16 libvirt wiki - networking
17 Hetzner Root-Server with Debian/KVM IPv4 and IPv6 Networking
18 RedHat - 6.2. Creating guests with virt-install
19 Installing Virtual Machines with virt-install, plus copy pastable distro install one-liners