Product SiteDocumentation Site

12.2. Virtualisierung

Virtualisierung ist einer der größten Fortschritte der letzten Jahre im Computerwesen. Der Ausdruck umfasst verschiedene Abstraktionen und Techniken der Simulation virtueller Rechner mit unterschiedlichen Graden der Unabhängigkeit von der tatsächlichen Hardware. Dabei kann ein physischer Server mehrere Systeme beherbergen, die gleichzeitig und getrennt voneinander funktionieren. Es gibt zahlreiche Anwendungen, und sie rühren häufig von dieser Trennung her: zum Beispiel Testumgebungen mit unterschiedlichen Konfigurationen, oder die getrennte Unterbringung von Diensten auf unterschiedlichen virtuellen Rechnern aus Sicherheitsgründen.
Es gibt zahlreiche Virtualisierungslösungen, jede mit ihren eigenen Vor- und Nachteilen. Dieses Buch konzentriert sich auf Xen, LXC und KVM, es gibt jedoch weitere bemerkenswerte Umsetzungen einschließlich der folgenden:

12.2.1. Xen

Xen ist eine Lösung zur „Paravirtualisierung“. Es führt zwischen der Hardware und den darüber liegenden Systemen eine dünne Abstraktionsschicht ein, die „Hypervisor“ genannt wird. Diese agiert als Schiedsrichter, der den Zugang der virtuellen Rechner zur Hardware kontrolliert. Er wickelt jedoch nur einige der Instruktionen ab, der Rest wird direkt von der Hardware im Auftrag des Systems ausgeführt. Der Hauptvorteil liegt darin, dass die Leistung nicht abnimmt und die Systeme so fast dieselbe Geschwindigkeit wie bei direkter Ausführung erreichen. Die Kehrseite besteht darin, dass die Kernel der Betriebssysteme, die man mit einem Xen-Hypervisor verwenden möchte, angepasst werden müssen, um mit Xen zu funktionieren.
Lassen Sie uns einige Zeit bei den Ausdrücken bleiben. Der Hypervisor ist die unterste Schicht, die direkt auf der Hardware läuft, sogar unterhalb des Kernels. Dieser Hypervisor kann die übrige Software auf verschiedene Domains aufteilen, die man als ebenso viele virtuelle Rechner ansehen kann. Eine dieser Domains (die erste, die gestartet wird) wird als dom0 bezeichnet und spielt eine besondere Rolle, da nur diese Domain den Hypervisor und die Ausführung der übrigen Domains kontrollieren kann. Diese übrigen Domains werden domU genannt. Mit anderen Worten und aus der Sicht des Benutzers entspricht dom0 dem „Host“ bei anderen Virtualisierungssystemen, während eine domU als „Gast“ angesehen werden kann.
Zur Verwendung von Xen unter Debian sind drei Komponenten erforderlich:
  • The hypervisor itself. According to the available hardware, the appropriate package will be either xen-hypervisor-4.11-amd64, xen-hypervisor-4.11-armhf, or xen-hypervisor-4.11-arm64.
  • A kernel that runs on that hypervisor. Any kernel more recent than 3.0 will do, including the 4.19 version present in Buster.
  • Die i386-Architektur erfordert zudem eine Standardbibliothek mit passenden Patches, um Xen nutzen zu können; diese befindet sich im Paket libc6-xen.
The hypervisor also brings xen-utils-4.11, which contains tools to control the hypervisor from the dom0. This in turn brings the appropriate standard library. During the installation of all that, configuration scripts also create a new entry in the GRUB bootloader menu, so as to start the chosen kernel in a Xen dom0. Note, however, that this entry is not usually set to be the first one in the list, but it will be selected by default.
Nachdem diese Voraussetzungen installiert sind, besteht der nächste Schritt darin, das Verhalten von dom0 selbst zu testen; hierzu gehört ein Neustart des Hypervisors und des Xen-Kernels. Das System sollte auf normale Art hochfahren mit einigen zusätzlichen Meldungen auf dem Terminal während der frühen Initialisierungsschritte.
Jetzt ist es an der Zeit, unter Verwendung der Hilfsprogramme aus xen-tools tatsächlich brauchbare Systeme auf dem domU-System zu installieren. Dieses Paket stellt den Befehl xen-create-image bereit, der die Aufgabe weitgehend automatisiert. Der einzig zwingend notwendige Parameter ist --hostname, der domU einen Namen gibt. Andere Optionen sind zwar ebenfalls wichtig, können aber in der Konfigurationsdatei /etc/xen-tools/xen-tools.conf gespeichert werden, und ihr Fehlen in der Befehlszeile führt nicht zu einer Fehlermeldung. Es ist daher wichtig, entweder vor der Erstellung von Abbildern den Inhalt dieser Datei zu überprüfen oder beim Aufruf des Befehls xen-create-image zusätzliche Parameter zu verwenden. Zu den wichtigen und beachtenswerten Parametern gehören folgende:
  • --memory, um den Umfang an RAM festzulegen, den das neu erstellte System nutzen kann;
  • --size und --swap, um die Größe der „virtuellen Platten“ zu definieren, die der domU zur Verfügung stehen;
  • --debootstrap-cmd, to specify the which debootstrap command is used. The default is debootstrap if debootstrap and cdebootstrap are installed. In that case, the --dist option will also most often be used (with a distribution name such as buster).
  • --dhcp legt fest, dass die Netzwerkkonfiguration der domU durch DHCP besorgt wird, während --ip die Benennung einer statischen IP-Adresse ermöglicht.
  • Schließlich muss noch eine Speichermethode für die zu erstellenden Abbilder (diejenigen, die von der domU aus als Festplatten gesehen werden) gewählt werden. Die einfachste Methode besteht darin, mit der Option --dir auf der dom0 eine Datei für jedes Gerät zu erstellen, das der domU zur Verfügung stehen soll. Für Systeme, die LVM verwenden, besteht die Alternative darin, die Option --lvm zu nutzen, gefolgt von dem Namen einer Volume-Gruppe; xen-create-image erstellt dann ein neues logisches Volume innerhalb dieser Gruppe, und dieses logische Volume wird der domU als Festplatte zur Verfügung gestellt.
