KVM-Virtualisierung auf Debian 13 einrichten

TL;DR

KVM + libvirt auf Debian 13: Virtualisierung prüfen, Pakete installieren, Bridge-Netzwerk (Native VLAN 40, optional Tagged VLANs 10/60), Storage Pool anlegen und VMs per virt-manager remote über SSH verwalten.

Getestet auf
  • Debian 13 (Trixie) / libvirt 11.3 / QEMU 10 / 2026-06
Inhalt

Einleitung: Was ist Virtualisierung

Virtualisierung ermöglicht es, auf einem physischen Gerät (dem Host) mehrere virtuelle Computer (die Gäste oder VMs) gleichzeitig zu betreiben. Jede VM verhält sich wie ein eigenständiger Rechner mit eigenem Betriebssystem, eigener IP-Adresse und eigenen Ressourcen.

Warum Virtualisierung im Homelab?

  • Ressourcen-Effizienz: Ein Server kann mehrere Dienste in getrennten VMs betreiben
  • Isolation: Probleme in einer VM beeinflussen andere VMs nicht
  • Flexibilität: VMs lassen sich einfach erstellen, klonen, snapshotten und löschen
  • Reproduzierbarkeit: Eine VM kann gesichert und auf anderer Hardware wiederhergestellt werden
  • Testumgebung: Mit eigenen VMs kann man neue Software oder Konfiguration gefahrlos ausprobieren

Warum KVM? Die Entscheidung für den Hypervisor

Bei der Wahl des Hypervisors stehen unter Linux hauptsächlich zwei Optionen zur Verfügung: KVM oder Xen. Für unser Setup haben wir uns für KVM entschieden.

Was ist ein Hypervisor

Ein Hypervisor ist die Software-Schicht, die zwischen der physischen Hardware und den virtuellen Maschinen vermittelt. Er teilt die Hardware-Ressourcen (CPU, RAM, Speicher, Netzwerk) auf die VMs auf.

Es gibt zwei Typen:

TypBeschreibungBeispiele
Typ 1 (Bare-Metal)Läuft direkt auf der Hardware, ohne Betriebssystem dazwischenXen, VMware ESXi
Typ 2 (Hosted)Läuft als Anwendung auf einem bestehenden BetriebssystemVirtualBox, VMware Workstation

KVM ist ein Sonderfall: Es ist technisch ein Typ-2-Hypervisor, weil es als Linux-Kernelmodul läuft. Durch die enge Integration in den Kernel erreicht es aber Typ-1-Performance.

KVM vs. Xen im Vergleich

AspektKVMXen
ArchitekturLinux-Kernelmodul, Host-OS bleibt normal nutzbarSeparater Hypervisor startet vor dem OS
InstallationEinfach – Pakete installieren, fertigKomplexer – erfordert speziellen Xen-Kernel und Reboot
Managementlibvirt, virt-manager, virsh – gut integriertEigene Tools (xl/xm), libvirt-Unterstützung vorhanden
VerbreitungStandard bei allen großen Cloud-Anbietern, Proxmox, OpenStackAWS (ältere Instanzen), Citrix
CommunitySehr aktiv, Teil des Linux-KernelsKleiner, aber stabil
DokumentationUmfangreich, viele TutorialsGut, aber weniger Community-Ressourcen

Warum wir KVM wählen

  1. Native Linux-Integration: KVM ist seit 2007 Teil des Linux-Kernels. Es ist kein Fremdkörper, sondern nutzt die vorhandene Linux-Infrastruktur.

  2. Einfache Einrichtung: Pakete installieren, Dienst starten, fertig. Kein spezieller Kernel, kein Reboot nach der Installation.

  3. Industriestandard: Google Cloud, DigitalOcean, Hetzner, IONOS und die meisten anderen Cloud-Anbieter setzen auf KVM. AWS nutzt bei allen neueren Instanztypen KVM (Nitro-System). Was du hier lernst, ist direkt übertragbar.

  4. Hervorragende Tool-Unterstützung: virt-manager, virsh, Ansible – alle wichtigen Werkzeuge unterstützen KVM erstklassig.

  5. Zukunftssicher: Die Entwicklung ist aktiv, die Community groß, und Debian investiert massiv in KVM als Standard-Virtualisierungslösung.


Voraussetzungen

Hardware-Anforderungen

  • CPU mit Virtualisierungserweiterungen: Intel VT-x oder AMD-V (bei den meisten CPUs der letzten 15 Jahre vorhanden)
  • Ausreichend RAM: Mindestens 8 GB für Host + eine VM, besser 16 GB oder mehr
  • Speicherplatz: SSD empfohlen, mindestens 100 GB für Host und VM-Images

Software-Voraussetzungen

  • Debian 13 (Trixie) mit minimaler Installation
  • SSH-Zugang zum Server
  • Root-Rechte oder sudo-Berechtigung

