Live‑Migrating VMs in Harvester: How It Works and What to Watch For
A step‑by‑step look at Harvester’s live migration feature, including prerequisites, a sample migration command, verification steps, and the key trade‑offs you need to consider before moving a running VM.
20 Feb 2026, 18:41 UTC

Why live migration matters in Harvester
Harvester builds on KubeVirt to run virtual machines inside Kubernetes. One of its most useful day‑to‑day operations is live migration: moving a running VM from one cluster node to another without powering it off. This lets you drain a node for maintenance, balance workloads, or respond to hardware issues while keeping the VM’s memory and device state intact.
What makes live migration possible
Two core requirements enable the feature:
- Shared storage – The VM’s disk image must be accessible from both the source and destination nodes. Harvester officially supports Longhorn (its built‑in CSI driver) or any NFS export that is mounted with the same
ReadWriteManyaccess mode on all nodes. - CPU compatibility – The source and destination nodes must expose the same CPU vendor and feature set to QEMU/KVM. If the CPUs differ, libvirt will refuse the migration unless you enable CPU mode
host-passthroughwith identical flags, which is rarely practical in a heterogeneous cluster.
When these conditions are satisfied, Harvester triggers KubeVirt’s live‑migration workflow: memory pages are copied over the network, dirty pages are re‑sent until convergence, and finally the VM is paused briefly to switch over to the destination host.
Starting a migration – UI, CLI, or kubectl
You can initiate a migration in three ways:
- UI – In the Harvester dashboard, open the VM’s detail page, click the “Migrate” button, and select a target node from the list.
- CLI (harvesterctl) – Run
harvesterctl vm migrate --nodefrom a workstation where the Harvester CLI is installed. - kubectl patch – Patch the VM’s
spec.runStrategytoAlwaysand setspec.migrationNodeNameto the desired node:
kubectl patch vm example-vm -n harvester-system --type merge -p '{\"spec\":{\"migrationNodeName\":\"worker-2\"}}'
The command returns immediately; the actual move happens asynchronously.
Verifying that the migration succeeded
After triggering the move, check the VM’s status in any of the following places:
- Harvester UI – The VM’s detail pane shows a “Migration” condition. It will first read
MigrationScheduled, thenMigrationInProgress, and finallyMigrationSucceededwhen the process ends. - kubectl – Inspect the VM object:
kubectl get vm example-vm -n harvester-system -o yaml | grep -A5 status.migrationState
Look for targetNodeName: worker-2 and completed: true.
/var/log/libvirt/qemu/.log. You should see lines like:
migration start: ...
migration completed: ...
If the logs contain “migration failed” or the UI shows a condition with reason MigrationFailed, the migration did not complete.
Trade‑offs and practical limits
Live migration is not free. The primary limiting factors are:
- Network bandwidth – Memory pages must be transferred while the VM stays running. Harvester recommends a minimum of 10 Gbps between nodes for production workloads; lower speeds increase migration time and raise the chance of a timeout, which triggers a fallback to a stop‑start migration (brief downtime).
- VM memory size – Larger VMs need more time to converge. You can estimate migration duration as roughly
(memory size) / (effective bandwidth)plus a few seconds for dirty‑page rounds. - Device passthrough – GPUs, NICs, or other hardware exposed via VFIO are not moved unless an identical device is present and configured on the target node. If you rely on such passthrough, verify compatibility beforehand or plan for a scheduled reboot.
To check whether your network is sufficient, run a simple bandwidth test between two nodes (e.g., iperf3 -c -t 10) and compare the result to the 10 Gbps guideline.
Actionable checklist before you migrate
- Confirm shared storage is reachable from all candidate nodes (
kubectl get pvshowsReadWriteMany). - Verify CPU uniformity:
lscpuoutput should match on source and destination, or use a custom CPU model in the VM’s spec that is present on both. - Ensure the inter‑node network meets the bandwidth target; run a quick iperf3 test if unsure.
- If the VM uses VFIO devices, validate that the same device IDs exist on the target node.
- Trigger the migration via your preferred method and watch the UI or
kubectl get vmfor theMigrationSucceededcondition. - After migration, verify the VM is responsive (e.g., SSH or application health check) and that the
spec.migrationNodeNamereflects the new host.
When all checks pass, you can safely use live migration to keep services running while you maintain the underlying Harvester cluster.
0 replies
A thoughtful contribution can make all the difference. Be the first to share one.