Nachdem diese Entscheidungen getroffen sind, können wir das Abbild der zukünftigen Xen-domU erstellen:
# xen-create-image --hostname testxen --dhcp --dir /srv/testxen --size=2G --dist=buster --role=udev

[...]
eneral Information
--------------------
Hostname       :  testxen
Distribution   :  buster
Mirror         :  http://deb.debian.org/debian
Partitions     :  swap            512M  (swap)
                  /               2G    (ext4)
Image type     :  sparse
Memory size    :  256M
Kernel path    :  /boot/vmlinuz-4.19.0-5-amd64
Initrd path    :  /boot/initrd.img-4.19.0-5-amd64
[...]
Logfile produced at:
         /var/log/xen-tools/testxen.log

Installation Summary
---------------------
Hostname        :  testxen
Distribution    :  buster
MAC Address     :  00:16:3E:0C:74:2F
IP Address(es)  :  dynamic
SSH Fingerprint :  SHA256:PuAGX4/4S07Xzh1u0Cl2tL04EL5udf9ajvvbufBrfvU (DSA)
SSH Fingerprint :  SHA256:ajFTX54eakzolyzmZku/ihq/BK6KYsz5MewJ98BM5co (ECDSA)
SSH Fingerprint :  SHA256:/sFov86b+rD/bRSJoHKbiMqzGFiwgZulEwpzsiw6aSc (ED25519)
SSH Fingerprint :  SHA256:/NJg/CcoVj+OLE/cL3yyJINStnla7YkHKe3/xEdVGqc (RSA)
Root Password   :  EwmQMHtywY9zsRBpqQuxZTb
Wir haben jetzt einen virtuellen Rechner, er läuft zur Zeit jedoch nicht (und belegt daher lediglich Platz auf der Festplatte der dom0). Wir können selbstverständlich weitere Abbilder erstellen, möglicherweise mit anderen Parametern.
Bevor wir diese virtuellen Rechner starten, müssen wir festlegen, wie wir auf sie zugreifen werden. Sie können natürlich als eigenständige Rechner angesehen werden, auf die nur über ihre jeweilige Systemkonsole zugegriffen wird, dies entspricht jedoch nur selten dem Nutzungsmuster. Meistens wird eine domU als entfernter Server angesehen, auf den nur über ein Netzwerk zugegriffen wird. Es wäre jedoch ziemlich umständlich, für jede domU eine Netzwerkkarte hinzuzufügen. Deshalb ist es möglich, mit Xen virtuelle Schnittstellen zu erstellen, die von jeder Domain gesehen und auf übliche Weise benutzt werden können. Man beachte, dass diese Karten, obwohl sie virtuell sind, nur von Nutzen sind, wenn sie mit einem Netzwerk verbunden sind, selbst wenn dieses virtuell ist. Xen bietet zu diesem Zweck mehrere Netzwerkmodelle:
  • Das einfachste Modell ist das bridge-Modell; alle eth0-Netzwerkkarten (sowohl in der dom0 als auch in den domU-Systemen) verhalten sich so, als wären sie direkt an einen Ethernet-Switch angeschlossen.
  • Dann kommt das routing-Modell, bei dem dom0 als Router agiert, der zwischen den domU-Systemen und dem (physischen) externen Netzwerk steht.
  • Schließlich befindet sich im NAT-Modell die dom0 ebenfalls zwischen den domU-Systemen und dem übrigen Netzwerk, jedoch sind die domU-Systeme von außen nicht direkt zugänglich, sondern der Datenverkehr wird auf der dom0 einer „Network Address Translation“ unterworfen.