Schritt 1: Hardware-Virtualisierung prüfen

Bevor wir loslegen, müssen wir sicherstellen, dass die CPU Hardware-Virtualisierung unterstützt und diese im BIOS aktiviert ist.

Melde dich per SSH auf dem Server an und führe folgenden Befehl aus:

egrep -c '(vmx|svm)' /proc/cpuinfo

Was bedeutet das Ergebnis?

  • Zahl größer als 0: Hardware-Virtualisierung ist aktiv. Die Zahl entspricht der Anzahl der CPU-Kerne mit dieser Funktion.
  • 0: Hardware-Virtualisierung ist nicht aktiv.

Falls das Ergebnis 0 ist, musst du ins BIOS/UEFI deines Servers und die Virtualisierung aktivieren. Die Option heißt je nach Hersteller unterschiedlich:

HerstellerBezeichnung
IntelIntel VT-x, Intel Virtualization Technology
AMDAMD-V, SVM Mode
DellVirtualization
HPVirtualization Technology

Nach der Aktivierung im BIOS den Server neu starten und den Test wiederholen.


Schritt 2: System aktualisieren

Vor der Installation sollte das System auf dem neuesten Stand sein:

sudo apt update
sudo apt upgrade -y

Schritt 3: KVM und libvirt installieren

Debian stellt alle notwendigen Pakete für KVM bereit. Wir installieren die Kernkomponenten:

sudo apt install --no-install-recommends \
    qemu-system \
    libvirt-daemon-system \
    libvirt-clients \
    bridge-utils \
    virtinst

Was wurde installiert?

Nach der Installation hast du folgende Komponenten:

  • qemu-system: Der Emulator, der die virtuelle Hardware bereitstellt
  • KVM-Kernelmodule: kvm, kvm_intel (oder kvm_amd) – ermöglichen Hardware-beschleunigte Virtualisierung
  • libvirt-daemon-system: Der Daemon zur Verwaltung von VMs
  • libvirt-clients: Kommandozeilen-Tools wie virsh
  • bridge-utils: Werkzeuge zum Erstellen und Verwalten von Netzwerk-Bridges
  • virtinst: Tool zum Erstellen neuer VMs (virt-install)

Schritt 4: KVM-Kernelmodule prüfen

Nach der Installation sollten die KVM-Module automatisch geladen sein. Prüfe das mit:

lsmod | grep kvm

Du solltest eine Ausgabe wie diese sehen:

kvm_intel             360448  0
kvm                  1142784  1 kvm_intel

Oder bei AMD-CPUs:

kvm_amd               155648  0
kvm                  1142784  1 kvm_amd

Falls die Module nicht geladen sind, lade sie manuell:

# Für Intel-CPUs
sudo modprobe kvm_intel

# Für AMD-CPUs
sudo modprobe kvm_amd

Schritt 5: libvirt-Daemon aktivieren

Der libvirt-Daemon (libvirtd) ist der zentrale Dienst für die VM-Verwaltung. Er muss gestartet und für den automatischen Start beim Booten aktiviert werden.

sudo systemctl enable --now libvirtd

Der Parameter --now bewirkt, dass der Dienst sofort gestartet wird, nicht erst beim nächsten Reboot.

Status prüfen

sudo systemctl status libvirtd

Du solltest active (running) sehen.

Erste Verbindung testen

sudo virsh list --all

Dieser Befehl zeigt alle VMs an (aktuell noch keine). Wenn keine Fehlermeldung erscheint, funktioniert die Verbindung zu libvirt.


Schritt 6: Benutzerberechtigungen einrichten

Standardmäßig kann nur root VMs verwalten. Für den täglichen Gebrauch solltest du deinen Benutzer (z.B. deinen ansible-Benutzer) zu den relevanten Gruppen hinzufügen.

Gruppen verstehen

GruppeBerechtigung
libvirtZugriff auf libvirt-Socket, VM-Verwaltung
kvmDirekter Zugriff auf /dev/kvm

Benutzer hinzufügen

# Für deinen Benutzer (ersetze 'ansible' durch deinen Benutzernamen)
sudo usermod -aG libvirt ansible
sudo usermod -aG kvm ansible

Änderungen aktivieren

Die Gruppenänderungen werden erst nach einem neuen Login wirksam. Du hast zwei Möglichkeiten:

  1. Neu einloggen: SSH-Verbindung trennen und neu verbinden
  2. Temporär für die aktuelle Shell: newgrp libvirt

Berechtigung prüfen

Nach dem erneuten Login:

# Sollte 'libvirt' und 'kvm' enthalten
groups

# Sollte ohne sudo funktionieren
virsh list --all

Schritt 7: UEFI-Support installieren

