SSD Nodes Learn Hosting plans →
Anleitungen Matt ConnorVon Matt Connor

VPS mit verschachtelter Virtualisierung: Proxmox nutzen?

Viele VPS-Anbieter verbergen das vmx-Flag. Pruefen Sie es mit kvm-ok in einer Minute und finden Sie heraus, ob KVM oder Proxmox-Gaeste laufen, inklusive Fehlermeldungen.

Die kurze Antwort

Verschachtelte Virtualisierung bedeutet, dass ein Hypervisor innerhalb einer virtuellen Maschine läuft: Ihr VPS ist bereits ein Gast, und Sie möchten darin eigene Gäste betreiben. Das funktioniert nur, wenn der Hypervisor Ihres Providers die Virtualisierungserweiterungen der CPU gezielt für Ihre Instanz bereitstellt. Prüfen Sie /proc/cpuinfo auf das Flag vmx (Intel) oder svm (AMD). Wenn keines der beiden Flags angezeigt wird, lässt sich das innerhalb des VPS nicht beheben.

Zunächst eine wichtige Abgrenzung: Docker benötigt das alles nicht. Container verwenden den Kernel Ihres VPS gemeinsam und greifen nie auf /dev/kvm zu. Wenn Sie eigentlich mehrere Dienste in Containern auf Ihrem Server betreiben möchten, ist bereits alles Notwendige vorhanden. Verschachtelte Virtualisierung ist relevant, wenn Sie einen zweiten Kernel, eine Proxmox-Testumgebung, einen Windows-Gast, Firecracker-MicroVMs, einen Android-Emulator, eine Kubernetes-Testumgebung mit echten virtuellen Maschinen oder CI-Runner benötigen, die VM-Images booten.

Was tatsächlich verschachtelt wird

Drei Ebenen:

  • L0, der Hypervisor des Anbieters auf der Hardware. Sie haben keinen Zugriff darauf.
  • L1, Ihr VPS. Für L0 ist dies lediglich ein Gast.
  • L2, die VM, die Sie innerhalb Ihres VPS ausführen möchten.

Hardwarevirtualisierung umfasst VT-x (das Flag vmx) und EPT auf Intel sowie AMD-V / SVM (svm) und RVI/NPT auf AMD. Ein Hypervisor verwendet diese Funktionen, um in den Gastmodus zu wechseln und damit die CPU zwei Seitentabellen gleichzeitig durchlaufen kann.

Keine dieser Funktionen wurde für eine erneute Verschachtelung entwickelt. Daher wird die Verschachtelung emuliert: Wenn L1 eine VMX-Anweisung wie VMLAUNCH oder VMRESUME ausführt, führt dies zu einem Trap an L0. L0 verwaltet dann stellvertretend für L1 die Shadow-Strukturen für L2. Auf CPUs mit VMCS-Shadowing können L1s VMREAD und VMWRITE ohne einen Exit verarbeitet werden. Dadurch reduziert sich ein großer Teil dieses Datenverkehrs, aber nicht der restliche Anteil. KVM erledigt dies effizient. Dennoch muss L0 bei jedem Exit zusätzliche Arbeit leisten. Deshalb muss der Anbieter die Funktion ausdrücklich aktivieren.

Wenn L0 KVM verwendet, müssen für eine beschleunigte L2 beide Bedingungen erfüllt sein:

  1. Das KVM-Modul von L0 ist mit nested=1 geladen.
  2. L0 stellt Ihrem VPS ein CPU-Modell bereit, das dieses Flag enthält: <cpu mode='host-passthrough'/> in libvirt, cpu: host in Proxmox und -cpu host in rohem QEMU. Ein generisches emuliertes Modell (qemu64, kvm64) verbirgt vmx, selbst wenn die Verschachtelung global aktiviert ist.

Andere Hypervisoren verwenden eigene Schalter. Hyper-V emuliert beispielsweise die Virtualisierungserweiterungen für einen verschachtelten Hypervisor innerhalb seiner VMs. Das gilt jedoch nur für VMs, in denen die Verschachtelung einzeln aktiviert wurde.

VPS in einer Minute prüfen

# 1. Are you in a VM, and under what?
systemd-detect-virt          # kvm, vmware, xen, microsoft, or "none" on metal