Zu diesen drei Netzknoten gehören eine Reihe von Schnittstellen mit ungewöhnlichen Bezeichnungen, wie zum Beispiel vif*, veth*, peth* und xenbr0. Der Xen-Hypervisor ordnet sie gemäß dem an, was auch immer als Layout festgelegt worden ist, unter der Kontrolle der Hilfsprogramme auf der Anwenderebene. Da die NAT- und Routing-Modelle besonderen Fällen vorbehalten sind, beschäftigen wir uns hier nur mit dem Bridging-Modell.
The standard configuration of the Xen packages does not change the system-wide network configuration. However, the xend daemon is configured to integrate virtual network interfaces into any pre-existing network bridge (with xenbr0 taking precedence if several such bridges exist). We must therefore set up a bridge in /etc/network/interfaces (which requires installing the bridge-utils package, which is why the xen-utils-4.11 package recommends it) to replace the existing eth0 entry:
auto xenbr0
iface xenbr0 inet dhcp
    bridge_ports eth0
    bridge_maxwait 0
After rebooting to make sure the bridge is automatically created, we can now start the domU with the Xen control tools, in particular the xl command. This command allows different manipulations on the domains, including listing them and, starting/stopping them. You might need to increase the default memory by editing the variable memory from configuration file (in this case, /etc/xen/testxen.cfg). Here we have set it to 1024 (megabytes).
# xl list
Name                                        ID   Mem VCPUs	State	Time(s)
Domain-0                                     0  1894     2     r-----      63.5
# xl create /etc/xen/testxen.cfg
Parsing config from /etc/xen/testxen.cfg
# xl list
Name                                        ID   Mem VCPUs	State	Time(s)
Domain-0                                     0  1505     2     r-----     100.0
testxen                                     13  1024     0     --p---       0.0
Man beachte, dass die domU testxen wirklichen Speicher des RAM verwendet, der ansonsten für die dom0 verfügbar wäre, und keinen simulierten Speicher. Man sollte daher darauf achten, das physische RAM entsprechend zuzuteilen, wenn man einen Server einrichtet, auf dem Xen-Instanzen laufen sollen.
Voilà! Unser virtueller Rechner startet. Wir können auf ihn auf zweifache Art zugreifen. Der normale Weg besteht darin, sich mit ihm „aus der Ferne“ über das Netzwerk zu verbinden, wie wir es auch bei einem wirklichen Rechner tun würden; hierzu ist es normalerweise erforderlich, entweder einen DHCP-Server oder eine DNS-Konfiguration einzurichten. Der andere Weg, der der einzige sein könnte, falsch die Netzwerk-Konfiguration nicht korrekt war, besteht darin, über den Befehl xl console die Konsole hvc0 zu benutzen:
# xl console testxen
[...]

Debian GNU/Linux 10 testxen hvc0

testxen login: 
Man kann dann eine Sitzung öffnen, als säße man an der Tastatur des virtuellen Rechners. Zur Trennung von dieser Konsole dient die Tastenkombination Strg+].
Sobald eine domU läuft, kann sie so wie jeder andere Server verwendet werden (da sie schließlich ein GNU/Linux-System ist). Ihr Status als virtueller Rechner ermöglicht jedoch einige zusätzliche Funktionen. So kann eine domU zum Beispiel mit den Befehlen xl pause und xl unpause vorübergehend angehalten und dann wieder fortgesetzt werden. Man beachte, dass bei einer angehaltenen domU, obwohl sie keine Prozessorleistung in Anspruch nimmt, der ihr zugeordnete Speicherplatz weiterhin belegt ist. Es könnte interessant sein, hier die Befehle xl save und xl restore in Erwägung zu ziehen: das Speichern einer domU gibt die Ressourcen frei, die vorher von dieser domU verwendet wurden, einschließlich des RAM. Wenn sie fortgesetzt wird (oder eigentlich ihr Pausieren beendet wird), bemerkt eine domU außer dem Fortschreiten der Zeit nichts. Falls eine domU läuft, wenn die dom0 heruntergefahren wird, speichern die gebündelten Skripten automatisch die domU, und stellen sie beim nächsten Hochfahren wieder her. Dies schließt natürlich die gleichen Unannehmlichkeiten ein, die entstehen, wenn man zum Beispiel einen Laptop in den Ruhezustand versetzt; insbesondere, dass Netzwerkverbindungen verfallen, falls die domU zu lange ausgesetzt ist. Man beachte auch, dass Xen insofern mit einem Großteil der ACPI-Energieverwaltung inkompatibel ist, als es nicht möglich ist, das Host-System (die dom0) in den Bereitschaftsbetrieb zu versetzen.
Das Anhalten oder Neustarten einer domU kann entweder aus dieser domU heraus geschehen (mit dem Befehl shutdown) oder von der dom0 aus mit xl shutdown oder xl reboot.