Moderne Betriebssysteme nutzen UEFI statt des älteren BIOS. Damit deine VMs mit UEFI booten können, installiere das OVMF-Paket:

sudo apt install ovmf

Was ist OVMF?

OVMF (Open Virtual Machine Firmware) ist eine Open-Source-Implementierung von UEFI für virtuelle Maschinen. Es ermöglicht:

  • UEFI-Boot in VMs
  • Secure Boot (für Windows 11 erforderlich)
  • GPT-Partitionierung mit großen Festplatten

libvirt wählt automatisch die passende Firmware, wenn du eine VM mit UEFI erstellst.


Schritt 8: Default-Netzwerk deaktivieren

libvirt erstellt standardmäßig ein NAT-Netzwerk (virbr0). Da wir ausschließlich eine Bridge-Konfiguration nutzen wollen, deaktivieren wir dieses Netzwerk:

# Default-Netzwerk stoppen
sudo virsh net-destroy default

# Autostart deaktivieren
sudo virsh net-autostart default --disable

Überprüfung

sudo virsh net-list --all

Das default-Netzwerk sollte nun als inactive und no bei Autostart angezeigt werden.


Schritt 9: Netzwerk-Bridge einrichten

VMs brauchen Netzwerkzugang. Für ein Homelab mit Serverdiensten ist eine Bridge die beste Wahl.

Warum Bridge statt NAT?

Für ein Homelab mit Serverdiensten ist eine Bridge die bessere Wahl:

  • VMs bekommen eigene IPs aus deinem VLAN (z.B. 192.168.40.x)
  • Andere Geräte im Netzwerk können die VMs direkt erreichen
  • Kein Port-Forwarding nötig
  • Jede VM kann eine statische IP-Adresse erhalten
  • DNS-Auflösung und Service Discovery funktionieren wie bei physischen Rechnern

Aktuelle Netzwerkkonfiguration dokumentieren

Bevor wir Änderungen vornehmen, dokumentieren wir den aktuellen Zustand:

# Alle Netzwerkinterfaces anzeigen
ip addr show

# Routing-Tabelle
ip route show

Notiere dir den Interface-Namen (z.B. eth0, enp0s3, eno1) – du brauchst ihn im nächsten Schritt.

Bridge mit /etc/network/interfaces.d/ einrichten

Debian 13 nutzt klassisch die /etc/network/interfaces Konfiguration mit Include-Dateien. Wir erstellen eine saubere Bridge-Konfiguration in einem separaten File.

Bestehende Interface-Konfiguration anpassen

Bearbeite /etc/network/interfaces und entferne oder kommentiere die IP-Konfiguration des physischen Interface:

sudo nano /etc/network/interfaces

Ändere die Konfiguration von enp1s0 (dein physisches Interface):