# 2. Does the CPU expose the extensions to you?
grep -o -E 'vmx|svm' /proc/cpuinfo | sort -u
lscpu | grep -i -E 'virtual|hypervisor'

# 3. The definitive check
sudo apt update && sudo apt install -y cpu-checker
kvm-ok

# 4. The device node the whole stack depends on
ls -l /dev/kvm

Eine nutzbare Instanz gibt vmx oder svm aus, kvm-ok lautet KVM acceleration can be used, und /dev/kvm ist mit dem Modus root:kvm 660 vorhanden. Ist das Flag vorhanden, aber der Gerätedateiknoten fehlt, laden Sie das Modul manuell und lesen Sie das Kernel-Log:

sudo modprobe kvm_intel     # or kvm_amd
sudo dmesg | tail -n 20

Eine Datei wird häufig zitiert und oft falsch verstanden:

cat /sys/module/kvm_intel/parameters/nested   # Y or N

In Ihrem VPS ist das die Einstellung Ihres KVM-Moduls. Sie legt fest, ob ein L2-Gast eine dritte Ebene verschachteln könnte. Sie sagt nichts darüber aus, ob L0 die Verschachtelung für Sie aktiviert hat. /proc/cpuinfo und kvm-ok geben darüber Auskunft. Der Parameter nested ist der Regler, den Sie auf einer Maschine setzen, die Ihnen vollständig gehört:

echo 'options kvm_intel nested=1' | sudo tee /etc/modprobe.d/kvm-nested.conf
sudo modprobe -r kvm_intel && sudo modprobe kvm_intel

Das Entfernen des Moduls wird verweigert, solange eine VM läuft. Fahren Sie die Gast-VMs daher zuerst herunter. Wenn es sich bei dem Rechner um einen Proxmox-Host handelt, beschreibt das Aktivieren verschachtelter Virtualisierung in Proxmox VE 9 dieselbe Änderung in modprobe.d sowie die Einstellung cpu: host pro VM, durch die das Flag innerhalb eines Gasts sichtbar wird.

Warum die meisten VPS-Hoster die Funktion deaktiviert lassen

  • Live-Migration. Wenn Ihnen vmx bereitgestellt wird, wird ein CPU-Modell mit diesem Flag offengelegt. Eine Gast-VM, die von diesen CPU-Funktionen abhängt, kann nicht sicher auf eine Maschine migriert werden, deren CPU diese Funktionen nicht unterstützt. Ein Hoster, der Knoten durch die Migration von Kunden-VMs leert, gibt diese Möglichkeit auf, sobald er verschachtelte Virtualisierung aktiviert.
  • Angriffsfläche. Die Pfade für verschachteltes VMX/SVM gehören zu den komplexesten Teilen der Virtualisierungsschicht des Kernels. Die CVE-Historie dieser Pfade ist entsprechend umfangreich.
  • L0 muss nicht KVM sein. Wenn systemd-detect-virt vmware, xen oder microsoft ausgibt, gelten die Regeln des jeweiligen Virtualisierungs-Stacks und nicht die von KVM.

Wird auf Ihrer Instanz kein Flag angezeigt, fragen Sie den Support. Manche Anbieter aktivieren die Funktion pro VM. Alternativ wählen Sie einen Tarif, der verschachtelte Virtualisierung ausdrücklich unterstützt, oder wechseln Sie auf einen dedizierten Server. Im weiteren Verlauf wird vorausgesetzt, dass Sie auf einer Maschine mit diesem Flag über root-Zugriff verfügen.

L2-Gast mit libvirt ausführen

sudo apt install -y qemu-system-x86 libvirt-daemon-system virtinst ovmf
sudo systemctl enable --now libvirtd
sudo usermod -aG libvirt,kvm "$USER"   # log out and back in

virt-install \
  --name guest1 \
  --memory 2048 \
  --vcpus 2 \
  --cpu host-passthrough \
  --disk path=/var/lib/libvirt/images/guest1.qcow2,size=20,format=qcow2,bus=virtio \
  --network network=default,model=virtio \
  --os-variant debian13 \
  --location https://deb.debian.org/debian/dists/trixie/main/installer-amd64/ \
  --graphics none \
  --console pty,target_type=serial \
  --extra-args 'console=ttyS0,115200n8'