12.2.2. LXC

Obwohl es dazu benutzt wird, „virtuelle Rechner“ zu erstellen, ist LXC genaugenommen kein Virtualisierungssystem, sondern ein System, um Gruppen von Prozessen voneinander zu isolieren, obwohl sie alle auf demselben Host laufen. Es macht sich eine Reihe neuerer Entwicklungen im Linux-Kernel zunutze, die gemeinhin als Kontrollgruppen (control groups) bekannt sind, mit denen verschiedene Sätze von Prozessen, die „Gruppen“ genannt werden, bestimmte Aspekte des Gesamtsystems auf unterschiedliche Weise sehen. Dies gilt vor allem für Aspekte wie die Prozesskennungen, die Netzwerkonfiguration und die Einhängepunkte. Eine derartige Gruppe isolierter Prozesse hat keinerlei Zugriff auf die anderen Prozesse des Systems, und ihre Zugriffe auf das Dateisystem können auf einen bestimmten Teilbereich eingegrenzt werden. Sie kann auch ihre eigene Netzwerkschnittstelle und Routing-Tabelle haben, und möglicherweise ist sie so konfiguriert, dass sie nur einen Teil der auf dem System verfügbaren Geräte sieht.
These features can be combined to isolate a whole process family starting from the init process, and the resulting set looks very much like a virtual machine. The official name for such a setup is a “container” (hence the LXC moniker: LinuX Containers), but a rather important difference with “real” virtual machines such as provided by Xen or KVM is that there is no second kernel; the container uses the very same kernel as the host system. This has both pros and cons: advantages include excellent performance due to the total lack of overhead, and the fact that the kernel has a global vision of all the processes running on the system, so the scheduling can be more efficient than it would be if two independent kernels were to schedule different task sets. Chief among the inconveniences is the impossibility to run a different kernel in a container (whether a different Linux version or a different operating system altogether).
Da wir es hier mit einer Isolierung und nicht mit einer einfachen Virtualisierung zu tun haben, ist es schwieriger, einen LXC-Container einzurichten, als nur ein Debian-Installationsprogramm auf einem virtuellen Rechner auszuführen. Wir werden einige Voraussetzungen beschreiben und dann zur Netzwerkkonfigurierung übergehen; damit werden wir in der Lage sein, das System, das in dem Container laufen soll, zu erstellen.

12.2.2.1. Vorbereitende Schritte

Das Paket lxc enthält die für die Ausführung von LXC erforderlichen Hilfsprogramme und muss daher installiert werden.
LXC benötigt außerdem das Konfigurationssystem für die Kontrollgruppen, das ein unter /sys/fs/cgroup einzuhängendes virtuelles Dateisystem ist. Weil Debian 8 auf systemd geschwenkt hat, das auch auf control groups setzt, wird es automatisch beim Starten ohne weitere Konfiguration ausgeführt.

12.2.2.2. Netzwerkkonfigurierung

The goal of installing LXC is to set up virtual machines; while we could, of course, keep them isolated from the network, and only communicate with them via the filesystem, most use cases involve giving at least minimal network access to the containers. In the typical case, each container will get a virtual network interface, connected to the real network through a bridge. This virtual interface can be plugged either directly onto the host's physical network interface (in which case the container is directly on the network), or onto another virtual interface defined on the host (and the host can then filter or route traffic). In both cases, the bridge-utils package will be required.
The simple case is just a matter of editing /etc/network/interfaces, moving the configuration for the physical interface (for instance, eth0) to a bridge interface (usually br0), and configuring the link between them. For instance, if the network interface configuration file initially contains entries such as the following:
auto eth0
iface eth0 inet dhcp
sollten sie deaktiviert und durch folgende ersetzt werden:
#auto eth0
#iface eth0 inet dhcp

auto br0
iface br0 inet dhcp
  bridge-ports eth0
Die Auswirkung dieser Konfiguration ähnelt derjenigen, die einträte, falls die Container Rechner wären, die an dasselbe physische Netzwerk angeschlossen sind wie der Host. Die „Bridge“-Konfiguration verwaltet den Übergang der Ethernet-Frames zwischen allen verbundenen Schnittstellen, zu denen sowohl die physische Schnittstelle eth0 als auch die für die Container festgelegten Schnittstellen gehören.
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.
Zusätzlich zu bridge-utils ist für diese „üppige“ Konfiguration das Paket vde2 erforderlich; die Datei /etc/network/interfaces wird dann zu:
# Schnittstelle eth0 bleibt unverändert
auto eth0
iface eth0 inet dhcp

# Virtuelle Schnittstelle
auto tap0
iface tap0 inet manual
  vde2-switch -t tap0

# Bridge für Container
auto br0
iface br0 inet static
  bridge-ports tap0
  address 10.0.0.1
  netmask 255.255.255.0
