kubevirt

Fehlerbehebung bei KubeVirt: CNI-Konflikte, CDI-Fehler und gängige Lösungen

Abubakar Siddiq Ango
Abubakar Siddiq Ango Senior Developer Advocate
17. März 2026 12 Min. Lesezeit Mittelstufe
Fehlerbehebung Virtualisierung Netzwerk

Voraussetzungen

KubeVirt fügt eine Virtualisierungsschicht auf Kubernetes hinzu, was bedeutet, dass die Fehlersuche zwei Schichten umfasst: die Kubernetes-Schicht (Pods, Services, PVs) und die KVM/libvirt-Schicht (QEMU-Prozesse, Virtio-Treiber, Festplatten-Images). Wenn ein Fehler auftritt, muss man wissen, welche Schicht man zuerst untersuchen sollte und wie man das Problem von einer Schicht zur anderen zurückverfolgen kann.

Dieser Leitfaden behandelt die fünf am häufigsten gemeldeten Probleme bei KubeVirt-Bereitstellungen, die aus GitHub-Issues, Community-Foren und Erfahrungen aus der Produktion zusammengetragen wurden. Jedes Problem ist nach dem gleichen Schema aufgebaut: auftretende Symptome, Diagnose, Ursache und Behebung.

Bevor Sie beginnen, stellen Sie sicher, dass Sie folgende Werkzeuge bereitliegen haben: kubectl, virtctlsowie SSH-Zugriff auf Ihre Cluster-Knoten für die Fehlerbehebung auf Knotenebene. Sie werden alle drei an verschiedenen Stellen in dieser Anleitung benötigen.

Problem 1: CNI-Konflikte – VMs können keine Verbindung zum Netzwerk herstellen

Dies ist das häufigste Problem, auf das Teams stoßen, wenn sie KubeVirt zum ersten Mal einsetzen. Es liegt an einer grundlegenden Diskrepanz zwischen dem, was das Kubernetes-Netzwerk bietet, und dem, was virtuelle Maschinen erwarten.

Symptome

  • Die VM startet erfolgreich, kann jedoch keine externen Hosts anpingen.
  • Die VM kann die IP-Adresse des Knotens anpingen, jedoch keine anderen Pods oder das Internet.
  • ARP-Anfragen von der VM werden nicht aufgelöst.

Diagnose

Überprüfen Sie zunächst den VMI-Status und die Netzwerkkonfiguration:

# Check the VMI status and network info
kubectl get vmi <vm-name> -o yaml | grep -A 20 interfaces

Überprüfen Sie als Nächstes den Netzwerk-Namespace innerhalb des virt-launcher-Pods:

# Check the virt-launcher pod's network namespace
kubectl exec -it virt-launcher-<vm-name>-xxxxx -- ip addr

Wenn die Schnittstellen korrekt aussehen, überprüfen Sie, ob der Datenverkehr tatsächlich die virtuelle Bridge der VM erreicht:

# Check if traffic reaches the VM's virtual bridge
kubectl exec -it virt-launcher-<vm-name>-xxxxx -- tcpdump -i k6t-eth0 -n

Wenn Sie feststellen, dass ARP-Anfragen die VM verlassen, aber keine Antworten zurückkommen, liegt ein Layer-2-/Layer-3-Konflikt vor.

Grundursache

Standardmäßige Kubernetes-CNIs (Calico, Cilium, Flannel) arbeiten auf Layer 3 – sie leiten IP-Pakete zwischen Pods weiter. Viele VMs erfordern jedoch Layer-2-Konnektivität: ARP-Auflösung, Broadcast-Verkehr und direkte Ethernet-Framing. Die virtuelle Ethernet-Brücke (k6t-eth0) innerhalb des virt-launcher-Pods verbindet die Netzwerkkarte der VM mit dem Pod-Netzwerk, doch Layer-2-Frames werden nicht korrekt über das Overlay der CNI weitergeleitet. Die CNI kann nur IP-Pakete weiterleiten, nicht jedoch Raw-Ethernet-Frames, sodass ARP-Anfragen der VM ins Leere laufen.

Beheben

Je nach Ihren Anforderungen haben Sie zwei Möglichkeiten.