Eine grafische Sitzung ist nicht erforderlich. Eine serielle Installation läuft eine Weile, daher sollten Sie sie in einer persistenten Shell starten: Derselbe tmux-Workflow, der Claude-Code-Sitzungen auf einem VPS aktiv hält hält eine virt-install-Konsole auch bei einer unterbrochenen SSH-Verbindung verbunden. Wenn --os-variant debian13 abgelehnt wird, ist Ihre osinfo-db älter als die betreffende Version. Führen Sie osinfo-query os aus und wählen Sie einen vorhandenen Namen. --cpu host-passthrough leitet vmx an L2 weiter. Das ist nur erforderlich, wenn L2 seinerseits virtualisieren muss. Machen Sie den Gast mit virsh autostart guest1 bootfähig.

Der virtio-Bus für Datenträger und NIC ist nicht nur Dekoration: Emulierte IDE- und e1000-Geräte verursachen wesentlich häufiger Traps im Hypervisor als virtio-Warteschlangen. Bei verschachtelter Virtualisierung wird ein Exit, den L0 nicht selbst verarbeiten kann, an L1 weitergereicht. Die Verarbeitung dort kann wiederum weitere Exits auslösen.

Netzwerk: Der Teil, den Tutorials auslassen

Ihr VPS hat eine öffentliche IP-Adresse und befindet sich hinter einer Infrastruktur, die unbekannte MAC-Adressen filtert. Daraus ergeben sich zwei Konsequenzen.

L2-Gäste direkt in das öffentliche Netzwerk zu bridgen funktioniert normalerweise nicht. Setzen Sie br0 auf die öffentliche Netzwerkkarte, geben Sie dem Gast eine eigene MAC-Adresse, und Sie werden sehen, dass ARP-Anfragen hinausgehen, aber keine Antwort zurückkommt. Der Switch des Providers verwirft Frames von einer MAC-Adresse, die er Ihnen nicht zugewiesen hat. Wenn dies Ihr Fehlerbild ist, suchen Sie den Fehler nicht weiter in der Bridge. Das ist die Ursache.

Verwenden Sie stattdessen das NAT-Netzwerk. libvirt stellt default bereit: virbr0, 192.168.122.0/24, Leases von dnsmasq und sofort funktionierenden ausgehenden Datenverkehr. Für eingehende Verbindungen beenden Sie TLS auf L1 und leiten die Anfragen per Proxy weiter. Die Zertifikatspfade weiter unten stammen aus Ausstellen eines Let's-Encrypt-Zertifikats mit Certbot unter Nginx:

server {
    listen 443 ssl;
    server_name lab.example.com;

    ssl_certificate     /etc/letsencrypt/live/lab.example.com/fullchain.pem;
    ssl_certificate_key /etc/letsencrypt/live/lab.example.com/privkey.pem;

    location / {
        proxy_pass http://192.168.122.50:8080;
        proxy_set_header Host $host;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header X-Forwarded-Proto $scheme;
    }
}

Weisen Sie dem Gast zuerst ein statisches Lease zu (virsh net-edit default), damit die Adresse in proxy_pass unverändert bleibt.

Management-Schnittstellen bleiben vom Internet getrennt: VNC auf 5900 und die Proxmox-Weboberfläche auf 8006 gehören an loopback und werden über einen SSH-Tunnel (ssh -N -L 8006:127.0.0.1:8006 you@your-vps) oder über ein selbst gehostetes WireGuard-VPN in den VPS erreicht. Dadurch liegt der gesamte 192.168.122.0/24-Gastbereich nur einen privaten Hop entfernt. Halten Sie die Firewall restriktiv: sudo ufw allow 22,80,443/tcp, sonst nichts. Wenn Gäste unmittelbar nach der Aktivierung von ufw keine ausgehende Verbindung mehr haben, ist DEFAULT_FORWARD_POLICY="DROP" in /etc/default/ufw meist die Ursache. Setzen Sie den Wert auf ACCEPT und laden Sie ufw neu.

Proxmox auf einem VPS

