Grundlagen: CRs, Services, warm vs. cold
MTV (Projektname: Forklift) ist ein Operator. Alles, was du tust, ist das Anlegen von Custom Resources – der Rest ist Orchestrierung durch Controller.
Die fünf CRs
- Provider – Verbindungsdaten zu Quelle und Ziel
- NetworkMap – Quellnetz → Zielnetz (pod, multus oder ignored)
- StorageMap – Quell-Datastore → StorageClass
- Plan – VM-Liste mit Migrationsparametern plus die beiden Maps
- Migration – führt einen Plan aus. Pro Plan läuft immer nur eine Migration gleichzeitig; mehrere nacheinander sind erlaubt (z. B. für Reste nach Teil-Fehlschlägen)
Cold Migration
VM ist während der gesamten Migration aus. Bei VMware läuft ein Conversion-Pod mit virt-v2v, der konvertiert und die Disks überträgt. Bei RHV/OpenStack übernehmen Volume Populators den Disk-Transfer.
Warm Migration
VM läuft weiter. MTV erstellt in Intervallen (Standard: 60 min) CBT-Snapshots und überträgt nur die Deltas (Precopy). Erst zum Cutover wird die VM heruntergefahren und der letzte Stand übertragen. Voraussetzung: Changed Block Tracking auf VM und jeder Disk aktiviert.
Services hinter den Kulissen
- Inventory – verbindet sich zu den Providern, hält lokales Inventar, stößt Validierung an
- Validation – prüft VMs per Regelwerk (Rego) auf Migrierbarkeit; Ergebnis: Plan-Status
ReadyoderNot ready - Migration Controller – orchestriert die Migration, setzt am Ende
Completed - Populator Controller – Disk-Transfers via Volume Populators (RHV, OpenStack)
- KubeVirt- und CDI-Controller – erledigen die eigentliche technische Arbeit (PVCs, Importer-Pods, virt-launcher)
virt-v2v: der Umbau der Gäste
virt-v2v arbeitet nur auf den Disks, nie in der laufenden VM – Gast-Credentials sind nicht nötig. Es injiziert VirtIO-Treiber, installiert den QEMU Guest Agent, passt die Boot-Konfiguration an und entfernt Hypervisor-Reste (VMware Tools, alte NIC-Treiber). Bei VMware- und OVA-Quellen setzt es zusätzlich die IP-Adressen.
Raw Copy Mode (skipGuestConversion: true) überspringt die Konvertierung komplett – für OS, die virt-v2v nicht kann (z. B. macOS) oder LUKS-Disks ohne Schlüssel. Standardmäßig laufen solche VMs dann auf Kompatibilitätsgeräten (SATA, E1000E, USB); mit useCompatibilityMode: false auf VirtIO, aber nur wenn die Treiber im Gast schon installiert sind.
In der RHEL-Gast-Falle: Guest Agent in Disconnected-Umgebungen
Bei RHEL-Gästen versucht virt-v2v, den Guest Agent aus der Red-Hat-Registry zu installieren. In abgeschotteten Umgebungen schlägt das fehl – dann per Hook oder anderer Automatisierung nachinstallieren.
VMware vSphere per CLI migrieren
Der Referenz-Workflow. Sechs CRs in fester Reihenfolge – jede weitere Quelle (Etappe 3) ist nur eine Variation davon.
Der CR-Stapel
- SecretvCenter/ESXi-Zugangsdaten,
urlz. B.https://<vCenter_host>/sdk.insecureSkipVerifynur bewusst setzen – Daten laufen dann unverschlüsselt. - Provider
type: vsphere,sdkEndpoint: vcenteroderesxi.vddkInitImageist optional, aber dringend empfohlen – beschleunigt Transfers massiv. - HostBindet einen ESXi-Host (per moRef) an eine Migrations-Netzwerk-IP.
- NetworkMap + StorageMapQuellnetz/-datastore (per moRef) auf NAD bzw. StorageClass mappen. Auch Pflicht, wenn VMs kein Netz/keine Disk haben – dann eben leer.
- PlanVM-Liste plus Parameter:
warm,preserveStaticIPs,skipGuestConversion, Namens-Templates, Scheduling-Labels. - MigrationReferenziert den Plan und startet ihn. Bei warm optional mit
cutover-Zeit (ISO 8601 mit UTC-Offset).
Plan-Parameter, die wehtun können
| Parameter | Wirkung |
|---|---|
| warm | true = warm, false = cold. Warm ohne cutover in der Migration-CR: es läuft nur Precopy, kein Umzug |
| preserveStaticIPs | vNICs ändern sich bei der Migration – statisch an den Interface-Namen gebundene IPs gehen sonst verloren |
| skipGuestConversion | true = Raw Copy Mode statt virt-v2v (siehe Etappe 0) |
| pvcNameTemplateUseGenerateName | true (Default) hängt Zufallszeichen an PVC-Namen an |
| migrateSharedDisks | Shared-Disk-Handling, siehe Etappe 2 |
| targetName | Zielname der VM – muss eindeutig und eine gültige Kubernetes-Subdomain sein, sonst schlägt die Migration automatisch fehl |
pvcNameTemplateUseGenerateName: false plus eigenes Template kann Namenskollisionen erzeugen – die Migration läuft los und crasht erst an der Kollision.Weitere Stolpersteine (aus den „Considerations")
- Kein Snapshot nach Migrationsstart – kann die Migration zum Scheitern bringen; ebenso vMotion/svMotion und Relocation deaktivieren (Datenkorruption)
- Antivirus in Quell-VMs vorher entfernen – bekannte Fehlerquelle
- NVMe-Disks aus VMware werden nicht unterstützt
- FIPS: vSphere-6- und vSphere-7-VMs lassen sich nicht auf FIPS-konforme OpenShift-Virtualization-Cluster migrieren
- UDN: Liegt die Provider-IP innerhalb des Subnetzes eines User-Defined Network, schlägt die Migration fehl
moRefs beschaffen (Inventory-Service abfragen)
Datastores, Netze, Hosts und VMs werden per Managed Object Reference (moRef) referenziert. Die holst du dir aus dem Inventory-Service:
# Route des Inventory-Service und Token
oc get route -n openshift-mtv
TOKEN=$(oc whoami -t)
# Provider-ID, dann z. B. Datastores auflisten
curl -H "Authorization: Bearer $TOKEN" https://<inventory_route>/providers/vsphere -k
curl -H "Authorization: Bearer $TOKEN" https://<inventory_route>/providers/vsphere/<provider_id>/datastores/ -k
Im JSON steht die moRef im Feld id (z. B. datastore-11).
Minimalbeispiel: Secret + Provider
Das Secret trägt Labels, damit MTV es dem Provider-Typ zuordnen kann; der Provider verweist zurück auf das Secret.
cat <<'EOF' | oc apply -f -
apiVersion: v1
kind: Secret
metadata:
name: vsphere-creds
namespace: openshift-mtv
labels:
createdForProviderType: vsphere
createdForResourceType: providers
type: Opaque
stringData:
user: <user>
password: <password>
insecureSkipVerify: "false"
cacert: |
<ca_certificate>
url: https://<vCenter_host>/sdk
EOF
cat <<'EOF' | oc apply -f -
apiVersion: forklift.konveyor.io/v1beta1
kind: Provider
metadata:
name: vsphere-source
namespace: openshift-mtv
spec:
type: vsphere
url: https://<vCenter_host>/sdk
settings:
vddkInitImage: <VDDK_image>
sdkEndpoint: vcenter
secret:
name: vsphere-creds
namespace: openshift-mtv
EOF
Migration abbrechen (ganz oder einzelne VMs)
Ganze Migration: Migration-CR löschen. Einzelne VMs: in den spec.cancel-Block der laufenden Migration-CR eintragen – der Rest läuft weiter.
oc delete migration <migration> -n openshift-mtv
# oder gezielt einzelne VMs (per moRef-id oder name)
cat <<'EOF' | oc apply -f -
apiVersion: forklift.konveyor.io/v1beta1
kind: Migration
metadata:
name: <migration>
namespace: openshift-mtv
spec:
cancel:
- id: vm-102
- name: rhel8-vm
EOF
Deep Inspection: VMs vor der Migration prüfen (Tech Preview)
Deep Inspection mountet die Disks in einem Inspection-Pod und analysiert Gast-OS, Dateisysteme und bekannte Konvertierungsprobleme – Fehler fallen so vor der Migration auf statt mittendrin. Läuft in Batches von 10 gleichzeitig; braucht VDDK und aktiviertes CBT.
# Conversion-CR mit conversion-type: DeepInspection anlegen, dann:
oc get conversion <vm_name>-inspection -n openshift-mtv -o json | jq '.status.phase'
oc get conversion <vm_name>-inspection -n openshift-mtv -o json | jq '.status.inspectionResult'
Pods und PVCs räumt MTV nach der Inspektion selbst auf. Tech Preview – nicht für Produktion supportet.
Spezialfälle: Storage Copy Offload & Shared Disks
Zwei VMware-Sonderwege: Daten direkt im SAN kopieren statt übers Netz – und Multi-Writer-Disks, die genau einmal mitgenommen werden müssen.
Storage Copy Offload (XCOPY)
Statt die Disks übers Netzwerk zu ziehen, ruft MTV via vmkfstools auf dem ESXi-Host den XCOPY-Befehl des Storage-Arrays auf (iSCSI oder FC). Die Daten wandern innerhalb des SAN – deutlich schneller. Voraussetzungen: unterstütztes Array, funktionierender CSI-Treiber dorthin, vSphere-Rolle mit Datastore- und Host-Configuration-Rechten (Vorschlag: „StorageOffloader").
- Feature einschalten
oc patch forkliftcontrollers forklift-controller --type merge -p '{"spec":{"feature_copy_offload": "true"}}' -n openshift-mtv - Vendor-Secret anlegenJe Hersteller eigene Keys: immer
STORAGE_HOSTNAME/USERNAME/PASSWORD, dazu z. B.ONTAP_SVM(NetApp),POWERMAX_SYMMETRIX_ID,PURE_CLUSTER_PREFIX; Hitachi zusätzlich vSphere-Zugang (GOVMOMI_*) undHOSTGROUP_ID_LIST. - StorageMap mit offloadPlugin
vsphereXcopyConfigmitsecretRefundstorageVendorProduct, dann normalen Plan darauf zeigen lassen.
Shared Disks: das Zwei-Pläne-Muster
Nur cold, keine Shared-Boot-Disks. Ab MTV 2.7.11 steuert migrateSharedDisks (Default: true) das Verhalten:
- Plan 1 (
migrateSharedDisks: true) – alle Shared Disks, pro Shared Disk genau eine angeschlossene VM, deren unshared Disks. VMs so wählen, dass jede Shared Disk nur einmal im Plan vorkommt. Vor dem Start: alle VMs an den Shared Disks ausschalten. - Plan 2 (
migrateSharedDisks: false) – alle übrigen VMs mit ihren unshared Disks (Transfer via CDI). MTV hängt die bereits migrierten Shared-PVCs danach automatisch wieder an.
VM-Namen automatisch generieren (Template-Utility)
Für DNS-konforme Zielnamen bietet MTV Template-Funktionen in den Namens-Templates, u. a. lower, trunc, replace, trimSuffix, nospace, mustRegexReplaceAll sowie Mathe-Funktionen (add, mod, max …). Beispiel: {{ lower "TEXT" }} → text, {{ trunc 3 "abcdef" }} → abc.
Andere Quellen: RHV bis EC2
Der CR-Stapel aus Etappe 1 bleibt identisch – nur Secret-Inhalte und Provider-Typ wechseln. Hier die Unterschiede, die zählen.
Provider-Typen im Überblick
| Quelle | type | Besonderheit |
|---|---|---|
| Red Hat Virtualization | ovirt | Engine-API-URL; Disk-Transfer per Volume Populator (cold) |
| OpenStack | openstack | Keystone-Zugang; Transfer per Volume Populator |
| OVA | ova | url: <nfs_server:/nfs_path> – die OVAs liegen auf einem NFS-Share |
| Microsoft Hyper-V | hyperv | Secret mit url (WinRM-Host) und smbUrl im Format //server/share – Vorwärts-Slashes, sonst YAML-Ärger mit Backslashes |
| AWS EC2 | ec2 | Provider-Setting target-az zwingend passend zu einer AZ mit OpenShift-Workern |
| OpenShift Virtualization | openshift | Secret mit token statt User/Passwort; für Migrationen zwischen Clustern |
target-az auf eine AZ ohne Worker-Nodes, kann der EBS-CSI-Treiber die Volumes nicht anhängen – die Migration scheitert erst spät. Bei Same-Account-Migrationen die Credentials des OpenShift-Clusters verwenden, damit der CSI-Treiber auf die Volumes zugreifen kann.OVA: Finger weg von Vendor-Appliances
OVA-Import ist für Gast-OS validiert, die aus vSphere exportiert wurden. Netzwerk-/Security-Appliances von Drittherstellern nutzen oft proprietäre Bootloader oder Disk-Layouts, die die virt-v2v-Konvertierung nicht übersteht – und die Konvertierung kann den Vendor-Support erlöschen lassen. Besser: das native QCOW2/KVM-Image des Herstellers per „Upload Image" oder „Import from URL" direkt in OpenShift Virtualization bringen.
OCP → OCP: Live Migration
Zwischen OpenShift-Virtualization-Clustern geht auch live – gleiche Prozedur wie sonst, nur bekommt der Plan das Label type: live. Voraussetzung sind die Live-Migration-Prerequisites von OpenShift Virtualization. Nebenbei: Bei OCP→OCP läuft kein virt-v2v, deshalb gibt es auch keine Conversion-Pod-Logs.
Advanced Options
Stellschrauben am ForkliftController und am Plan: Precopy-Takt, AIO-Puffer, eigene Validierungsregeln, Hooks und gezieltes Scheduling.
Precopy-Intervall (warm)
Wie oft MTV zwischen Start und Cutover Snapshots zieht. Default 60 Minuten, Änderung ohne Pod-Neustart:
oc patch forkliftcontroller/<forklift-controller> -n openshift-mtv \
-p '{"spec":{"controller_precopy_interval": <minuten>}}' --type=merge
AIO-Buffering (nur cold!)
Tunt die NBD/NFC-Puffer für Transfers – lohnt bei mehreren VMs gleichzeitig vom selben ESXi-Host. Konfiguration: virt_v2v_extra_args: "--vddk-config /mnt/extra-v2v-conf/input.conf" plus virt_v2v_extra_conf_config_map: "perf" im ForkliftController, dazu eine ConfigMap perf, deren binaryData.input.conf die Base64-kodierten Werte enthält:
echo -e "VixDiskLib.nfcAio.Session.BufSizeIn64KB=16\nvixDiskLib.nfcAio.Session.BufCount=4" | base64
# Ergebnis in die ConfigMap perf (binaryData: input.conf), dann forklift-controller-Pod neu starten
Eigene Validierungsregeln (Rego)
Die Validation prüft VMs mit OPA-Regeln; Treffer landen als „Concerns" in der Inventory und der Web-Konsole. Eigene Regeln kommen in eine ConfigMap forklift-validation-config im Namespace openshift-mtv und überleben so Pod-Neustarts und Upgrades. Package-Namespaces: io.konveyor.forklift.vmware bzw. .ovirt.
- Gleicher Regelname wie eine bestehende Regel – die Regeln werden per ODER verknüpft
- Widerspruch zu einer Default-Regel (z. B.
default valid_inputumdefiniert) – der Validation-Service startet nicht mehr - Defaults prüfen:
oc rsh <validation_pod>, danngrep -R "default" /usr/share/opa/policies/io/konveyor/forklift/<provider>
Hooks: Ansible vor und nach der Migration
Pro Plan maximal ein PreHook und ein PostHook. Das Playbook wird Base64-kodiert in der Hook-CR hinterlegt, als ConfigMap in einen Job im Namespace openshift-mtv gemountet und loggt sich per SSH in die VM ein – PreHook auf der Quelle, PostHook auf OpenShift. Die VM muss dafür laufen und per SSH erreichbar sein. Service Account optional, braucht aber mindestens Schreibrechte auf openshift-mtv.
Target-VM-Scheduling (MTV ≥ 2.10)
Steuert, wo migrierte VMs landen – direkt im Plan, gilt für alle VMs des Plans:
- targetAffinity – komplexe Regeln inkl. podAntiAffinity, z. B. VMs für DR auf verschiedene Nodes verteilen
- targetLabels – Organisations-Labels; System-Labels (migration, plan, vmID) überschreiben gleiche Keys
- targetNodeSelector – exaktes Key-Value-Matching, klassisch für GPU- oder Storage-Nodes
- convertorLabels / -NodeSelector / -Affinity – dasselbe für die virt-v2v-Konvertierungs-Pods (nur cold), z. B. um I/O-starke Nodes für die Konvertierung zu reservieren
Anti-Affinity gibt es nur auf Workload-Ebene (Pods), nicht auf Node-Ebene.
Performance: Metriken und Parallelität
Red-Hat-Labordaten als Best Case (vSphere-basiert). Die eine Zahl, die du dir merken musst: 10 gleichzeitige VMs pro ESXi-Host.
Parallelität steuern: MAX_VM_INFLIGHT
Maximale gleichzeitige VM-Transfers pro ESXi-Host, Default 20. Ein Slot pro VM, egal wie viele Disks. Beispiel: MAX_VM_INFLIGHT=20 und 2 ESXi-Hosts im Provider = bis zu 20 VMs je Host parallel.
- 10 VMs gleichzeitig statt sequenziell – rund dreimal schneller (272 statt 100 MiB/s); mehr als 10 pro Host bringt kaum noch etwas
- Mehrere Hosts skalieren: 80 VMs von 1 Host: 2:43 h (294 MiB/s) – von 8 Hosts à 10 VMs: 41 min (1.173 MiB/s)
- Pläne aufteilen: max. 500 Disks pro Plan; 500 VMs in 1 Plan: 5:10 h – 800 VMs in 8 Plänen: 57 min. Faustregel: ~100 VMs pro Plan
Netz & Endpoints
10-GbE-Netz einplanen; Migration frisst Bandbreite und teilt sie sich sonst mit Produktivdiensten. Bei vielen VMs auf mehreren Hosts: vCenter-Endpoint für Inventory, ESXi-Netze für den Transfer. Ab vSphere 7.0 lässt sich das NBD-Interface am ESXi taggen: esxcli network ip interface tag add -t vSphereBackupNFC -i vmk2. BIOS/Host-Power-Management auf High Performance bringt messbar (+15 MiB/s Datastore-Read bei >10 VMs).
Warm-Empfehlungen
Bis 400 Disks parallel getestet; ab ~300 sinkt die Precopy-Rate um ~25 % – daher Gruppen von ≤200 Disks fahren. Cutover möglichst direkt nach Planstart setzen (nur ein Precopy pro VM). Viele Einzel-VM-Pläne mit Zeitpuffer: controller_precopy_interval auf 120–240 min erhöhen.
Große Disks (≥ 1 TB Daten pro Disk)
- Wartungsfenster einplanen, parallele Migrations- und Lastspitzen vermeiden, MTV priorisieren
- Hohe Churn-Rate (≥100 GB zwischen Snapshots): Precopy-Intervall verkürzen und mindestens 24 h vor dem Cutover starten
- Sehr große Single-Disk-VMs: wenn Downtime möglich, cold statt warm; alternativ Daten auf mehrere Disks splitten für parallele Transfers
- Datenbanken mit Dauerschreiblast: ggf. außerhalb von MTV per DB-eigener Replikation umziehen
AIO-Messwerte & getestete Maxima
Beste Werte mit BufSizeIn64KB=16 / BufCount=4 bei 10 VMs auf einem Host: Migrationszeit −31,1 % (0:24:32 → 0:16:54), Leserate 347,83 → 504,93 MB/s. Kein Effekt bei einzelner VM oder mehreren Hosts. Getestete Cold-Maxima: 8 ESXi-Hosts, 500 VMs/Plan, 5.000 VMs gesamt, 40 Pläne parallel, 6-TB-Disk (3 TB Daten), 50 Disks pro VM. Warm: 200 VMs/Plan, 400 parallele Disk-Transfers.
Prometheus-Metriken (mtv_*)
Alle mit Labels für provider, mode (cold/warm) und target (local/remote); Netz-/Storage-Throughput ist Tech Preview:
- mtv_plans_status – aktueller Status aller Pläne (Gauge)
- mtv_migration_duration_seconds / mtv_migrations_duration_seconds – Dauer je Plan (Gauge) bzw. Histogramm über Zeitintervalle
- mtv_migration_data_transferred_bytes – übertragene Bytes je erfolgreichem Plan
- mtv_workload_migrations_status_total – Counter je Status/Plan-ID
- mtv_plan_alert_status – Fehlschläge inkl. Phase, in der es scheiterte
- mtv_migration_net_throughput / mtv_migration_storage_throughput – Live-Durchsatz laufender Pläne
Troubleshooting
Feste Eskalationsreihenfolge – und die Fehlermeldungen, die im Alltag am häufigsten auftauchen.
Diagnose-Reihenfolge
- MigrationsfortschrittVirtual-machines-Tab des Plans: welche VM hängt in welcher Phase?
- OpenShift Lightspeed fragenAb MTV 2.12 mit aktivierter Integration: Fragen in natürlicher Sprache („Why did the migration for VM X fail?").
- Pod-LogsErst ab der Konvertierungsphase vorhanden. Migration Resources → Pod → View logs.
- forklift-controller-Logs
oc logs -n openshift-mtv deployment/forklift-controller– alle MTV-Ereignisse. - must-gatherPflichtanhang für jeden Support-Case, filterbar nach Namespace, Plan oder VM.
oc adm must-gather --image=registry.redhat.io/migration-toolkit-virtualization/mtv-must-gather-rhel8:2.12.3
# gefiltert:
oc adm must-gather --image=...:2.12.3 -- PLAN=<migration_plan> /usr/bin/targeted
oc adm must-gather --image=...:2.12.3 -- VM=<vm_id> NS=<namespace> /usr/bin/targeted
Häufige Fehlermeldungen
| Meldung | Ursache & Lösung |
|---|---|
| Warm import retry limit reached | VM hat das CBT-Snapshot-Maximum (32) erreicht. Alte MTV-Snapshots im vSphere-Client löschen, Plan neu starten |
| Unable to resize disk image | EXT4 auf Block-Storage: CDI unterschätzt den Filesystem-Overhead. In der CDI-CR spec.config.filesystemOverhead.global auf > 0.10 setzen (z. B. "0.15") |
| ConnectionTestFailed (OVA) | Irreführend – erscheint auch bei korrekter Konfiguration, bevor der Provider auf Ready springt. Erst abwarten, dann prüfen |
| Error pulling VDDK image | Provider liegt außerhalb von openshift-mtv, VDDK-Image dort nicht erreichbar. Image in den Provider-Namespace bringen oder Pull-Secrets für Cross-Namespace-Zugriff einrichten |
| VDDK image required for vSAN | vSAN-Backend ohne VDDK geht grundsätzlich nicht. VDDK-Image bauen und im Provider eintragen |
| Failed to restart… taking a snapshot (Windows, warm) | Volume Shadow Copy Service (VSS) läuft nicht im Gast |
| VM name validation failed: Invalid DNS name | Punkte, Großbuchstaben, führende/abschließende Bindestriche oder >63 Zeichen. MTV benennt automatisch um – oder gezielt per targetName/Template |
Storage-Copy-Offload-Spezialfälle
- SOAP-Fehler ohne Ursache – transiente vSphere↔ESXi-Verbindungsfehler; Populator/Migration einfach neu starten
- CLI Fault: object … not found – VIB installiert, aber hostd nicht neu gestartet: per SSH auf den ESXi und
/etc/init.d/hostd restart - SSH-Fehler – SSH auf dem ESXi deaktiviert, Netzproblem, oder Timeout:
SSH_TIMEOUT_SECONDSim Provider-Secret erhöhen (z. B. 300). Prüfen:vim-cmd hostsvc/get_ssh_status - Cannot derive SVM (NetApp) – ONTAP-SVM nicht konfiguriert; Management-LIF der SVM als
STORAGE_HOSTNAMEeintragen
Was must-gather einsammelt
CRs (DataVolume, VirtualMachine, Plan, Job) plus Logs von importer-, conversion-, virt-launcher-, forklift-controller-, forklift-must-gather-api- und hook-job-Pods. Namenskonvention der Pods: <plan>-<vm_id><5_zeichen>, Importer mit Präfix importer-. Leere Logs fehlen im Archiv. Für den Self-Service Technical Supportability Review (KI-Auswertung im Customer Portal) braucht es das allgemeine Cluster-must-gather ohne --image.
Chronologisch: VMware-Cold-Migration komplett
Alle Etappen als eine Schrittfolge – vom leeren Namespace bis zur laufenden VM. Warm-Zusätze jeweils markiert.
Die vier Phasen auf einen Blick
- Phase A · VorbereitenSchritte 1–3: Quelle prüfen, Secret und Provider anlegen.
- Phase B · MappenSchritte 4–6: moRefs holen, NetworkMap und StorageMap schreiben.
- Phase C · Planen & StartenSchritte 7–8: Plan-CR, dann Migration-CR.
- Phase D · ÜberwachenSchritte 9–10: Fortschritt und Ziel-VM verifizieren.
Phase A · Vorbereiten
Schritt 1 · Quelle aufräumen
Fehlerquellen vor dem Start beseitigen, statt sie mitten in der Migration zu debuggen: Antivirus aus den Quell-VMs entfernen, vMotion/svMotion für die betroffenen VMs deaktivieren, VM-Namen auf DNS-Konformität prüfen. Für warm: CBT auf jeder VM und jeder Disk aktivieren. vSphere-Rechte auf Datacenter-Ebene mit Propagierung vergeben.
Schritt 2 · Secret anlegen
Ohne gültige Credentials kommt der Provider nie auf Ready – das Secret ist das Fundament.
cat <<'EOF' | oc apply -f -
apiVersion: v1
kind: Secret
metadata:
name: vsphere-creds
namespace: openshift-mtv
labels:
createdForProviderType: vsphere
createdForResourceType: providers
type: Opaque
stringData:
user: <user>
password: <password>
insecureSkipVerify: "false"
cacert: |
<ca_certificate>
url: https://<vCenter_host>/sdk
EOF
Schritt 3 · Provider (und Host) anlegen
Der Provider macht die Quelle für MTV sichtbar; das VDDK-Image beschleunigt jeden Transfer. Die Host-CR bindet den ESXi an das Migrationsnetz.
cat <<'EOF' | oc apply -f -
apiVersion: forklift.konveyor.io/v1beta1
kind: Provider
metadata:
name: vsphere-source
namespace: openshift-mtv
spec:
type: vsphere
url: https://<vCenter_host>/sdk
settings:
vddkInitImage: <VDDK_image>
sdkEndpoint: vcenter
secret:
name: vsphere-creds
namespace: openshift-mtv
EOF
cat <<'EOF' | oc apply -f -
apiVersion: forklift.konveyor.io/v1beta1
kind: Host
metadata:
name: esxi-01
namespace: openshift-mtv
spec:
provider:
namespace: openshift-mtv
name: vsphere-source
id: <source_host_mor>
ipAddress: <source_network_ip>
EOF
Phase B · Mappen
Schritt 4 · moRefs aus dem Inventory holen
Maps und VM-Liste referenzieren vSphere-Objekte per moRef – ohne die IDs geht nichts weiter.
TOKEN=$(oc whoami -t)
curl -H "Authorization: Bearer $TOKEN" https://<inventory_route>/providers/vsphere -k
curl -H "Authorization: Bearer $TOKEN" https://<inventory_route>/providers/vsphere/<provider_id>/datastores/ -k
Schritt 5 · NetworkMap schreiben
Jedes Quellnetz braucht ein Ziel – pod, multus (mit NAD und Namespace) oder ignored, wenn ein Netz bewusst nicht mitkommen soll.
cat <<'EOF' | oc apply -f -
apiVersion: forklift.konveyor.io/v1beta1
kind: NetworkMap
metadata:
name: vmware-netmap
namespace: openshift-mtv
spec:
map:
- destination:
name: <network_name>
type: pod
source:
id: <source_network_id>
- destination:
name: <network_attachment_definition>
namespace: <nad_namespace>
type: multus
source:
id: <source_network_id>
provider:
source:
name: vsphere-source
namespace: openshift-mtv
destination:
name: <destination_provider>
namespace: openshift-mtv
EOF
Schritt 6 · StorageMap schreiben
Datastore-moRef auf StorageClass; accessMode (ReadWriteOnce/ReadWriteMany) ist bei normalen VMware-Migrationen Pflicht.
cat <<'EOF' | oc apply -f -
apiVersion: forklift.konveyor.io/v1beta1
kind: StorageMap
metadata:
name: vmware-storagemap
namespace: openshift-mtv
spec:
map:
- destination:
storageClass: <storage_class>
accessMode: ReadWriteOnce
source:
id: <source_datastore>
provider:
source:
name: vsphere-source
namespace: openshift-mtv
destination:
name: <destination_provider>
namespace: openshift-mtv
EOF
Phase C · Planen & Starten
Schritt 7 · Plan-CR anlegen
Der Plan bündelt VMs, Maps und Verhalten. warm: false für cold; preserveStaticIPs: true, wenn Gäste statische IPs an Interface-Namen binden.
cat <<'EOF' | oc apply -f -
apiVersion: forklift.konveyor.io/v1beta1
kind: Plan
metadata:
name: vmware-plan
namespace: openshift-mtv
spec:
warm: false
provider:
source:
name: vsphere-source
namespace: openshift-mtv
destination:
name: <destination_provider>
namespace: openshift-mtv
map:
network:
name: vmware-netmap
namespace: openshift-mtv
storage:
name: vmware-storagemap
namespace: openshift-mtv
preserveStaticIPs: true
targetNamespace: <target_namespace>
vms:
- id: <vm_moref>
- name: <vm_name>
EOF
Schritt 8 · Migration-CR anlegen (Start)
Erst diese CR setzt den Plan in Bewegung. Bei warm gehört hier die Cutover-Zeit hinein – ohne sie läuft nur Precopy.
cat <<'EOF' | oc apply -f -
apiVersion: forklift.konveyor.io/v1beta1
kind: Migration
metadata:
name: vmware-migration-1
namespace: openshift-mtv
spec:
plan:
name: vmware-plan
namespace: openshift-mtv
cutover: 2026-08-10T22:00:00.000+02:00
EOF
Ab jetzt: keine Snapshots mehr auf den Quell-VMs anlegen.
Phase D · Überwachen
Schritt 9 · Fortschritt beobachten
Pro Disk entsteht ein DataVolume → PVC → Importer-Pod; danach der Conversion-Pod mit virt-v2v, dann die VirtualMachine-CR. Der Migration Controller startet die VM nur, wenn sie auch auf der Quelle lief.
oc get migration vmware-migration-1 -n openshift-mtv -o yaml
oc get pods -n <target_namespace> -w
# Logs des Conversion-Pods bei Hängern:
oc logs <conversion_pod> -n <target_namespace>
Schritt 10 · Verifizieren
Plan-Status muss auf Completed stehen; danach in der Ziel-VM prüfen, dass sie bootet, alle Disks sieht und das Netz stimmt. Der Power-State der Quelle wird übernommen – eine ausgeschaltete Quell-VM bleibt auch am Ziel aus.
oc get plan vmware-plan -n openshift-mtv -o jsonpath='{.status.conditions}'
oc get vm -n <target_namespace>