Für die grundlegende Konnektivität (die VM benötigt lediglich einen Internetzugang und Zugriff von Pod zu Pod): Verwenden Sie die Standardeinstellung Maskenball Bindungsmodus. Dabei wird der Datenverkehr der VM über die Pod-IP weitergeleitet, was mit jeder CNI funktioniert, da der Datenverkehr der VM den Pod als reguläre IP-Pakete verlässt:

spec:
  domain:
    devices:
      interfaces:
        - name: default
          masquerade: {}
  networks:
    - name: default
      pod: {}

Der Masquerade-Modus übernimmt die Übersetzung zwischen dem internen Netzwerk der VM und dem Pod-Netzwerk auf transparente Weise. Die VM erhält eine interne IP-Adresse (in der Regel 10.0.2.15), und der gesamte ausgehende Datenverkehr wird über die IP-Adresse des Pods weitergeleitet.

Für Layer-2-Zugriff (VM benötigt DHCP, Broadcast oder VLANs): Installieren Sie Multus CNI und erstellen Sie eine NetworkAttachmentDefinition mit einem Bridge-Plugin:

apiVersion: k8s.cni.cncf.io/v1
kind: NetworkAttachmentDefinition
metadata:
  name: br-lan
spec:
  config: |
    {
      "cniVersion": "0.3.1",
      "type": "bridge",
      "bridge": "br-lan",
      "ipam": {}
    }

Verbinden Sie dann Ihre VM mit diesem Netzwerk:

spec:
  domain:
    devices:
      interfaces:
        - name: lan
          bridge: {}
  networks:
    - name: lan
      multus:
        networkName: br-lan

Warnung: Reibungsverluste auf Layer-2-/Layer-3-Ebene sind das größte Netzwerkproblem bei KubeVirt. Wenn Ihre VMs Layer 2 benötigen (was bei den meisten älteren VMs der Fall ist), müssen Sie Multus verwenden. Innerhalb des Standard-Pod-Netzwerks gibt es keine Abhilfe. Planen Sie dies frühzeitig in Ihrer Bereitstellung ein, anstatt es später nachzurüsten.

Problem 2: Fehler beim CDI-Importer – Datenvolumes hängen

Der Containerized Data Importer (CDI) ist für den Import von Festplatten-Images in PVCs zuständig. Wenn dieser Vorgang fehlschlägt, können Ihre VMs nicht gestartet werden, da keine Festplatte zum Booten vorhanden ist.

Symptome

  • DataVolume hängt fest Import geplant oder Import läuft über einen längeren Zeitraum.
  • Der CDI-Importer-Pod zeigt Fehler an oder startet wiederholt neu.
  • kubectl get dv <name> zeigt an, dass der Fortschritt bei 0 % oder einem niedrigen Prozentsatz stehen geblieben ist.

Diagnose

# Check DataVolume status
kubectl describe dv <datavolume-name>

# Find and check the importer pod
kubectl get pods -l cdi.kubevirt.io/storage.import.importPvcName=<pvc-name>
kubectl logs <cdi-importer-pod-name>

Die Pod-Protokolle des Importers enthalten die eigentlichen Antworten. Der Status von DataVolume zeigt an, dass der Vorgang hängengeblieben ist; die Pod-Protokolle verraten Ihnen, warum.

Häufige Ursachen und Lösungen

Ursache A: Zu kleine PVC-Größe. Die Ziel-PVC muss mindestens so groß sein wie die virtuelle Größe des Disk-Images. QCOW2-Images haben eine virtuelle Größe, die deutlich größer sein kann als ihre Dateigröße auf der Festplatte – eine 2-GB-QCOW2-Datei kann sich auf eine virtuelle Festplatte von 50 GB ausdehnen.

# Check virtual size of a QCOW2 image
qemu-img info <image-file>

Suchen Sie nach dem Feld „Virtuelle Größe“. Legen Sie die PVC-Größe Ihres DataVolume auf mindestens diesen Wert fest, zuzüglich eines gewissen Spielraums für den Overhead des Dateisystems (etwa 5–10 % zusätzlich).