Proxmox VE 9 basiert auf Debian 13 und lässt sich daher auf einem Debian-VPS installieren, indem Sie das pve-no-subscription-Repository und das Paket proxmox-ve hinzufügen. Übernehmen Sie die Repository- und Keyring-Zeilen aus der aktuellen Proxmox-Dokumentation. Eine aus einem alten Blogbeitrag kopierte URL lässt die Installation fehlschlagen. Ob Proxmox überhaupt auf gemieteter Hardware eingesetzt werden sollte, sollten Sie klären, bevor Sie einen Abend mit der folgenden Netzwerkkonfiguration verbringen. Der Kosten- und Leistungsvergleich zwischen einem Proxmox-System zu Hause und einem gemieteten VPS beantwortet diese Frage bereits anhand der Berechnung von Stromkosten und Hardwareanforderungen.

Die Pakete sind nicht der schwierige Teil. Proxmox erwartet vmbr0 als Bridge an einer physischen Netzwerkkarte. Damit laufen Sie direkt in die oben beschriebene Sackgasse der MAC-Filterung. Auf einem VPS funktioniert ein NAT- oder geroutetes vmbr0 ohne angeschlossenen physischen Port. Die Gastsysteme verwenden einen privaten Adressbereich. Für öffentlich erreichbare Dienste konfigurieren Sie DNAT-Regeln oder einen Reverse Proxy auf dem Host. Wenn die öffentlich erreichbaren Dienste Container statt VMs sind, übernimmt Traefik vor mehreren Anwendungen aus einer Docker-Compose-Datei dieselbe Routing-Aufgabe mit automatischen Zertifikaten. Erstellen Sie zuerst einen Snapshot von /etc/network/interfaces. Eine fehlerhafte Bridge-Konfiguration kann Sie von einem System aussperren, dessen Konsole möglicherweise nicht verfügbar ist.

Leistung, sachlich beschrieben

Verschachtelung ist langsamer als eine einstufige Ausführung. Der Mechanismus ist dabei spezifisch und nicht allgemein: Die Kosten entstehen bei Exits und der Adressübersetzung, nicht bei normalen Instruktionen. Wenn EPT/NPT verfügbar ist, führt L0 die Seitentabellen von L1 für L2 und die eigenen Seitentabellen in einer gemeinsamen Shadow-Tabelle zusammen. Ein TLB-Treffer läuft dadurch mit der Geschwindigkeit der Hardware. Ein TLB-Miss ist teurer: Die Hardware durchläuft gleichzeitig die Seitentabelle des Gasts und die Shadow-Tabelle. Jede Änderung, die L1 an seinen eigenen Seitentabellen vornimmt, erzwingt einen Exit, damit L0 die Shadow-Tabelle synchronisieren kann. Teuer ist jede Operation, die den Gastmodus verlässt: I/O, Timer-Interrupts, MMIO und Interprozessor-Interrupts. Ein L2-Exit wird von L0 verarbeitet und möglicherweise über L1 zurückgereicht. CPU-gebundene Arbeit mit einem kleinen Working Set liegt nahe an der nativen Leistung. Große Working Sets im Arbeitsspeicher verursachen zusätzliche TLB-Misses. Bei Workloads, die hauptsächlich aus Systemaufrufen, Paketen und Festplatten-I/O bestehen, machen sich die Schichten deutlich bemerkbar.

Daher gilt: Verwenden Sie überall virtio-Geräte. Ihre qcow2-Datei liegt außerdem auf einem Datenträger, den der Provider bereits virtualisiert hat. Damit sind zwei Thin-Provisioning-Schichten übereinandergelegt. Dabei verhindert cache=none auf dem Gastdatenträger, dass dieselben Blöcke gleichzeitig in zwei Page-Caches liegen. Hier gibt es keine Benchmark-Werte. Messen Sie Ihren eigenen Workload auf Ihrer eigenen Instanz.

Fehlerbilder und die angezeigten Meldungen

INFO: /dev/kvm does not exist / KVM acceleration can NOT be used aus kvm-ok. Entweder ist das Modul nicht geladen, oder das Flag wird nicht bereitgestellt. Prüfen Sie zuerst /proc/cpuinfo.

kvm: disabled by bios in dmesg. Auf Bare Metal aktivieren Sie den VT-x/SVM-Schalter in der Firmware. In einem VPS bedeutet dies, dass L0 die Erweiterungen nicht an Sie weitergibt. Keine Eingabe im Gast kann das ändern.

