XEN Update
XENvelopemt
Einleitung
Seit Einführung der Virtualisierungslösung KVM direkt im Linux Kernel ist es in den letzten Jahren stiller um den älteren XEN-Hypervisor geworden. Als Typ 1 Hypervisor wurde ihm immer als Nachteil ausgelegt, nicht direkt im Linux Kernel angesiedelt zu sein. Bei genauer Betrachtung erscheint mir persönlich das eher als Vorteil denn als Nachteil. Seine Entwicklung und Unterstützung steht auf einer Basis, welche tatsächlich unabhängig von einem bestimmten Kernel bzw. Betriebsystem ist. Der XEN Hypervisor ist also KEINE Linux-Lösung, sondern kann ebenfalls auf alternativen BSD oder Unix Systemen [1] wie z.B. FreeBSD aufbauen.
Was zeichnet XEN als Hypervisor aus
- alt = ausgereift (Erfahrung, hat sich bewährt)
- klein = sicher (einfach, weniger Fehler) und stabil (weniger Code, weniger Fehler)
- Modular = unabhängig (OS) und flexibel (Einsatzszenarien)
- Typ 1 Hypervisor = performant
- Breite Hardware Unterstützung (ARM, Embedded, Cloud/IoT usw.)
Konzept
Die Virtualisierungslösung XEN besteht aus einem Hostsystem, Dom0 genannt, welches einer ganz normalen Linux-, BSD oder Unix Installation entspricht. Einziger Unterschied ist, dass nicht der normale System-Kernel direkt gestartet wird, sondern der XEN Hypervisor (xen.gz) diesen Kernel (Debian: vmlinuz) startet. Die Management Domain Dom0 selbst ist damit ein Standard Linux System, bei mir seit mehr als 10 Jahren Debian, derzeit Buster.
Auf dem Management System Dom0 selbst wird natürlich keinerlei Software oder Funktionalität installiert, dafür verwendet man ja die VMs. Sie dient ausschliesslich dem Management der virtualisierten Hardware- und Infrastruktur (Software-) komponenten für die geplanten virtuellen Maschinen (VM), bei XEN als DomU bezeichnet.
Einige interessante aktuelle Entwicklungen im XEN Umfeld
- Driver Domain [2]
- Dom0 Disaggregation [3]
- XAPI (XEN Management API)
- XCPng [4](OpenSource Nachfolger des Citrix XEN Server)
- Xen on Embedded and Automotive systems [5]
- Unikernels [6][7]
- Qubes OS [8] (OS auf XEN Basis mit maximaler Sicherheit)
Für XEN Endanwender wie mich sind hier die Punkte Driver Domain und Disaggregation interessant. Qubes OS treibt diese beiden Ansätze auf die Spitze und hat damit ein maximal sicheres und freies Betriebsystem auf XEN Basis erstellt (empfohlen und genutzt z.B. von Edward Snowden), indem sie nicht jeweils ein ganzes System virtualisieren, sondern einzelne Applikationen. So gibt es z.B. einen Browser in einer "privaten" Umgebung, einen Browser in einer "Arbeit" Umgebung und evtl. noch einen separaten in einer "Banking" Umgebung.
Die Entwicklungen im Bereich Embedded/Automotive im Zusammenspiel mit maximaler Sicherheit und auch die Implementierungen in Cloud/IoT Bereich zeigen, das XEN durchaus aktuelle und höchst interessante Weiterentwicklungen erfährt. Warum? Vermutlich gerade durch die oben genannten Punkte in Zusammenhang mit dem OpenSource Ansatz und der durch den kleinen, einfachen, performanten und sicherem Design des Hypervisors, der für alle Anwendungsbereiche Vorteile aufweisen kann.
XEN steht IMHO daher einzig aus Endanwendersicht hinter besser integrierten Lösungen wie KVM zurück, ob das derzeit tatsächlich noch gerechtfertigt ist oder nicht sei von jedem selbst zu bewerten. Eine XEN Installation ist inzwischen nicht komplizierter als eine KVM Installation, trotz der zusätzlichen XEN Schicht unter dem eigentlichem Hostsystem.
Praxis für Endanwender
Einfach gesagt: Performance und Sicherheit der XEN Virtualisierung steigen, indem das Hostsystem Dom0 möglichst wenig selbst machen muss bzw. kann. Man möchte also soviel wie möglich auslagern. Das Konzept wird bei XEN als Domain Disaggregation bezeichnet.
XEN Driver Domain
Eine Driver Domain ist ein erster Schritt der Dom0 Disaggragtion: Funktionen von Hardware Treibern werden aus der Dom0 in eine VM ausgelagert, eine ganz normale DomU (PV). Sie dient den anderen VMs als Driver-Backend für z.B. Netzwerk, Storage und USB.
XEN Network Driver Domain mit Debian (Buster, XEN 4.11 oder Bullseye, XEN 4.14)
Status: Implemented and running ;-)
Wir starten damit, der Dom0 die Netzwerkkarte wegzunehmen (LOL), und verfrachten diese in eine Network Driver Domain. Das Henne - Ei Problem Netzwerk lösen wir dadurch, das wir zuerst ganz normal die Dom0 installieren, und eine weitere DomU. Wenn beide installiert sind, können wir die Netzwerkkonfiguration so ändern, dass die Netzwerkkarte nach einem Neustart der DomU zugeordnet ist, und die Dom0 ein virtuelles Netzwerkinterface benutzt.
- Hardware Adresse der Netzwerkarte(n) ermitteln und in einer Konfigurationsdatei /etc/xen/xen-pciback.conf speichern
# lspci | awk '/Ethernet/ {print "#"$1" #"$2" "$3" "$4}' > /etc/xen/xen-pciback.conf # cat /etc/xen/xen-pciback.conf 00:19.0 #Ethernet controller: Intel #02:00.0 #Ethernet controller: Intel #03:00.0 #Ethernet controller: Intel
- Der Dom0 die Netzwerkkarte wegnehmen
In obigem Beispiel soll z.B. nur das OnBoard-Netzwerkinterface (00:19.0) dem XEN Backend zugeordnet werden. Folgendes Skript hilft dabei, PCI-Karten aus dem Konfigfile aus der Dom0 zu lösen:
NAME=xen-pciback MODULE=xen_pciback CONFIGNAME=/etc/xen/$NAME.conf modprobe $MODULE cat $CONFIGNAME | awk '{if ($1 !~ /#/) print $1}' | while read PCI ; do [ -n "$PCI" ] && xl pci-assignable-remove -r echo $PCI done
Hier ist das entsprechende Debian Init-Script /etc/init.d/xen-pcibackend .
Network Driver Domain Konfiguration
Die Network Driver Domain erhält neben dem PCI Device noch ein virtuelles Netzwerkinterface für die Dom0.
/etc/xen/Domain-N.cfg
name = 'Domain-N' vcpus = '1' memory = '256' bootloader = 'pygrub' disk = [ 'phy:/dev/ssd/Domain-N-disk,xvda2,w', 'phy:/dev/ssd/Domain-N-swap,xvda1,w' ] vif = [ 'ip=192.168.1.4, bridge=xenbr0' ] pci = [ '00:19.0' ] # Ethernet controller: Intel
Die Dom0 verbindet sich mit der Network Driver Domain wie üblich über die virtuelle Bridge xenbr0 (vif=[bridge=xenbr0]).
XEN-Bridge Konfiguration der Dom0 in /etc/network/interfaces (Debian)
# --------------------------------- # settings for all XEN bridges # --------------------------------- iface xenbridge inet manual pre-up brctl addbr $IFACE bridge_fd 0 bridge_stp off bridge_hello 1 bridge_maxwait 0 bridge_waitport 0 post-up ip link set $IFACE promisc off post-down brctl delbr $IFACE # ---------------------------------------------------------- # xenbr0 -> Dom0 Network Interface connects to Driver Domain # ---------------------------------------------------------- auto xenbr0 iface xenbr0 inet static inherits xenbridge address 192.168.1.5/24 gateway 192.168.1.4
Die Network Driver Domain ist jetzt die einzige Verbindung der Dom0 zur Aussenwelt. In den meisten Fällen muss daher in dieser IP-Forwarding aktiviert werden, damit die Dom0 weiterhin Updates erhalten kann. Je nach Netzwerk-Design muss auch auf dem Internet-Router eine Route zur Dom0 mit Domain-N als Gateway eingerichtet werden. Eine 'Outgoing NAT' Regel für die Dom0 in Richtung Internet muss natürlich ebenfalls aktiv sein.
sysctl -w net.ipv4.ip_forward=1 # or make it permanent: uncomment in /etc/sysctl.conf and execute sysctl -p for refresh # Uncomment the next line to enable packet forwarding for IPv4 net.ipv4.ip_forward=1
Alternativ kann man die Dom0 natürlich von einem internem Update-Mirror mit Updates versorgen. Dann braucht die Dom0 keine Verbindung mehr zum Internet. Sofern Domain-N selbst als Mirror dient, braucht man auch kein IP-Forwarding, und die Dom0 ist NUR von der Domain-N aus erreichbar.
XEN Konfiguration innerhalb der XEN Driver Domain
Die Network Driver Domain erfüllt initial nur einen Zweck: Die Netzwerkkarte den anderen VMs zur Verfügung stellen. Dazu verbindet man die Netzwerkkarte mit einer Bridge, welche die virtuellen Interfaces aller VMs mit der Netzwerkkarte verbindet. Zusätzlich wird eine Netzwerkverbindung über das virtuelle Interface eth0 mit der Dom0 eingerichtet.
Netzwerkkonfiguration der Domain-N in /etc/network/interfaces (Debian)
# --------------------------------------- # The (routing) network interface to Dom0 # --------------------------------------- auto eth0 iface eth0 inet static address 192.168.1.4/24 # --------------------------------- # settings for all XEN bridges # --------------------------------- iface xenbridge inet manual pre-up brctl addbr $IFACE bridge_fd 0 bridge_stp off bridge_hello 1 bridge_maxwait 0 bridge_waitport 0 post-up ip link set $IFACE promisc off post-down brctl delbr $IFACE # ------------------------------------------- # br_lan -> Network Backend Interface vor VMs # ------------------------------------------- auto br_lan iface br_lan inet static inherits xenbridge bridge_ports none address 192.168.2.4/24 gateway 192.168.2.12 # --------------------------------- # The backend network device enp0s0 # --------------------------------- auto enp0s0 iface enp0s0 inet manual pre-up ifup br_lan up brctl addif br_lan $IFACE down brctl delif br_lan $IFACE
Nach dem Booten der Domain-N hat diese jetzt folgende Netzwerkkonfiguration:
- eine Bridge für die VMs (br_lan)
- ein virtuelles Interface für die Dom0 (eth0)
- die Netzwerkkarte die mit der Bridge verbunden ist (enp0s0)
- eine Default-Route
Domain-N:~# brctl show bridge name bridge id STP enabled interfaces br_lan 8000.6805ca23181e no enp0s0 Domain-N:~# ip -br a lo UNKNOWN 127.0.0.1/8 ::1/128 eth0 UP 192.168.1.4/24 fe80::216:3eff:fe28:e73/64 enp0s0 UP fe80::6a05:caff:fe23:181e/64 br_lan UP 192.168.2.4/24 fe80::28c8:c4ff:feac:7489/64 Domain-N:~# ip -br r default via 192.168.2.12 dev br_lan onlink 192.168.1.0/24 dev eth0 proto kernel scope link src 192.168.1.4
XEN -Tools und -Utils Installation in Domain-N
Die Driver Domain muss Zugriff auf die XEN Konfigurationsdatenbank xenstore erhalten, damit die grundlegenden Konfigurationsdaten der laufenden XEN Instanzen zwischen der Dom0 von der Driver Domain ermittelt werden können. Hierzu werden die xen-utils Pakete installiert.
Domain-N:~# apt-get install --no-install-recommends xen-utils
Jede virtuelle Maschine die unsere Domain-N als Network-Backend benutzt, erzeugt hier dynamisch ein neues virtuelles Netzwerkinterface vifx.y, wobei x die ID der XEN-VM entspricht, und y der Interface-ID. Den Namen kann man aber in der XEN Konfiguration der VM mit dem Parameter vifname frei definieren. Diese dynamisch erzeugten Interfaces müssen automatisch der Bridge br_lan hinzugefügt werden. Das kann auf zwei Arten erfolgen:
- man definiert die entsprechenden statischen Einträge in /etc/network/interfaces
- oder ein Daemon erledigt diese Arbeit automatisch
Lösung zu 1) statische Konfiguration in /etc/network/interfaces
auto /vif* allow-hotplug /vif* iface vif_vm2 inet manual pre-up ifup br_lan up brctl addif br_lan $IFACE down brctl delif br_lan $IFACE ...
Lösung zu 2) dynamische Konfiguration mittels xl devd Der Daemon der diese Aufgabe erledigt wird mitels xl devd gestartet. Daher müssen die XEN-Utils installiert sein, was wir schon vorhin erledigt haben.
xl devd
Hier ist ein entsprechendes Init-Skript zum Start des Daemons
Nach dem Start einer neuen wurde das virtuelle Interface automatisch mit der Backend-Bridge verbunden:
Domain-N:~# brctl show bridge name bridge id STP enabled interfaces br_lan 8000.6805ca23181e no enp0s0 vif_vm2
Die entprechende Eintrag in der XEN Konfiguration für die VM lautet:
vif = [ 'bridge=br_lan, vifname=vif_vm2, backend=Domain-N' ]
XEN Start-/Stop- Reihenfolge von VMs
Nachdem zukünftig alle VMs von der Driver Domain abhängig sind, um Netzwerkverbindung zu erhalten, müssen wir uns noch um die Startreihenfolge kümmern. Beim Runterfahren des gesamten Systems sollte die Driver Domain auch erst nach allen anderen VMs runterfahren. Hierzu passen wir innerhalb der Dom0 das File xendomains an, welches alle VMs automatisch startet und auch stopped.
Die Idee ist, dass wir ein 2.tes Start-/Stop- File xendomains.local anlegen, welches alle VMs die nicht die Driver Domain Domain-N, eine Firewall (opnsense) oder ein File-Server sind zuerst stoppen, dann den File-Server und anschliessend die Firewall stoppen, bevor das normale xendomains Skript alle restlichen virtuellen Maschinen runterfährt, welches jetzt nur noch die Driver Domain Domain-N sein sollte.
Hier ist das zusätzliche Dom0 Init-Skript /etc/init.d/xendomains.local zum stoppen der VMs in vorgegebener Reihenfolge.
XEN StubDom
ToDo: Implement OpnSense HVM (FreeBSD) with StubDom[9]
Die stubdom ist unter Debian derzeit leider nicht vorhanden.
Ich versuche diese aus den XEN Sourcen selbst zu installieren, oder aus den Debian Paket zu erstellen.
Als erste XEN VM richte ich mir deshalb gleich ein Debian System ein, mit dem ich die fehlenden Dateien erstellen möchte.
xen-create-image --hostname bullseye --dist bullseye --vifname=vif_bullseye --bridge=br_lan --dhcp
- Aus den Debian Sourcen
apt-get source xen apt-get build-dep xen # edit debian/rules >>> enable-stubdom # apply a patch - see below Compile Error cd xen-4.14.* debuild -b -us -uc make dist-stubdom
- Aus den originalen XEN Sourcen
# Sourcen für XEN 4.14.1 (Debian Bullseye verwendet xen 4.14.1) wget https://downloads.xenproject.org/release/xen/4.14.1/xen-4.14.1.tar.gz tar xvzf xen-4.14.1.tar.gz cd xen-4.14.1 make dist-stubdom
# --------------------------------- # läuft auf Fehler beim Kompilieren eines (nicht notwendigen) Treibers # fix: # im File tools/firmware/etherboot/ipxe/src/ininiband/flexboot.c in den Zeilen 368 und 409 jeweils # den korrekten Typ vor dem Parameter qp->type einfügen: (nodnic_queue_pair_type) # :368 ... (nodnic_queue_pair_type)qp->type ... # :409 ... (nodnic_queue_pair_type)qp->type ... diff flexboot_nodnic.c.orig flexboot_nodnic.c 368c368 < status = nodnic_port_create_qp(&port->port_priv, qp->type, --- > status = nodnic_port_create_qp(&port->port_priv, (nodnic_queue_pair_type)qp->type, 409c409 < nodnic_port_destroy_qp(&port->port_priv, qp->type, --- > nodnic_port_destroy_qp(&port->port_priv, (nodnic_queue_pair_type)qp->type, # ----------------------------------
XAPI
ToDo: test it once ? Really ?
XCP-ng
ToDo: test it once - done - Use it ? Hhm, not really ... ;-)
Qubes OS
ToDo: test it once ;-)
Verweise
Grafik: XEN Disaggregation (Quelle: XEN.Org)
- ↑ https://wiki.xenproject.org/wiki/Dom0_Kernels_for_Xen
- ↑ https://wiki.xenproject.org/wiki/Driver_Domain
- ↑ https://wiki.xenproject.org/wiki/Dom0_Disaggregation
- ↑ https://xenproject.org/developers/teams/xcp-ng/
- ↑ https://wiki.xenproject.org/wiki/Category:Embedded_and_Automotive
- ↑ https://wiki.xenproject.org/wiki/MirageOS
- ↑ https://wiki.xenproject.org/wiki/Category:Unikraft
- ↑ https://www.qubes-os.org/
- ↑ https://wiki.xenproject.org/wiki/Device_Model_Stub_Domains