Ursache B: Die StorageClass unterstützt keine dynamische Bereitstellung. CDI muss während des Importvorgangs temporäre PVCs für die Formatkonvertierung und Validierung erstellen. Wenn die Standard-StorageClass keine dynamische Bereitstellung unterstützt, verbleibt das temporäre PVC im Status „Pending“ und der Import wird nicht fortgesetzt.

Lösung: Legen Sie eine Standard-StorageClass fest, die dynamische Bereitstellung unterstützt, oder geben Sie Folgendes an: spec.storage.storageClassName ausdrücklich in Ihrem DataVolume-Manifest. Überprüfen Sie dies mit kubectl get sc — die Standardklasse sollte Folgendes enthalten (Standard) neben seinem Namen und einen Provisioner, der dynamische Bereitstellung unterstützt.

Ursache C: Nicht unterstütztes Quellformat. CDI unterstützt standardmäßig die Formate QCOW2, RAW, VMDK (mit Konvertierung) und ISO. Andere Formate wie VHD oder VHDX müssen vor dem Import manuell konvertiert werden.

qemu-img convert -f vhd -O qcow2 source.vhd target.qcow2

Ursache D: Netzwerkprobleme beim Abrufen des Images. Wenn die DataVolume-Quelle eine HTTP-URL ist, benötigt der Importer-Pod ausgehenden Netzwerkzugriff. Überprüfen Sie die Proxy-Konfiguration, mögliche Fehler bei der DNS-Auflösung oder Firewall-Regeln, die den Datenausgang aus dem Cluster blockieren. Der Importer-Pod läuft im selben Namespace wie Ihr DataVolume, sodass ihn auch NetworkPolicies auf Namespace-Ebene blockieren können.

Tipp: Bei großen Bildern (50 GB+) kann der Import selbst bei schnellen Netzwerken mehr als 30 Minuten dauern. Überprüfen Sie die Protokolle des CDI-Importer-Pods auf Fortschrittsmeldungen, bevor Sie davon ausgehen, dass der Vorgang hängengeblieben ist. Die Protokolle geben den Fertigstellungsgrad in Prozent und den Durchsatz an – wenn sich diese Zahlen ändern, läuft der Import.

Problem 3: VM lässt sich nicht starten – virt-launcher: „CrashLoopBackOff“

Wenn eine VM nicht gestartet werden kann, äußert sich dieses Problem fast immer in Form eines fehlgeschlagenen virt-launcher-Pods. Dieser Pod ist der Wrapper-Prozess, der die QEMU-Instanz für Ihre VM verwaltet; daher zeigen sich hier alle Probleme im Zusammenhang mit der VM-Konfiguration, den Knotenkapazitäten oder der Ressourcenverfügbarkeit.

Symptome

  • Die VirtualMachineInstance ist in Terminplanung oder Fehlgeschlagen.
  • „virt-launcher“-Pod bei „CrashLoopBackOff“.
  • Ereignisse zeigen Fehler im Zusammenhang mit dem Gerätzugriff oder Ressourcenbeschränkungen an.

Diagnose

# Check VMI events
kubectl describe vmi <vm-name>

# Check virt-launcher pod logs
kubectl logs virt-launcher-<vm-name>-xxxxx

# On the node, check libvirt logs (requires SSH)
journalctl -u kubelet | grep <vm-name>

Die VMI-Ereignisse enthalten in der Regel den ersten Hinweis. Die Protokolle des virt-launchers enthalten den detaillierten Fehler von QEMU oder libvirt.

Häufige Ursachen und Lösungen

Ursache A: KVM-Gerät nicht verfügbar. Es werden Fehler wie die folgenden angezeigt: Gerät /dev/kvm nicht gefunden oder Die Erstellung der Domäne ist fehlgeschlagen. Das bedeutet, dass auf dem Knoten keine Hardware-Virtualisierung aktiviert ist oder dass der /dev/kvm Das Gerät ist für den Pod nicht zugänglich.