modprobe: ERROR: could not insert 'kvm_intel': Operation not supported. Die vom Kernel erkannte CPU unterstützt vmx nicht. Auch das ist eine Entscheidung von L0.

Could not access KVM kernel module: Permission denied. Die Ursache sind Berechtigungen, nicht die Hardware. ls -l /dev/kvm sollte die Gruppe kvm und den Modus 660 anzeigen. Fügen Sie sich dieser Gruppe hinzu und starten Sie eine neue Login-Shell, da die Gruppenmitgliedschaft in einer bereits laufenden Sitzung nicht übernommen wird.

kvm: Device or resource busy, wenn QEMU startet. Ein anderes Hypervisor-Modul belegt die CPU. Führen Sie lsmod aus und suchen Sie neben kvm_intel nach vboxdrv oder VMware-Modulen. Entladen Sie das nicht benötigte Modul.

/var/run/libvirt/libvirt-sock: No such file or directory aus virsh. Der Daemon ist nicht aktiv: sudo systemctl enable --now libvirtd.

Proxmox: KVM virtualisation configured, but not available. Für einen Gast ist KVM-Beschleunigung aktiviert, obwohl der Host sie nicht bereitstellen kann. Konfigurieren Sie Nested Virtualization korrekt oder deaktivieren Sie die Option und verwenden Sie Emulation.

Android-Emulator: x86_64 emulation currently requires hardware acceleration! Erneut /dev/kvm, normalerweise liegt die Ursache bei der Gruppe.

Keine Fehlermeldung und alles ist extrem langsam. QEMU fällt ohne Accelerator-Flag auf TCG, seinen Software-Emulator, zurück. Das funktioniert korrekt, ist aber langsam. Ein Bootvorgang, der in Sekunden abgeschlossen ist, dauert dann Minuten. Übergeben Sie -accel kvm explizit. Dadurch beendet sich QEMU mit einer Fehlermeldung, statt unbemerkt zu emulieren.

Ein Gast verschwindet während des Betriebs. Suchen Sie in dmesg nach Out of memory: Killed process ... qemu-system-x86_64. Ein L2-Gast ist ein Prozess auf L1, und der OOM-Killer behandelt ihn wie jeden anderen Prozess. Der Arbeitsspeicher für L2 stammt aus der festen Speicherzuweisung von L1. Er kann sich keinen Speicher vom Host ausleihen.

Betrieb: Backups, Upgrades und Grenzen

Backups. Das Kopieren der qcow2-Datei eines laufenden Gasts kann zu einem inkonsistenten Image führen, weil der Gast währenddessen weiter schreibt. Führen Sie entweder virsh shutdown guest1 aus, warten Sie, bis virsh domstate guest1 shut off meldet (der Shutdown-Befehl kann zurückkehren, während der Gast noch beendet wird), und kopieren Sie die Datei anschließend. Oder erstellen Sie einen externen Snapshot (virsh snapshot-create-as guest1 snap1 --disk-only --atomic). Dann werden Schreibvorgänge während des Kopierens in ein Overlay umgeleitet, während die nun statische Basis kopiert wird. Führen Sie den Snapshot anschließend mit virsh blockcommit guest1 vda --active --pivot zurück. Übertragen Sie die Kopien vom VPS auf ein anderes System. Ein Snapshot auf derselben Festplatte schützt vor keinem Ausfall.

Upgrades. apt full-upgrade installiert neue kvm_intel/kvm_amd-Module. Der laufende Kernel verwendet jedoch weiterhin die alten Module, bis Sie das System neu starten. Lassen Sie den vorherigen Kernel installiert und führen Sie kvm-ok nach jeder Kerneländerung erneut aus. Wenn ein Host anschließend ohne vmx startet, ist er dann nur noch einen Boot-Eintrag von einem wieder funktionierenden System entfernt.

Wo die Skalierung endet. Eine öffentliche IP-Adresse bedeutet, dass jeder L2-Dienst über einen Proxy oder eine DNAT-Regel auf L1 das Internet erreicht. Live-Migration ist nicht möglich. Bei CPU-Konkurrenz wird zuerst der verschachtelte Exit-Pfad beeinträchtigt. Ein Hypervisor mit mehreren Gästen ist außerdem ein System, dessen RAM bereits vollständig verplant ist. Verschachtelte VMs können eine feste Speicherzuweisung nicht durch Overcommit ausgleichen. Wenn ein Laborsystem darüber hinauswächst, ist die Lösung kein noch höherer Verschachtelungsstapel. Sie besteht in einer dedizierten Maschine, auf der Sie L0 sind und für die diese Einschränkungen nicht gelten.