Das Netzwerk kann dann entweder statisch in den Containern eingerichtet werden oder dynamisch mit einem DHCP-Server, der auf dem Host läuft. Solch ein DHCP-Server muss so konfiguriert sein, dass er Anfragen auf der Schnittstelle br0 beantwortet.

12.2.2.3. Das System einrichten

Lassen Sie uns jetzt das von dem Container zu verwendende Dateisystem einrichten. Da dieser „virtuelle Rechner“ nicht direkt auf der Hardware laufen wird, sind im Vergleich zu einem Standard-Dateisystem einige Feineinstellungen vorzunehmen, insbesondere was den Kernel, die Geräte und Konsolen betrifft. Glücklicherweise enthält das Paket lxc Skripten, die diese Konfigurierung weitestgehend automatisieren. So installieren zum Beispiel die folgenden Befehle (die das Paket debootstrap und rsync erfordern) einen Debian-Container:
root@mirwiz:~# lxc-create -n testlxc -t debian
debootstrap is /usr/sbin/debootstrap
Checking cache download in /var/cache/lxc/debian/rootfs-stable-amd64 ... 
Downloading debian minimal ...
I: Retrieving Release 
I: Retrieving Release.gpg 
[...]
Download complete.
Copying rootfs to /var/lib/lxc/testlxc/rootfs...
[...]
root@mirwiz:~# 
Man beachte, dass das Dateisystem zunächst in /var/cache/lxc erstellt und dann in sein Zielverzeichnis verschoben wird. So lassen sich mehrere identische Container wesentlich schneller erstellen, da sie nur kopiert werden müssen.
Note that the Debian template creation script accepts an --arch option to specify the architecture of the system to be installed and a --release option if you want to install something else than the current stable release of Debian. You can also set the MIRROR environment variable to point to a local Debian mirror.
Das neu erstellte Dateisystem enthält jetzt ein minimales Debian-System, und per Voreinstellung hat der Container keine Netzwerkschnittstelle (außer Loopback). Da wir das nicht wollen, editieren wir die Konfigurationsdatei des Containers (/var/lib/lxc/testlxc/config) und fügen einige lxc.network.*-Einträge hinzu:
lxc.net.0.type = veth
lxc.net.0.flags = up
lxc.net.0.link = br0
lxc.net.0.hwaddr = 4a:49:43:49:79:20
Diese Einträge bedeuten jeweils, dass eine virtuelle Schnittstelle in dem Container erzeugt wird; dass sie automatisch in Gang gesetzt wird, wenn der besagte Container startet; dass sie automatisch mit der br0-Bridge auf dem Host verbunden wird; und dass ihre MAC-Adresse wie angegeben lautet. Falls diese letzte Angabe fehlt oder deaktiviert ist, wird eine zufällige MAC-Adresse erzeugt.
Ein anderer nützlicher Eintrag in dieser Datei ist die Angabe des Hostnamens:
lxc.uts.name = testlxc

12.2.2.4. Den Container starten

Now that our virtual machine image is ready, let's start the container with lxc-start --daemon --name=testlxc.
In LXC releases following 2.0.8, root passwords are not set by default. We can set one running lxc-attach -n testlxc passwd. Now we can login:
root@mirwiz:~# lxc-console -n testlxc
Debian GNU/Linux 9 testlxc console	

testlxc login: root
Password: 
Linux testlxc 4.19.0-5-amd64 #1 SMP Debian 4.19.37-5 (2019-06-19) x86_64