Lösung: Verbinde dich per SSH mit dem Knoten und überprüfe, ob /dev/kvm vorhanden ist. Ist dies nicht der Fall, aktivieren Sie VT-x (Intel) oder AMD-V (AMD) in den BIOS-/UEFI-Einstellungen. Wenn Sie auf Cloud-Instanzen arbeiten, benötigen Sie Instanzen, die verschachtelte Virtualisierung unterstützen (dies ist nicht bei allen Instanztypen der Fall). Als letzte Möglichkeit für Entwicklungsumgebungen können Sie die Software-Emulation im KubeVirt CR aktivieren, indem Sie useEmulation: true, aber verwende dies niemals in der Produktion – es ist um ein Vielfaches langsamer.

Grund B: Unzureichende Ressourcen. Fehler wie zu wenig Speicherplatz oder CPU-Pinning fehlgeschlagen bedeutet, dass die VM mehr CPU-Leistung oder Arbeitsspeicher anfordert, als auf einem der planbaren Knoten verfügbar ist.

Behebung: Zuweisbare Ressourcen des Knotens prüfen:

kubectl describe node <node-name> | grep -A 10 "Allocatable"

Vergleichen Sie dies mit den Ressourcenanforderungen Ihrer VM. Denken Sie daran, dass auch Kubernetes-Systemkomponenten, DaemonSets und andere Pods Ressourcen verbrauchen. Reduzieren Sie entweder die Ressourcenanforderungen der VM oder erweitern Sie die Kapazität des Clusters.

Ursache C: Fehler beim Abrufen des Bildes. Wenn Sie ein containerDisk Quelle: Der virt-launcher-Pod muss das Container-Image abrufen, das die Festplatte enthält. Fehler beim Abrufen des Images – falsche Registry-URL, fehlende Authentifizierung oder ein nicht vorhandenes Image-Tag – führen zu einem „CrashLoopBackOff“ mit bildbezogenen Fehlermeldungen in den Pod-Ereignissen.

Lösung: Überprüfen Sie, ob die Bild-URL korrekt ist, und stellen Sie sicher, dass imagePullSecrets sind im Namespace der VM konfiguriert, und testen Sie das manuelle Abrufen des Images:

crictl pull <image-url>

Thema 4: Fehler bei der Live-Migration

Die Live-Migration ist einer der wichtigsten Vorteile des Betriebs von VMs auf KubeVirt – sie ermöglicht es Ihnen, laufende VMs zu Wartungszwecken, zur Lastverteilung oder für Upgrades zwischen Knoten zu verschieben. Allerdings gibt es strenge Voraussetzungen, die nicht immer auf den ersten Blick erkennbar sind.

Symptome

  • Die Migration ist hängen geblieben Terminplanung oder TargetReady Phase.
  • Die Migration schlägt mit Zeitüberschreitungs- oder Verdrängungsfehlern fehl.
  • kubectl get vmim zeigt fehlgeschlagene Migrationen an.

Diagnose

# Check migration status
kubectl get vmim -A
kubectl describe vmim <migration-name>

# Check target node's virt-handler logs
kubectl logs -n kubevirt virt-handler-xxxxx --since=5m

Anhand der Ereignisse des Migrationsobjekts können Sie feststellen, in welcher Phase ein Fehler aufgetreten ist. Die Protokolle des virt-handler auf dem Zielknoten zeigen, was während des eigentlichen Migrationsversuchs schiefgelaufen ist.

Voraussetzungen für die Live-Migration

Bevor Sie mit der Fehlerbehebung für den jeweiligen Fehler beginnen, stellen Sie sicher, dass diese drei Voraussetzungen erfüllt sind:

  1. Gemeinsamer storage. Die PVCs der VM müssen den Zugriffsmodus „ReadWriteMany“ (RWX) verwenden. Sowohl der Quell- als auch der Zielknoten benötigen gleichzeitigen Zugriff auf denselben storage. Lokaler storage, hostPath-Volumes und PVCs mit dem Modus „ReadWriteOnce“ funktionieren nicht.

  2. Kompatible CPU-Modelle. Der Quell- und der Zielknoten müssen über kompatible CPU-Funktionen verfügen. Wenn der Quellknoten über AVX-512 verfügt, der Zielknoten jedoch nicht, schlägt die Migration fehl. Verwenden Sie spec.domain.cpu.model: Host-Modell um Flexibilität über heterogene Cluster hinweg zu gewährleisten, oder an ein bestimmtes Basismodell binden.

  3. Ausreichende Netzwerkbandbreite. Große VMs mit aktiven Workloads erzeugen „Dirty Pages“ schneller, als diese bei der Migration kopiert werden können. Wenn die Rate der „Dirty Pages“ die Migrationsbandbreite übersteigt, konvergiert die Migration nie und läuft schließlich ab.