FAQ

Benötige ich verschachtelte Virtualisierung, um Docker auf einem VPS auszuführen?

Nein. Container verwenden den Kernel Ihres VPS gemeinsam und öffnen nie /dev/kvm. Daher führt eine einfache Instanz ohne das Flag vmx oder svm Docker und Docker Compose problemlos aus. Verschachtelte Virtualisierung ist nur erforderlich, wenn Sie einen zweiten Kernel ausführen möchten: eine Proxmox-Testumgebung, ein Windows-Gastsystem, Firecracker-MicroVMs, einen Android-Emulator oder CI-Runner, die VM-Images booten.

Wie prüfe ich, ob mein VPS verschachtelte Virtualisierung unterstützt?

Führen Sie grep -o -E 'vmx|svm' /proc/cpuinfo | sort -u und anschließend kvm-ok aus dem Paket cpu-checker aus. Eine geeignete Instanz gibt vmx (Intel) oder svm (AMD) aus. kvm-ok meldet KVM acceleration can be used. Außerdem ist /dev/kvm mit der Gruppe kvm und dem Modus 660 vorhanden. Ignorieren Sie /sys/module/kvm_intel/parameters/nested für diese Prüfung. Diese Datei beschreibt Ihr eigenes KVM-Modul, nicht die Funktionen, die der Hypervisor des Anbieters für Sie bereitstellt.

Warum deaktivieren die meisten VPS-Anbieter verschachtelte Virtualisierung?

Wenn vmx verfügbar gemacht wird, erhält der Gast ein CPU-Modell mit diesem Flag. Ein Gast, der von diesen CPU-Funktionen abhängt, kann nicht live auf eine Maschine migriert werden, deren CPU sie nicht unterstützt. Ein Anbieter, der Nodes durch das Verschieben von Kundensystemen leert, muss deshalb auf diese Möglichkeit verzichten. Die verschachtelten VMX-/SVM-Codepfade weisen außerdem eine lange CVE-Historie auf. Einige Hosts aktivieren die Funktion weiterhin auf Anfrage pro VM. Andere führen verschachtelte Virtualisierung als Leistungsmerkmal eines Tarifs auf.

Meine verschachtelte VM hat auf der öffentlichen Bridge kein Netzwerk. Was ist falsch?

Der Switch des Anbieters verwirft Frames von einer MAC-Adresse, die er Ihnen nicht zugewiesen hat. Ein L2-Gast, der über die öffentliche NIC gebridged ist, sendet daher ARP-Anfragen, erhält aber keine Antwort. Beenden Sie die Fehlersuche an br0. Verwenden Sie stattdessen das libvirt-NAT-Netzwerk default (virbr0, 192.168.122.0/24), weisen Sie dem Gast eine statische Lease zu und veröffentlichen Sie öffentliche Dienste über einen Reverse Proxy oder eine DNAT-Regel direkt auf dem VPS.

Wie viel langsamer ist eine verschachtelte VM?

Die zusätzlichen Kosten entstehen bei VM-Exits und bei der Adressübersetzung. Wenn EPT/NPT aktiv ist, werden Instruktionen und TLB-Treffer innerhalb von L2 mit Hardwaregeschwindigkeit ausgeführt. Bei einem TLB-Miss müssen jedoch zusätzliche Seitentabellen durchlaufen werden. I/O, Timer-Interrupts, MMIO und IPIs werden von L0 verarbeitet und möglicherweise über L1 zurückgeleitet. CPU-intensive Aufgaben mit einer kleinen Arbeitsspeichermenge sind nahezu so schnell wie nativ. Bei großen Arbeitsspeichermengen sowie syscall-, paket- und datenträgerintensiven Workloads macht sich jede Ebene bemerkbar. Verwenden Sie überall virtio-Geräte und cache=none auf den Gastdatenträgern. Messen Sie anschließend Ihren eigenen Workload.