Jede VM, die Sie bisher gestartet haben, war nur vorübergehend. Das Container-Disk-Image ist schreibgeschützt, Änderungen während der Laufzeit werden im Arbeitsspeicher gespeichert, und alles, was Sie ändern, geht beim Neustart der VM verloren. Das ist die richtige Standardeinstellung zum Lernen, aber die falsche, wenn Sie Daten dauerhaft behalten möchten. Dieses Tutorial behebt beide Probleme: Es ordnet einen PersistentVolumeClaim zu testvm um einen dauerhaften Zustand zu gewährleisten, und startet dann eine neue VM direkt aus einem echten Cloud-Image, das von CDI importiert wurde.
containerDisk ist nicht persistent
Das sollte man klar sagen, weil es den Leuten in der Produktion Probleme bereitet: a containerDisk ist ein in einen OCI-Container eingebettetes Disk-Image. Die Schreibvorgänge der VM werden in eine beschreibbare Schicht im Arbeitsspeicher geschrieben. Wird die VM angehalten, gehen diese Schreibvorgänge verloren. Verwenden Sie containerDisks für zustandslose, unveränderliche und kurzlebige Workloads – beispielsweise als Betriebssystem-Root für einen Build-Agenten, als Basis-Image für einen Worker-Knoten oder als schnell bereitgestellte temporäre VM. Alles, was Sie auf keinen Fall verlieren möchten, benötigt ein PVC.
Eine PVC-Datei in die laufende VM einbinden
Erstellen Sie ein kleines PVC, das auf Ihrer Standard-StorageClass basiert:
apiVersion: v1
Art: PersistentVolumeClaim
Metadaten:
name: testvm-data
Spezifikation:
Zugriffsmodi: [ReadWriteOnce]
Ressourcen:
Anfragen:
storage: 5 Gi
kubectl apply -f testvm-data-pvc.yaml
kubectl get pvc testvm-data
Schließen Sie es im laufenden Zustand an die VM an:
virtctl addvolume testvm--volume-name=testvm-data
Der Gast sieht, dass ein neues Blockgerät erscheint (in der Regel /dev/vdb) ohne Neustart – der Kernel erkennt das Gerät genauso, wie er ein an einen echten Rechner angeschlossenes USB-Laufwerk erkennen würde. Per SSH einloggen, partitionieren, formatieren, mounten, etwas zur Überprüfung darauf schreiben:
virtctl ssh -i ~/.ssh/id_ed25519 ubuntu@vmi/testvm
# Im Gast
lsblk
sudo mkfs.ext4 /dev/vdb
sudo mkdir -p /mnt/data
sudo mount /dev/vdb /mnt/data
echo "persistent across reboots" | sudo tee /mnt/data/canary.txt
sudo umount /mnt/data
exit
Beenden Sie die VM und starten Sie sie erneut. Das PVC bleibt bestehen; wenn Sie die Verbindung wiederherstellen und die VM neu mounten, ist Ihre Datei immer noch vorhanden. Das ist die Dauerhaftigkeit, die KubeVirt von storage von Kubernetes übernimmt – ohne virtualisierungsspezifischen Code schreiben zu müssen.
Eine neue VM von einem DataVolume starten
„Hotplug“ ist die richtige Wahl, wenn Sie einer bestehenden VM eine Datenträger-Festplatte hinzufügen. Bei einer VM, die von einem echten Cloud-Image (nicht von der kleinen containerDisk) bootet, sollten Sie ein DataVolume als Stammverzeichnis verwenden.
Ein DataVolume ist ein PVC mit besonderen Funktionen. Der DataVolume-Controller von CDI überwacht diese, erstellt im Hintergrund ein PVC und führt einen Importer-Pod aus, der ein Cloud-Image von einer HTTP-URL (oder aus einer Registry, einem Upload, einem vorhandenen PVC-Klon, einem VolumeSnapshot, usw.) in das PVC. Wenn der Importeur meldet Erfolgreich, kann nun von der PVC-Festplatte gebootet werden.
Hier ist eine VM, deren Root-Festplatte ein DataVolume ist, auf die das offizielle Ubuntu 22.04-Cloud-Image importiert wird:
apiVersion: kubevirt.io/v1
kind: VirtualMachine
metadata:
name: ubuntu-vm
spec:
runStrategy: Always
dataVolumeTemplates:
- metadata:
name: ubuntu-vm-rootdisk
spec:
source:
http:
url: https://cloud-images.ubuntu.com/jammy/current/jammy-server-cloudimg-amd64.img
storage:
accessModes: [ReadWriteOnce]
resources:
requests:
storage: 20Gi
template:
metadata:
labels:
kubevirt.io/domain: ubuntu-vm
spec:
domain:
devices:
disks:
- name: rootdisk
disk:
bus: virtio
- name: cloudinitdisk
disk:
bus: virtio
interfaces:
- name: default
masquerade: {}
resources:
requests:
memory: 2Gi
cpu: "1"
networks:
- name: default
pod: {}
volumes:
- name: rootdisk
dataVolume:
name: ubuntu-vm-rootdisk
- name: cloudinitdisk
cloudInitNoCloud:
userData: |
#cloud-config
ssh_authorized_keys:
- PASTE_YOUR_PUBLIC_KEY_HERE
Wenden Sie es an und beobachten Sie den Import:
kubectl apply -f ubuntu-vm.yaml
kubectl get datavolume,pvc,vmi -l kubevirt.io/domain=ubuntu-vm-w
CDI führt durch Auf den ersten Verbraucher warten → Import läuft (mit %) → Erfolgreich (3–8 Minuten für ein Image von ca. 600 MB, abhängig von der Bandbreite). Sobald das DataVolume bereit ist, startet die VM und Sie können virtctl ssh in.
Die Zugriffsmodus-Falle
Die Zugriffsmodi: [ReadWriteOnce] Die oben genannte Option funktioniert bei einer VM mit einem einzigen Knoten und verhindert die Live-Migration. RWO-PVCs lassen jeweils nur die Zuordnung zu einem Pod zu, sodass KubeVirt die VM nicht auf einen anderen Knoten migrieren kann, ohne sie zuvor anzuhalten. Für eine live migrierbare VM muss die StorageClass Folgendes unterstützen: ReadWriteMany (RWX) und das DataVolume/PVC muss dies deklarieren. Auf einem Sandbox-Cluster unter Longhorn stehen beide Modi zur Verfügung – Sie wählen einen davon bei der Erstellung des Volumes aus. Bei den meistenstorage ist nur RWO verfügbar; für RWX benötigen Sie einenstorage (NFS, CephFS, EFS).
Das stellt Teams erst spät im Projektverlauf vor Probleme. Richten Sie Ihre DataVolumes von Anfang an mit dem Zugriffsmodus ein, den Sie tatsächlich benötigen. Wenn die Migration wichtig ist, wählen Sie RWX. Wenn nicht, ist RWO kostengünstiger und schneller.
Wie geht es weiter?
Storage Migration bilden die Grundlage für alle betrieblichen Abläufe – Backups, Hochverfügbarkeit und Ausfälle aufgrund geplanter Wartungsarbeiten. Mit einem echten DataVolume-Stammverzeichnis und dem richtigen Zugriffsmodus lässt sich der Rest des Betriebsablaufs (Live-Migration mit virtctl migrate, Schnappschüsse via Snapshot einer virtuellen Maschine(einschließlich Backup-Integrationen) fällt in den Zuständigkeitsbereich von KubeVirt, und das Benutzerhandbuch ist die nächste Lektüre, die Sie sich vornehmen sollten.