# This file describes the network interfaces available on your system
# and how to activate them. For more information, see interfaces(5).
source /etc/network/interfaces.d/*

# The loopback network interface
auto lo
iface lo inet loopback

# The primary network interface - now without IP (managed by bridge)
allow-hotplug enp1s0
iface enp1s0 inet manual

Wichtig: Die IP-Adresse wird nun von der Bridge br40 übernommen, nicht mehr vom physischen Interface!

Bridge-Konfiguration erstellen

Erstelle eine neue Datei für die Bridge-Konfiguration:

sudo nano /etc/network/interfaces.d/br40

Mit folgendem Inhalt:

# Bridge for KVM VMs (VLAN 40 - INFRA)
auto br40
iface br40 inet static
    address 192.168.40.100/24
    gateway 192.168.40.1
    dns-nameservers 192.168.40.1
    dns-search home.arpa
    bridge_ports enp1s0
    bridge_stp off
    bridge_fd 0

Wichtig: Passe enp1s0 an dein tatsächliches Interface an!

Hinweis zur VLAN-Planung: Diese Basis-Konfiguration nutzt VLAN 40 (INFRA) als Native VLAN (untagged). Für Multi-VLAN-Setups siehe Abschnitt “Erweiterte Konfiguration: VLAN-Unterstützung”.

Bedeutung der Bridge-Parameter

ParameterBedeutung
bridge_portsFügt das physische Interface zur Bridge hinzu
bridge_stp offDeaktiviert Spanning Tree Protocol (beschleunigt das Hochfahren)
bridge_fd 0Setzt Forward Delay auf 0 Sekunden

Netzwerk neu starten

Achtung: Bei SSH-Verbindung wird diese kurz unterbrochen!

sudo systemctl restart networking

Alternativ kannst du auch rebooten:

sudo reboot

Bridge-Konfiguration prüfen

Nach dem Neustart der Netzwerkdienste:

# Bridge anzeigen
ip addr show br40

# Prüfen, ob das physische Interface der Bridge zugeordnet ist
sudo brctl show

Erwartete Ausgabe von brctl show:

bridge name     bridge id               STP enabled     interfaces
br40            8000.001ec952d26b       no              enp1s0

Schritt 10: Kernel-Parameter für Bridge-Netzwerk setzen

Um zu verhindern, dass Bridge-Traffic durch iptables gefiltert wird (was Performance-Probleme und Verbindungsprobleme verursachen kann), müssen wir Kernel-Parameter setzen.

Wichtig: Diese Einstellung deaktiviert die Firewall-Filterung für Bridge-Traffic. Der VM-Traffic wird nicht durch die Host-Firewall (iptables/nftables) gefiltert. Firewall-Regeln müssen direkt in den VMs oder auf dem Gateway konfiguriert werden.

br_netfilter-Modul laden

# Modul laden
sudo modprobe br_netfilter

# Modul beim Boot automatisch laden
echo "br_netfilter" | sudo tee /etc/modules-load.d/br_netfilter.conf

Kernel-Parameter konfigurieren

sudo tee /etc/sysctl.d/99-bridge.conf << 'EOF'
# Keine Firewall-Filterung für Bridge-Traffic
net.bridge.bridge-nf-call-ip6tables = 0
net.bridge.bridge-nf-call-iptables = 0
net.bridge.bridge-nf-call-arptables = 0
EOF

Einstellungen anwenden

sudo sysctl -p /etc/sysctl.d/99-bridge.conf

Überprüfung

sudo sysctl -a | grep bridge-nf-call

Alle drei Werte sollten 0 sein.


Schritt 11: Bridge in libvirt registrieren

Damit libvirt die Bridge kennt und wir sie bei der VM-Erstellung auswählen können, registrieren wir sie:

# XML-Definition erstellen
cat > /tmp/host-bridge.xml << 'EOF'
<network>
  <name>host-bridge</name>
  <forward mode="bridge"/>
  <bridge name="br40"/>
</network>
EOF

# In libvirt registrieren
sudo virsh net-define /tmp/host-bridge.xml

# Netzwerk starten und Autostart aktivieren
sudo virsh net-start host-bridge
sudo virsh net-autostart host-bridge

# Aufräumen
rm /tmp/host-bridge.xml

Netzwerke in libvirt anzeigen

sudo virsh net-list --all

Erwartete Ausgabe:

 Name          State    Autostart   Persistent
------------------------------------------------
 default       inactive no          yes
 host-bridge   active   yes         yes

Schritt 12: Storage Pool einrichten

libvirt nutzt Storage Pools zur Verwaltung von VM-Festplatten. Wir richten den Standard-Pool ein und setzen die korrekten Berechtigungen.

Standard-Pool aktivieren

# Standard-Pool definieren (falls noch nicht vorhanden)
sudo virsh pool-define-as default dir --target /var/lib/libvirt/images

# Pool erstellen und starten
sudo virsh pool-build default
sudo virsh pool-start default
sudo virsh pool-autostart default

Berechtigungen setzen

# Verzeichnis-Besitzer setzen
sudo chown -R libvirt-qemu:kvm /var/lib/libvirt/images/

# Berechtigungen setzen
sudo chmod 0711 /var/lib/libvirt/images/

Pool-Status prüfen

# Alle Pools anzeigen
sudo virsh pool-list --all

# Details des default-Pools
sudo virsh pool-info default

Schritt 13: Installation verifizieren

Führe diese Checks durch, um sicherzustellen, dass alles funktioniert:

# 1. KVM-Module geladen?
lsmod | grep kvm
# Erwartung: kvm_intel oder kvm_amd ist gelistet

# 2. libvirt-Daemon läuft?
sudo systemctl status libvirtd
# Erwartung: active (running)

# 3. Bridge-Netzwerk aktiv?
sudo virsh net-list
# Erwartung: 'host-bridge' ist active

# 4. Bridge korrekt konfiguriert?
ip addr show br40
# Erwartung: IP 192.168.40.100/24 ist zugewiesen

# 5. Benutzerberechtigungen korrekt?
virsh list --all
# Erwartung: Funktioniert ohne sudo

# 6. Storage Pool aktiv?
virsh pool-list
# Erwartung: 'default' ist active

Remote-Verwaltung mit virt-manager (Client-System)

Um VMs von deinem Arbeitsrechner aus zu verwalten, installierst du virt-manager auf dem Client-System.

Client-Voraussetzungen

  • Debian-basiertes System (Debian, Ubuntu, etc.)
  • SSH-Zugang zum KVM-Host (kvm01.home.arpa / 192.168.40.100)
  • SSH-Key-basierte Authentifizierung empfohlen

Installation auf dem Client

sudo apt update
sudo apt install virt-manager

SSH-Key-Authentifizierung einrichten (falls noch nicht vorhanden)

Auf dem Client-System:

# SSH-Key generieren (falls noch nicht vorhanden)
ssh-keygen -t ed25519 -C "dein-client@hostname"

# Public Key zum Host kopieren
ssh-copy-id ansible@192.168.40.100

Teste die Verbindung:

ssh ansible@192.168.40.100

Du solltest dich ohne Passwort-Eingabe anmelden können.

virt-manager mit Remote-Host verbinden

Starte virt-manager:

virt-manager

Verbindung über GUI hinzufügen

  1. Klicke auf FileAdd Connection
  2. Wähle folgende Einstellungen:
    • Hypervisor: QEMU/KVM
    • Checkbox: “Connect to remote host over SSH” aktivieren
    • Username: ansible
    • Hostname: 192.168.40.100 (oder kvm01.home.arpa falls DNS bereits läuft)
  3. Klicke auf Connect

Alternative: Verbindung per Kommandozeile

Du kannst virt-manager auch direkt mit der Verbindungs-URI starten:

virt-manager -c 'qemu+ssh://ansible@192.168.40.100/system'

Verbindung testen

Nach erfolgreicher Verbindung solltest du:

  • Den Host kvm01.home.arpa (192.168.40.100) in der Liste sehen
  • Alle VMs auf dem Host anzeigen können
  • VMs erstellen, starten, stoppen können
  • Konsolen-Zugriff auf VMs haben

Erweiterte Konfiguration: VLAN-Unterstützung

Wenn deine VMs in verschiedenen VLANs laufen sollen (z.B. VLAN 10 für MGMT, VLAN 40 für INFRA und VLAN 60 für DEV), benötigst du eine erweiterte Netzwerkkonfiguration.

Konzept: Native VLAN vs. Tagged VLANs

Wichtiges Grundprinzip:

Auf einem Trunk-Port gibt es ein Native VLAN (untagged) und mehrere Tagged VLANs:

  • Native VLAN: Pakete ohne VLAN-Tag → nutzt das physische Interface direkt (z.B. enp1s0)
  • Tagged VLANs: Pakete mit VLAN-Tag → benötigen Subinterfaces (z.B. enp1s0.10, enp1s0.60)

Du kannst NICHT gleichzeitig enp1s0 direkt UND enp1s0.40 als Subinterface verwenden!

Konzept: Bridge pro VLAN

Die empfohlene Methode ist, für jedes VLAN eine separate Bridge zu erstellen. Jede Bridge nutzt entweder das physische Interface (Native VLAN) oder ein VLAN-Subinterface (Tagged VLANs).

Netzwerk-Szenario:

  • VLAN 10 (192.168.10.0/24): MGMT - FW Interface, Switch Interfaces
  • VLAN 20 (192.168.20.0/24): CLIENTS - Client LAN/WLAN
  • VLAN 30 (192.168.30.0/24): GUESTS - Gäste LAN/WLAN
  • VLAN 40 (192.168.40.0/24): INFRA - Infrastruktur-Systeme (Native VLAN)
  • VLAN 50 (192.168.50.0/24): IOT - Internet of Things: Smart Home etc.
  • VLAN 60 (192.168.60.0/24): DEV - Infrastruktur-Testsysteme

Für KVM-Host relevant: VLAN 10 (Management), VLAN 40 (INFRA - Native), VLAN 60 (DEV)

Switch-Konfiguration

Auf dem Switch muss der Port zum KVM-Host als Trunk-Port konfiguriert werden.

# Verbindung zum Switch via SSH
ssh admin@switch-ip

# Interface konfigurieren (z.B. Port 24)
configure
interface gigabitEthernet 1/0/24
description KVM-Host kvm01

# Trunk Mode aktivieren
switchport mode trunk

# Native VLAN setzen (VLAN 40 - INFRA)
switchport trunk native vlan 40

# Erlaubte VLANs festlegen
switchport trunk allowed vlan 10,40,60

# Speichern und Interface aktivieren
no shutdown
exit
write memory

Was bedeutet das?

  • Trunk Mode: Port sendet/empfängt VLAN-Tags (802.1Q)
  • Native VLAN 40: Untagged Traffic gehört zu VLAN 40 (INFRA)
  • Allowed VLANs: Nur VLANs 10, 40, 60 dürfen diesen Port passieren

Hinweis für andere Switches: Die Konzepte sind identisch, nur die Befehle unterscheiden sich. Suche in der Dokumentation deines Switches nach “Trunk Port”, “Native VLAN” und “Allowed VLANs”.

Host-Konfiguration mit VLAN-Bridges

VLAN-Paket installieren

sudo apt install vlan

VLAN-Modul laden

# Modul laden
sudo modprobe 8021q

# Modul beim Boot automatisch laden
echo "8021q" | sudo tee /etc/modules-load.d/vlan.conf

Basis-Interface konfigurieren

Passe /etc/network/interfaces an:

sudo nano /etc/network/interfaces
# This file describes the network interfaces available on your system
# and how to activate them. For more information, see interfaces(5).
source /etc/network/interfaces.d/*

# The loopback network interface
auto lo
iface lo inet loopback

# Physical interface without IP (trunk port)
allow-hotplug enp1s0
iface enp1s0 inet manual

Bridge für Management-VLAN (VLAN 10 - Tagged)

Erstelle /etc/network/interfaces.d/br10-vlan10:

# VLAN 10 Subinterface (Tagged)
auto enp1s0.10
iface enp1s0.10 inet manual
    vlan-raw-device enp1s0

# MGMT Bridge (VLAN 10)
auto br10
iface br10 inet manual
    bridge_ports enp1s0.10
    bridge_stp off
    bridge_fd 0

Hinweis: Die Bridge br10 hat keine IP-Adresse, da der Host nicht direkt im MGMT-Netzwerk sein muss. VMs in diesem VLAN bekommen IPs aus 192.168.10.0/24.

Bridge für INFRA (VLAN 40 - Native/Untagged)

Erstelle /etc/network/interfaces.d/br40-vlan40:

# INFRA Bridge (VLAN 40 - Native/Untagged)
# Native VLAN nutzt das physische Interface DIREKT
auto br40
iface br40 inet static
    address 192.168.40.100/24
    gateway 192.168.40.1
    dns-nameservers 192.168.40.1
    dns-search home.arpa
    bridge_ports enp1s0
    bridge_stp off
    bridge_fd 0

Wichtig: Da VLAN 40 das Native VLAN ist, wird enp1s0 direkt verwendet (NICHT enp1s0.40). Untagged Traffic auf dem Port gehört automatisch zu VLAN 40.

Bridge für DEV (VLAN 60 - Tagged)

Erstelle /etc/network/interfaces.d/br60-vlan60:

# VLAN 60 Subinterface (Tagged)
auto enp1s0.60
iface enp1s0.60 inet manual
    vlan-raw-device enp1s0

# DEV Bridge (VLAN 60)
auto br60
iface br60 inet manual
    bridge_ports enp1s0.60
    bridge_stp off
    bridge_fd 0

Hinweis: Die Bridge br60 hat keine IP-Adresse, da der Host nicht im DEV-Netzwerk sein muss. VMs in diesem VLAN bekommen IPs aus 192.168.60.0/24.

Optional: Bridge mit IP-Adresse in zusätzlichem VLAN

Falls der Host auch im DEV-Netzwerk (VLAN 60) erreichbar sein soll:

# DEV Bridge (VLAN 60) - mit Host-IP
auto br60
iface br60 inet static
    address 192.168.60.100/24
    bridge_ports enp1s0.60
    bridge_stp off
    bridge_fd 0

Hinweis: In der Regel reicht INFRA-Zugriff über VLAN 40. Eine zusätzliche IP in VLAN 60 ist nur bei speziellen Anforderungen nötig.

Netzwerk neu starten

sudo systemctl restart networking

Oder sicherer mit Reboot:

sudo reboot

Konfiguration überprüfen

# Alle Bridges anzeigen
brctl show

# VLAN-Interfaces anzeigen
ip -d link show | grep vlan

# Alle Bridges mit IPs
ip addr show | grep -E "^[0-9]+:|inet "

Erwartete Ausgabe von brctl show:

bridge name     bridge id               STP enabled     interfaces
br10            8000.001ec952d26b       no              enp1s0.10
br40            8000.001ec952d26b       no              enp1s0
br60            8000.001ec952d26b       no              enp1s0.60

Beachte: br40 nutzt enp1s0 direkt (Native VLAN), während br10 und br60 die Subinterfaces nutzen (Tagged VLANs).

Bridges in libvirt registrieren

Für jede Bridge erstellen wir ein libvirt-Netzwerk:

# Bridge br10 (MGMT - VLAN 10)
cat > /tmp/vlan10-bridge.xml << 'EOF'
<network>
  <name>vlan10-mgmt</name>
  <forward mode="bridge"/>
  <bridge name="br10"/>
</network>
EOF

sudo virsh net-define /tmp/vlan10-bridge.xml
sudo virsh net-start vlan10-mgmt
sudo virsh net-autostart vlan10-mgmt

# Bridge br40 (INFRA - VLAN 40)
cat > /tmp/vlan40-bridge.xml << 'EOF'
<network>
  <name>vlan40-infra</name>
  <forward mode="bridge"/>
  <bridge name="br40"/>
</network>
EOF

sudo virsh net-define /tmp/vlan40-bridge.xml
sudo virsh net-start vlan40-infra
sudo virsh net-autostart vlan40-infra

# Bridge br60 (DEV - VLAN 60)
cat > /tmp/vlan60-bridge.xml << 'EOF'
<network>
  <name>vlan60-dev</name>
  <forward mode="bridge"/>
  <bridge name="br60"/>
</network>
EOF

sudo virsh net-define /tmp/vlan60-bridge.xml
sudo virsh net-start vlan60-dev
sudo virsh net-autostart vlan60-dev

# Aufräumen
rm /tmp/vlan*.xml

Überprüfung der libvirt-Netzwerke

sudo virsh net-list --all

Erwartete Ausgabe:

 Name          State    Autostart   Persistent
------------------------------------------------
 default       inactive no          yes
 vlan10-mgmt   active   yes         yes
 vlan40-infra  active   yes         yes
 vlan60-dev    active   yes         yes

VM-Erstellung mit VLAN-Zuordnung

Per virt-install

# VM in VLAN 40 (INFRA) — Beispiel: forgejo
sudo virt-install \
  --name forgejo \
  --ram 4096 \
  --vcpus 2 \
  --disk size=20 \
  --os-variant debian12 \
  --cdrom /var/lib/libvirt/images/debian-13.0-amd64-netinst.iso \
  --network network=vlan40-infra \
  --graphics vnc,listen=127.0.0.1,password=yes

Sicherheitshinweis: VNC ist standardmäßig unverschlüsselt. Nutze listen=127.0.0.1 um nur lokale Verbindungen zu erlauben und setze ein Passwort mit password=yes. Für Produktivumgebungen ist SPICE mit TLS empfehlenswert.

Per virt-manager

In virt-manager beim Erstellen/Bearbeiten einer VM:

  1. Netzwerk-Einstellungen öffnen
  2. Network source auswählen:
    • vlan10-mgmt für Management
    • vlan40-infra für Infrastruktur-Server
    • vlan60-dev für Test-Server
  3. Fertig

Netzwerkplanung mit VLANs

VLANNetzwerkGatewayVerwendungBridgeTyp
10192.168.10.0/24192.168.10.1Management Infrastrukturbr10Tagged
40192.168.40.0/24192.168.40.1Infrastruktur-Server (Natives VLAN)br40Native
60192.168.60.0/24192.168.60.1Test-Serverbr60Tagged

Beispiel VM-Planung (orientiert an der Serien-Referenz):

VMVLANIP-AdresseZweck
kvm01 (Host)40192.168.40.100KVM-Host Management
forgejo40192.168.40.110Git/CI (Forgejo)
pki40192.168.40.112PKI Server (step-ca)
dns0140192.168.40.113DNS (PowerDNS/Bind9)
dev-sandbox60192.168.60.20Testsystem

Wichtige Hinweise zu VLANs

  1. Native VLAN 40: Das INFRA-VLAN nutzt das physische Interface direkt ohne Tagging - verwende enp1s0, nicht enp1s0.40
  2. Tagged VLANs: VLAN 10 und VLAN 60 nutzen Subinterfaces (enp1s0.10, enp1s0.60)
  3. Trunk-Port erforderlich: Der Switch-Port muss als Trunk mit Native VLAN 40 und Allowed VLANs 10,40,60 konfiguriert sein
  4. Sicherheit: VLAN-Segmentierung erfolgt auf Switch-Ebene - INFRA (40) ist vom DEV-Netzwerk (60) getrennt
  5. Performance: Minimal, da VLAN-Tagging hardwarebeschleunigt ist
  6. Virtio-Treiber: Verwende virtio als Network-Model für beste Performance mit VLANs

Fehlerbehebung VLAN-Setup

# VLAN-Modul geladen?
lsmod | grep 8021q

# VLAN-Interfaces sichtbar?
ip -d link show type vlan

# Bridges korrekt?
brctl show

# Native VLAN: br40 nutzt enp1s0 direkt?
brctl show | grep br40
# Erwartung: br40 -> enp1s0 (NICHT enp1s0.40)

# Traffic sehen (tcpdump)
sudo tcpdump -i enp1s0 -e -n vlan

VLAN-Konnektivität testen

# Vom Host zu VM in VLAN 40 (sollte funktionieren)
ping -c 3 192.168.40.110

# Vom Host zu VM in VLAN 60 (funktioniert nur wenn br60 eine IP hat)
ping -c 3 192.168.60.20

# VLAN-Tags auf dem Interface beobachten
sudo tcpdump -i enp1s0 -nn -e 'vlan 10 or vlan 60'
# Native VLAN (40) erscheint OHNE vlan-Tag

Zusammenfassung: Was haben wir eingerichtet?

Nach diesem Tutorial hast du einen vollständigen Virtualisierungs-Host mit:

KomponenteFunktion
KVMHardware-beschleunigte Virtualisierung im Linux-Kernel
QEMUEmulator für virtuelle Hardware (CPU, Festplatten, Netzwerk)
libvirtEinheitliche Verwaltungs-API für VMs
virshKommandozeilen-Tool für VM-Verwaltung
Bridge-NetzwerkNetzwerkverbindung für VMs per Bridge (br40) mit eigenen IPs im LAN
Storage PoolVerwaltetes Verzeichnis für VM-Festplatten und ISO-Images
virt-managerGrafische Remote-Verwaltung vom Client-System
VLAN-SupportOptional: Multi-VLAN-Fähigkeit mit getrennten Bridges

Nächste Schritte

Mit dieser Grundlage kannst du nun:

  1. Erste VM erstellen: Über virt-manager oder mit virt-install (nächster Serienteil)
  2. ISO-Images bereitstellen: Nach /var/lib/libvirt/images/ kopieren
  3. Infrastruktur-VMs aufsetzen: Forgejo, DNS, PKI für dein Homelab

Wichtige Verzeichnisse

PfadInhalt
/var/lib/libvirt/images/VM-Festplatten und ISO-Images
/etc/libvirt/libvirt-Konfiguration
/var/log/libvirt/Log-Dateien
/etc/libvirt/qemu/VM-Konfigurationsdateien (XML)

Nützliche Kommandos für den täglichen Gebrauch

# VM-Status anzeigen
virsh list --all

# VM starten/stoppen
virsh start <vm-name>
virsh shutdown <vm-name>
virsh destroy <vm-name>  # Erzwingt Shutdown

# VM-Informationen
virsh dominfo <vm-name>
virsh domstats <vm-name>

# Konsolen-Zugriff
virsh console <vm-name>

# VM-Konfiguration bearbeiten
virsh edit <vm-name>

# Storage Pool Info
virsh pool-list
virsh vol-list default

# Netzwerk-Status
virsh net-list --all

Fehlerbehebung

“Cannot access storage file”

# Berechtigungen prüfen
ls -la /var/lib/libvirt/images/

# libvirt-Benutzer Zugriff geben
sudo chown libvirt-qemu:kvm /var/lib/libvirt/images/*.iso
sudo chmod 0644 /var/lib/libvirt/images/*.iso

“Network ‘host-bridge’ is not active”

sudo virsh net-start host-bridge
sudo virsh net-autostart host-bridge

virsh ohne sudo funktioniert nicht

# Gruppen prüfen
groups

# Falls libvirt fehlt
sudo usermod -aG libvirt $USER
sudo usermod -aG kvm $USER

# Neu einloggen
exit
# Dann neu per SSH verbinden

Bridge hat keine Verbindung

# Bridge-Status prüfen
ip addr show br40
brctl show

# Netzwerk-Dienst neu starten
sudo systemctl restart networking

# Falls das nicht hilft: Reboot
sudo reboot

virt-manager kann sich nicht verbinden

# Auf dem Host: libvirtd-Status prüfen
sudo systemctl status libvirtd

# Auf dem Client: SSH-Verbindung testen
ssh ansible@192.168.40.100

# Auf dem Host: Benutzer in libvirt-Gruppe?
groups ansible

VM startet nicht / “Failed to start domain”

# VM-Logs prüfen
sudo tail -f /var/log/libvirt/qemu/<vm-name>.log

# VM-Konfiguration validieren
virsh dumpxml <vm-name>

# Häufige Ursachen:
# - ISO-Datei fehlt oder falsche Berechtigungen
# - Netzwerk nicht verfügbar
# - Nicht genug RAM/CPU-Kerne verfügbar

VLAN-Traffic funktioniert nicht

# VLAN-Modul geladen?
lsmod | grep 8021q

# VLAN-Interfaces existieren?
ip -d link show | grep vlan

# Switch-Port korrekt konfiguriert? (Trunk, Native VLAN, Allowed VLANs)
# Prüfe Switch-Konfiguration

# Traffic auf VLAN-Interface beobachten
sudo tcpdump -i enp1s0.10 -n

# Bridge-Zuordnung prüfen
brctl show

Weiterführende Ressourcen


Weiterführend


Changelog

  • 2026-06-24 — bare-001-Hostname durchgehend durch kanonischen Hostnamen kvm01/kvm01.home.arpa ersetzt (inkl. Switch-Port-Description im CLI-Beispiel); VM-Planungstabelle auf Serien-Referenz angepasst (gitlabforgejo, runner entfernt); virt-install-Beispiel-VM auf forgejo umbenannt; Nächste-Schritte-Abschnitt entschlackt (Terraform/GitLab/Grafana-Verweise entfernt, da nicht in Serienscope); Weiterführend + Changelog ergänzt.
  • 2026-01-20 — Erstveröffentlichung (Entwurf).