The programs included with the Debian GNU/Linux system are free software;
the exact distribution terms for each program are described in the
individual files in /usr/share/doc/*/copyright.

Debian GNU/Linux comes with ABSOLUTELY NO WARRANTY, to the extent
permitted by applicable law.
root@testlxc:~# ps auxwf
USER       PID %CPU %MEM    VSZ   RSS TTY      STAT START   TIME COMMAND
root         1  0.0  0.2  56736  6608 ?        Ss   09:28   0:00 /sbin/init
root        32  0.0  0.1  46096  4680 ?        Ss   09:28   0:00 /lib/systemd/systemd-journald
root        75  0.0  0.1  67068  3328 console  Ss   09:28   0:00 /bin/login --
root        82  0.0  0.1  19812  3664 console  S    09:30   0:00  \_ -bash
root        88  0.0  0.1  38308  3176 console  R+   09:31   0:00      \_ ps auxwf
root        76  0.0  0.1  69956  5636 ?        Ss   09:28   0:00 /usr/sbin/sshd -D
root@testlxc:~# 
Wir befinden uns nun in dem Container; unser Zugriff auf diejenigen Prozesse beschränkt, die vom Container selbst gestartet wurden, und unser Zugriff auf das Dateisystem ist in ähnlicher Weise auf die zugehörige Teilmenge des gesamten Dateisystems (/var/lib/lxc/testlxc/rootfs) eingeschränkt. Wir können die Konsole mit Control+a q wieder verlassen.
Beachten Sie, dass wir den Container beim Aufruf von lxc-start durch die Option --daemon als Hintergrundprozess laufen lassen. Wir können den Container dann mit einem Befehl wie lxc-stop --name=testlxc schließen.
Das Paket lxc enthält ein Initialisierungsskript, das automatisch einen oder mehrere Container starten kann, wenn der Host bootet (es basiert auf lxc-autostart welches Container startet, deren Option lxc.start.auto auf 1 gesetzt ist). Eine feinere Steuerung der Startreihenfolge ist mit lxc.start.order und lxc.group möglich: standardmäßig startet das Initialisierungsskript zuerst Container, die Teil der Gruppe onboot sind und dann die Container, die nicht Teil einer Gruppe sind. In beiden Fällen wird die Reihenfolge innerhalb einer Gruppe durch die Option lxc.start.order definiert.

12.2.3. Virtualisierung mit KVM

KVM, das Kernel-based Virtual Machine bedeutet, ist in erster Linie ein Kernel-Modul, das den größten Teil der Infrastruktur bereitstellt, die von einem Virtualisierungsprogramm benutzt werden kann, ist jedoch selbst kein Virtualisierungsprogramm. Die eigentliche Steuerung der Virtualisierung wird von einer Anwendung auf der Grundlage von QEMU vorgenommen. Wundern Sie sich nicht, dass dieser Abschnitt über qemu-*-Befehle spricht: er handelt dennoch von KVM.
Im Gegensatz zu anderen Virtualisierungssystemen war KVM von Anfang an Teil des Linux-Kernels. Seine Entwickler entschieden sich, die für eine Virtualisierung vorgesehenen Prozessor-Befehlssätze (Intel-VT und AMD-V) zu nutzen, wodurch KVM leichtgewichtig, elegant und ressourcenschonend bleibt. Die Kehrseite ist natürlich, dass KVM nicht auf allen Rechnerarchitekturen läuft, sondern nur auf denen mit entsprechenden Prozessoren. Sie können überprüfen, ob Sie einen derartigen Prozessor haben wenn unter den CPU-Flags in der Datei /proc/cpuinfo „vmx“ oder „svm“ aufgeführt ist.
Mit aktiver Unterstützung seiner Entwicklung durch Red Hat scheint KVM auf dem Wege zu sein, zur Referenz für Linux-Virtualisierung zu werden.

12.2.3.1. Vorbereitende Schritte

Im Gegensatz zu Programmen wie VirtualBox enthält KVM selbst keine Benutzerschnittstelle zur Erstellung und Verwaltung virtueller Rechner. Das Paket qemu-kvm stellt nur eine ausführbare Datei zum Start eines virtuellen Rechners bereit sowie ein Initialisierungsskript, das die passenden Kernel-Module lädt.
Glücklicherweise stellt Red Hat mit der Entwicklung der Bibliothek libvirt und der dazugehörigen Werkzeuge des virtual machine manager einen weiteren Satz von Hilfsprogrammen zur Lösung dieses Problems bereit. Mit libvirt ist es möglich, virtuelle Rechner einheitlich zu verwalten unabhängig von dem Virtualisierungssystem, das hinter den Kulissen beteiligt ist (gegenwärtig unterstützt es QEMU, KVM, Xen, LXC, OpenVZ, VirtualBox, VMWare und UML). virtual-manager ist eine grafische Schnittstelle, die libvirt zur Erstellung und Verwaltung virtueller Rechner benutzt.
We first install the required packages, with apt-get install libvirt-clients libvirt-daemon-system qemu-kvm virtinst virt-manager virt-viewer. libvirt-daemon-system provides the libvirtd daemon, which allows (potentially remote) management of the virtual machines running of the host, and starts the required VMs when the host boots. libvirt-clients provides the virsh command-line tool, which allows controlling the libvirtd-managed machines.
Das Paket virtinst stellt den Befehl virt-install bereit, mit dem es möglich ist, virtuelle Rechner von der Befehlszeile aus zu erstellen. Und schließlich ermöglicht virt-viewer den Zugriff auf die grafische Konsole eines virtuellen Rechners.

12.2.3.2. Netzwerkkonfigurierung

Genauso wie in Xen und LXC gehört zu der häufigsten Netzwerkkonfiguration eine Bridge, mit der die Netzwerkschnittstellen der virtuellen Rechner zusammengefasst werden (siehe Abschnitt 12.2.2.2, „Netzwerkkonfigurierung“).
Stattdessen kann (und das ist die Voreinstellung bei KVM) dem virtuellen Rechner eine private Adresse (im Bereich von 192.168.122.0/24) zugeordnet und NAT eingerichtet werden, so dass der virtuelle Rechner auf das externe Netzwerk zugreifen kann.
Für den Rest dieses Abschnitts wird angenommen, dass der Host über eine eth0 als physische Schnittstelle und eine br0-Bridge verfügt, und das Erstere mit Letzterer verbunden ist.

12.2.3.3. Installation mit virt-install

Die Erstellung eines virtuellen Rechners ist der Installation eines normalen Systems sehr ähnlich, außer dass die Eigenschaften des virtuellen Rechners in einer scheinbar endlosen Befehlszeile beschrieben werden.
In der Praxis bedeutet dies, dass wir das Debian-Installationsprogramm verwenden, indem wir den virtuellen Rechner auf einem virtuellen DVD-ROM-Laufwerk hochfahren, dem ein auf dem Host-System gespeichertes DVD-Abbild von Debian zugeordnet ist. Der virtuelle Rechner exportiert seine grafische Konsole über das VNC-Protokoll (für Einzelheiten siehe Abschnitt 9.2.2, „Entfernte grafische Arbeitsflächen benutzen“), so dass wir den Installationsprozess steuern können.
Zunächst müssen wir libvirtd mitteilen, wo die Plattenabbilder gespeichert werden sollen, es sei denn, dass der voreingestellte Ort (/var/lib/libvirt/images/) in Ordnung ist.
root@mirwiz:~# mkdir /srv/kvm
root@mirwiz:~# virsh pool-create-as srv-kvm dir --target /srv/kvm
Pool srv-kvm created

root@mirwiz:~# 
Wir wollen jetzt mit dem Installationsprozess für den virtuellen Rechner beginnen und uns die wichtigsten Optionen des Befehls virt-install ansehen. Der Befehl registriert den virtuellen Rechner und seine Parameter in libvirtd und startet ihn dann, so dass seine Installierung fortgesetzt werden kann.
# virt-install --connect qemu:///system  1
               --virt-type kvm           2
               --name testkvm            3
               --memory 1024             4
               --disk /srv/kvm/testkvm.qcow,format=qcow2,size=10  5
               --cdrom /srv/isos/debian-10.2.0-amd64-netinst.iso  6
               --network bridge=virbr0   7
               --graphics vnc            8
               --os-type linux           9
               --os-variant debian10

Starting install...
Allocating 'testkvm.qcow'             |  10 GB     00:00

1

Die Option --connect legt den zu verwendenden „Hypervisor“ fest. Sie hat die Form einer URL, die ein Virtualisierungssystem enthält (xen://, qemu://, lxc://, openvz://, vbox:// und so weiter) und den Rechner, der den virtuellen Rechner aufnehmen soll (dies kann leer bleiben, falls es sich dabei um den lokalen Host handelt). Zusätzlich hierzu, und im Fall vom QEMU/KVM, kann jeder Benutzer virtuelle Rechner, die mit eingeschränkten Berechtigungen laufen, verwalten, wobei der URL-Pfad es ermöglicht, „System“-Rechner (/system) von anderen (/session) zu unterscheiden.

2

Da KVM auf die gleiche Weise wie QEMU verwaltet wird, kann mit --virt-type kvm die Verwendung von KVM festgelegt werden, obwohl die URL aussieht, als würde QEMU verwendet.

3

Die Option --name legt einen (eindeutigen) Namen für den virtuellen Rechner fest.

4

The --memory option allows specifying the amount of RAM (in MB) to allocate for the virtual machine.

5

The --disk specifies the location of the image file that is to represent our virtual machine's hard disk; that file is created, unless present, with a size (in GB) specified by the size parameter. The format parameter allows choosing among several ways of storing the image file. The default format (qcow2) allows starting with a small file that only grows when the virtual machine starts actually using space.

6

Die Option --cdrom wird zur Anzeige des Ortes verwendet, an dem sich die optische Platte befindet, die für die Installierung benutzt wird. Der Pfad kann entweder ein lokaler Pfad zu einer ISO-Datei sein, eine URL, von der die Datei bezogen werden kann, oder die Gerätedatei eines physischen CD-ROM-Laufwerks (das heißt /dev/cdrom).

7

Mit --network wird festgelegt, wie sich die virtuelle Netzwerkkarte in die Netzwerkkonfiguration des Hosts integriert. Das voreingestellte Verhalten (das in unserem Beispiel ausdrücklich erzwungen wird) besteht darin, sie in eine bereits bestehende Netzwerk-Bridge einzubinden. Falls es eine derartige Bridge nicht gibt, kann der virtuelle Rechner das physische Netzwerk nur über NAT erreichen, das heißt, dass er eine Adresse in einem privaten Teilnetzbereich erhält (192.168.122.0/24).

8

--graphics vnc states that the graphical console should be made available using VNC. The default behavior for the associated VNC server is to only listen on the local interface; if the VNC client is to be run on a different host, establishing the connection will require setting up an SSH tunnel (see Abschnitt 9.2.1.3, „Verschlüsselte Tunnel mit Port-Weiterleitung einrichten“). Alternatively, --graphics vnc,listen=0.0.0.0 can be used so that the VNC server is accessible from all interfaces; note that if you do that, you really should design your firewall accordingly.

9

Mit den Optionen --os-type und --os-variant lassen sich einige Parameter des virtuellen Rechners optimieren in Abhängigkeit von den bekannten Funktionen des Betriebssystems, das hier genannt wird.
Jetzt läuft der virtuelle Rechner, und wir müssen uns mit der grafischen Konsole verbinden, um den Installationsprozess fortzusetzen. Falls die bisherigen Schritte in einer grafischen Arbeitsumgebung ausgeführt wurden, sollte diese Verbindung von sich aus starten. Anderenfalls, oder falls wir aus der Ferne arbeiten, kann virt-viewer von jeder beliebigen grafischen Umgebung aus aufgerufen werden, um die grafische Konsole zu öffnen (man beachte, dass zweimal nach dem Root-Passwort des entfernten Hosts gefragt wird, da dieser Arbeitsgang zwei SSH-Verbindungen erfordert):
$ virt-viewer --connect qemu+ssh://root@server/system testkvm
root@server's password: 
root@server's password: 
Wenn der Installationsprozess endet, startet der virtuelle Rechner neu und ist dann einsatzbereit.

12.2.3.4. Rechner mit virsh verwalten

Nachdem die Installation nunmehr erledigt ist, wollen wir sehen, wie man mit den vorhandenen virtuellen Rechnern umgeht. Zunächst soll libvirtd nach einer Liste der virtuellen Rechner, die er verwaltet, gefragt werden:
# virsh -c qemu:///system list --all
 Id Name                 State
----------------------------------
  8 testkvm              shut off
Lassen Sie uns unseren virtuellen Testrechner starten:
# virsh -c qemu:///system start testkvm
Domain testkvm started
Wir können jetzt die Verbindungshinweise für die grafische Konsole bekommen (die angegebene VNC-Anzeige kann als Parameter an vncviewer übergeben werden):
# virsh -c qemu:///system vncdisplay testkvm
127.0.0.1:0
Zu den weiteren bei virsh verfügbaren Unterbefehlen gehören:
  • reboot, um einen virtuellen Rechner neu zu starten;
  • shutdown, um ein sauberes Herunterfahren einzuleiten;
  • destroy, um ihn brutal zu stoppen;
  • suspend, um ihn in den Bereitschaftsbetrieb zu versetzen;
  • resume, um ihn wieder in Betrieb zu nehmen;
  • autostart, um den automatischen Start des virtuellen Rechners beim Hochfahren des Hosts zu aktivieren (oder ihn mit der Option --disable zu deaktivieren);
  • undefine, um alle Spuren des virtuellen Rechners von libvirtd zu entfernen.
Alle diese Unterbefehle erfordern als einen ihrer Parameter die Kennung eines virtuellen Rechners.

12.2.3.5. Ein RPM-basiertes System in Debian mit yum installieren

Wenn auf der virtuellen Maschine ein Debian-System (oder eines seiner Derivate) laufen soll, kann das System mit debootstrap aufgesetzt werden, wie oben beschrieben. Soll aber auf der virtuellen Maschine ein RPM-basiertes System laufen, dann muss es mit dem Utility yum (aus dem gleichnamigen Paket) installiert werden.
Die Prozedur erfordert die Verwendung von rpm, um einen ersten Satz von Dateien zu extrahieren, insbesondere yum Konfigurationsdateien gefolgt vom Aufruf von yum, um den restlichen Satz von Paketen zu extrahieren. Aber da wir yum von außerhalb des chroot aufrufen, müssen wir einige temporäre Änderungen vornehmen. Im Beispiel unten ist das Ziel chroot /srv/centos.
# rootdir="/srv/centos"
# mkdir -p "$rootdir" /etc/rpm
# echo "%_dbpath /var/lib/rpm" > /etc/rpm/macros.dbpath
# wget http://mirror.centos.org/centos/7/os/x86_64/Packages/centos-release-7-6.1810.2.el7.centos.x86_64.rpm
# rpm --nodeps --root "$rootdir" -i centos-release-7-6.1810.2.el7.centos.x86_64.rpm
rpm: RPM should not be used directly install RPM packages, use Alien instead!
rpm: However assuming you know what you are doing...
warning: centos-release-7-6.1810.2.el7.centos.x86_64.rpm: Header V3 RSA/SHA256 Signature, key ID f4a80eb5: NOKEY
# sed -i -e "s,gpgkey=file:///etc/,gpgkey=file://${rootdir}/etc/,g" $rootdir/etc/yum.repos.d/*.repo
# yum --assumeyes --installroot $rootdir groupinstall core
[...]
# sed -i -e "s,gpgkey=file://${rootdir}/etc/,gpgkey=file:///etc/,g" $rootdir/etc/yum.repos.d/*.repo