Häufige Lösungen

Stellen Sie storage ein verteiltes Backend um, das RWX-Zugriff unterstützt – Rook-Ceph, Longhorn oder das gemeinsam genutzte Dateisystem Ihres Cloud-Anbieters. Dies ist für die Live-Migration zwingend erforderlich.

Falls die Netzwerkbandbreite begrenzt ist, legen Sie eine explizite Bandbreitenbegrenzung für die Migration fest, um zu verhindern, dass der Migrationsdatenverkehr das Netzwerk überlastet:

apiVersion: kubevirt.io/v1
Art: KubeVirt
Metadaten:
  name: kubevirt
  Namespace: kubevirt
spec:
  Konfiguration:
    Migrationen:
      BandbreiteProMigration: 64Mi

Sie können auch das Zeitlimit für die Migration verlängern und die Anzahl der zulässigen Konvergenzschritte festlegen, um größeren VMs mehr Zeit für den Abschluss zu geben:

Spezifikation:
  Konfiguration:
    Migrationen:
      completionTimeoutPerGiB: 800
      progressTimeout: 150

Warnung: Ohne gemeinsam genutzten storage RWX) ist eine Live-Migration nicht möglich. VMs auf lokalem storage an ihren Knoten gebunden. Planen Sie Ihr storage entsprechend, bevor Sie Knoten für Wartungsarbeiten evakuieren müssen.

Thema 5: Schlechte VM-Leistung

Ihre VM startet und läuft, wirkt jedoch spürbar langsamer als eine Bare-Metal- oder herkömmliche Hypervisor-Konfiguration. Dies ist keine inhärente Einschränkung von KubeVirt – es handelt sich fast immer um ein Konfigurationsproblem.

Symptome

  • Die VM läuft trotz ausreichender Ressourcenzuweisung träge.
  • CPU-intensive Arbeitslasten laufen deutlich langsamer als erwartet.
  • Die Disk-I/O-Benchmarks zeigen Werte, die weit unter denen der Benchmarks auf Host-Ebene liegen.

Diagnose

Überprüfen Sie zunächst, ob die Software-Emulation aktiv ist:

# Prüfen, ob Software-Emulation verwendet wird
kubectl get kubevirt kubevirt -n kubevirt -o jsonpath='{.spec.configuration.developerConfiguration.useEmulation}'

Wenn das zurückgibt richtig, dann haben Sie das Problem gefunden. Überprüfen Sie als Nächstes das CPU-Modell, das die VM tatsächlich verwendet:

virtctl console <vm-name>
# Inside the VM, run:
lscpu | grep "Model name"

Wenn der Modellname statt Ihrer tatsächlichen Host-CPU eine allgemeine Bezeichnung wie „QEMU Virtual CPU“ anzeigt, wird kein CPU-Passthrough unterstützt.

Häufige Ursachen und Lösungen

Ursache A: Software-Emulation. Wenn useEmulation: trueDie VM läuft vollständig auf QEMU ohne KVM-Hardwarebeschleunigung. Dies ist 10- bis 100-mal langsamer als hardwarebeschleunigte Virtualisierung. Diese Option ist nur für Entwicklungs- und Testzwecke auf Rechnern ohne VT-x/AMD-V vorgesehen.

