kubevirt

VM-Netzwerk mit KubeVirt: Masquerade, DNS und Dienste

Abubakar Siddiq Ango
Abubakar Siddiq Ango Senior Developer Advocate
27. April 2026 4 Min. Lesezeit Anfänger
Virtualisierung Netzwerk Dienste

Voraussetzungen

  • Lebenszyklus der VM und SSH-Zugrifftestvm Ausführung mit SSH-Schlüssel-Authentifizierung
  • Grundlegende Kubernetes-Service-YAML-Dateien (Ports, Selektor, Typ) sicher beherrschen

Die Fragen zum Netzwerk auf Tag zwei für eine KubeVirt-VM lassen sich alle auf dieselbe Erkenntnis zurückführen: Eine laufende VM ist in einen Pod eingebettet. Die Netzwerk-Grundelemente, die Kubernetes bereits für Pods bereitstellt – Labels, Services, NetworkPolicies – lassen sich direkt anwenden. Es gibt fast nichts VM-Spezifisches zu lernen. Fast.

Masquerade ist NAT

Die Standard-Schnittstellenbindung (die Sie bisher verwendet haben) lautet Maskenball. Die VM erhält eine eigene interne IP-Adresse – in der Regel etwa 10.0.2.2 — und KubeVirt verbirgt ihn hinter NAT innerhalb des virt-launcher-Pods. Der ausgehende Datenverkehr vom Gast wird per Source-NAT an die Cluster-IP des Pods weitergeleitet. Eingehender Cluster-Datenverkehr sollte an den Pod gerichtet sein, nicht an den Gast.

Überprüfen Sie dies, indem Sie sich per SSH in die VM einloggen und die beiden Adressen vergleichen:

virtctl ssh -i ~/.ssh/id_ed25519 ubuntu@vmi/testvm

# Im Gast
ip -4 addr show enp1s0
exit

Betrachten Sie nun den Pod von der Host-Seite aus:

kubectl get pod -l kubevirt.io/domain=testvm-o jsonpath='{.items[0].status.podIP}'

Die interne Adresse des Guests und die Cluster-IP des Pods unterscheiden sich voneinander – beide sind echt und in ihrem jeweiligen Kontext routbar. Die Pod-IP ist das, was der Rest des Clusters sieht, daher zielen Dienste darauf ab.

DNS und die Außenwelt

Da Masquerade den Gast durch das Pod-Netzwerk leitet, übernimmt dieser die DNS-Konfiguration des Pods und erhält automatisch Zugriff auf das Cluster-DNS sowie eine Internetverbindung:

virtctl ssh -i ~/.ssh/id_ed25519 ubuntu@vmi/testvm

# Im Gast
sudo apt-get update    # funktioniert; löst archive.ubuntu.com über das Cluster-DNS auf
curl -sI https://kubernetes.io | head -1
nslookup kubernetes.default.svc.cluster.local
exit

Die ersten beiden funktionieren, weil der Pod über einen Internet-Ausgang verfügt; der dritte löst den Kubernetes-API-Dienst innerhalb des Clusters auf dieselbe Weise auf wie jeder andere Pod auch. Es gibt keine VM-spezifischen Besonderheiten.

Einen auf der VM ausgeführten Dienst freigeben

Starten Sie einen kleinen Webserver im Gast, damit wir etwas zur Verfügung stellen können:

virtctl ssh -i ~/.ssh/id_ed25519 ubuntu@vmi/testvm

# Im Gast
sudo apt-get install -y nginx
echo "Hallo von testvm" | sudo tee /var/www/html/index.html
exit

Es gibt zwei Möglichkeiten, einen Dienst davor zu schalten.

Möglichkeit 1 — virtctl expose. Eine Verknüpfung, die einen sinnvollen Label-Selektor auswählt (kubevirt.io/domain) und erstellt einen ClusterIP-Dienst:

virtctl expose vmi testvm--name=testvm-web--port=80--target-port=80
kubectl get svc testvm-web

Möglichkeit 2 – Den Dienst selbst schreiben. Was virtctl expose tut, aber transparent:

apiVersion: v1
Art: Service
Metadaten:
  Name: testvm-web
Spezifikation:
  Selektor:
    kubevirt.io/domain: testvm
  Ports:
    - Port: 80
      Zielport: 80
  type: Cluster-IP

Der Selektor passt auf die Beschriftungen auf dem virt-launcher-Pod, da KubeVirt Labels aus spec.template.metadata.labels auf der VM hinunter zum VMI und weiter zum Pod. Aus Sicht des Dienstes ist die VM ein Pod mit ein paar ungewöhnlichen Containern – für die Routing-Logik spielt das keine Rolle.

Test aus einem Debug-Pod:

kubectl run -it --rm curl-debug--image=curlimages/curl--restart=Never-- \
  curl -s testvm-web.$NS.svc.cluster.local

Du wirst zurückkommen Hallo von testvm.

Wann sollte welcher Diensttyp verwendet werden?

Es gelten dieselben drei Regeln wie für jede andere containerisierte Arbeitslast:

  • Cluster-IP — nur innerhalb des Clusters. Geeignet für den Datenverkehr zwischen VMs sowie zwischen Pods und VMs; was virtctl expose ist standardmäßig eingestellt auf.
  • NodePort — öffnet auf jedem Knoten einen Port. Nur sparsam einsetzen, vor allem für Entwicklungszwecke. kubectl expose vmi testvm --type=NodePort --port=80 wenn du schnell eine brauchst.
  • Lastenausgleich — Dies ist nur sinnvoll, wenn Sie über einen Controller verfügen, der externe Load Balancer bereitstellt (Cloud LB, MetalLB, KubeLB). In einem verwalteten Cluster ist dies die Lösung für den Produktivbetrieb. In einer Sandbox bleibt es In Bearbeitung bis etwas die Anfrage erfüllt.

Die Netzwerkrichtlinien gelten weiterhin

Da der Datenverkehr des Gastes über den „virt-launcher“-Pod läuft, Standardmäßige Kubernetes-Netzwerkrichtlinien wählen VMs auf dieselbe Weise aus wie Pods. A podSelector passend kubevirt.io/domain: testvm deckt die VM nahtlos ab. Das bedeutet, dass Mikrosegmentierung, Namespace-Isolation und ausgehende Datenkontrollen alle funktionieren – Ihre bestehenden Richtlinien-Tools müssen nicht erweitert werden, um virtualisierte Workloads abzudecken. Dies ist der oft unterschätzte Vorteil des Betriebs von VMs als Pods.

Wie geht es weiter?

Das Thema Netzwerk ist abgehakt. Die nächste Lücke betrifft den dauerhaften Speicherzustand – jede VM, die Sie bisher gestartet haben, befand sich auf einer temporären Container-Festplatte. Das storage zeigt, wie man einen echten PersistentVolumeClaim zuordnet, führt durch den DataVolume-Importer von CDI und behandelt die Falle beim Zugriffsmodus, die Teams bei der Live-Migration oft zu schaffen macht.