Lösung: Aktivieren Sie die Hardware-Virtualisierung auf Ihren Knoten und legen Sie useEmulation: false (oder die Einstellung ganz entfernen, da falsch (ist die Standardeinstellung).

Ursache B: Kein CPU-Passthrough. Standardmäßig stellt KubeVirt den VMs ein generisches CPU-Modell zur Verfügung. Dies gewährleistet eine breite Kompatibilität, verbirgt jedoch leistungssteigernde CPU-Funktionen vor dem Gast. Bei CPU-intensiven Workloads sollten die CPU-Funktionen des Hosts weitergeleitet werden:

Spezifikation:
  Domäne:
    CPU:
      Modell: Host-Passthrough
      dedizierte CPU-Platzierung: true

Die dedicatedCpuPlacement Diese Option bindet VM-vCPUs an physische Kerne und verhindert so Schwankungen bei der Auslastung. Beachten Sie, dass hierfür der CPU-Manager auf dem Knoten aktiviert sein muss (kubelet --cpu-manager-policy=static).

Ursache C: Keine Hugepages. Bei speicherintensiven VMs führt die standardmäßige Seitengröße von 4 KB zu einer hohen Belastung des Translation Lookaside Buffers (TLB) und häufigen Durchläufen der Seitentabelle. Hugepages (2 MB oder 1 GB) reduzieren diesen Overhead erheblich:

Spezifikation:
  Domäne:
    Speicher:
      Hugepages:
        Seitengröße: 2Mi
    Ressourcen:
      Anfragen:
        Speicher: 4 Gi

Auf dem Knoten müssen Hugepages vorab zugewiesen worden sein. Auf jedem Knoten:

echo 2048 > /sys/kernel/mm/hugepages/hugepages-2048kB/nr_hugepages

Für eine dauerhafte Konfiguration fügen Sie Folgendes hinzu hugepagesz=2M hugepages=2048 zu den Kernel-Boot-Parametern.

Ursache D: Virtio-Treiber fehlen. Dies betrifft in erster Linie Windows-VMs. Ohne Virtio-Treiber greift KubeVirt auf die IDE-Emulation für Festplatten und die e1000-Emulation für das Netzwerk zurück – beide sind deutlich langsamer als ihre Virtio-Entsprechungen. Der Festplattendurchsatz kann ohne Virtio um das 5- bis 10-fache sinken.

Lösung: Installieren Sie die virtio-win-Treiber innerhalb des VM-Gasts. Sie können die virtio-win-ISO-Datei bei der Erstellung der VM als sekundäres CD-ROM-Laufwerk zuweisen und die Treiber über den Windows-Geräte-Manager installieren.

Referenz zu Diagnosebefehlen

Halten Sie diese Tabelle bei der Fehlerbehebung griffbereit. Dies sind die Befehle, auf die Sie am häufigsten zurückgreifen werden:

BefehlZweck
kubectl get vmiListe der laufenden VM-Instanzen
kubectl describe vmi <name>Detaillierter VMI-Status und Ereignisse
virtctl console <name>Auf die serielle Konsole der VM zugreifen
virtctl ssh <name>Per SSH in die VM einloggen (erfordert einen Gast-Agenten)
kubectl logs virt-launcher-<name>-xxxProtokolle des virt-launcher-Pods
kubectl get dvStatus des DataVolume-Imports
kubectl get vmimMigrationsstatus
kubectl -n kubevirt logs -l kubevirt.io=virt-handlervirt-handler-Protokolle
kubectl -n kubevirt logs -l kubevirt.io=virt-controllervirt-controller-Protokolle

Nächste Schritte

Zusammenfassung

Die häufigsten Probleme mit KubeVirt lassen sich in fünf Kategorien einteilen: Netzwerk (Layer-2-/Layer-3-CNI-Konflikte), Import von Disk-Images (Probleme mit CDI-Größe und -Format), Fehler beim VM-Start (KVM-Gerät, Ressourcen, Image-Abruf), Live-Migration (storage CPU-Kompatibilität) sowie Leistung (Emulation, CPU-Modell, Hugepages). Verwenden Sie für das Netzwerk den Masquerade-Modus für einfache Setups und Multus mit einem Bridge-Plugin für Layer-2-Anforderungen. Stellen Sie zur Leistungsoptimierung sicher, dass die Hardware-Virtualisierung aktiviert ist, und ziehen Sie bei anspruchsvollen Workloads CPU-Passthrough und Hugepages in Betracht. Im Zweifelsfall beginnen Sie mit den Logs des virt-launcher-Pods – diese enthalten die nützlichsten Fehlermeldungen im KubeVirt-Stack.