Skip to content

docs, virtual hardware: explain how the CPU model affects live migration - #1052

Open
fjvbn2003 wants to merge 2 commits into
kubevirt:mainfrom
fjvbn2003:cpu-model-live-migration
Open

fjvbn2003 wants to merge 2 commits into
kubevirt:mainfrom
fjvbn2003:cpu-model-live-migration

Conversation

@fjvbn2003

Copy link
Copy Markdown
Contributor

What this PR does / why we need it:

The user guide introduces host-model and host-passthrough in docs/compute/virtual_hardware.md, but it does not say how the CPU model affects live migration. docs/compute/live_migration.md has no CPU item under Limitations either. As a result, a host-model VMI (the default when no model is set) can report LiveMigratable: True and then fail to migrate after 5 minutes, and nothing in the docs explains why.

This PR adds a "CPU model and live migration" subsection under "CPU model special cases":

  • a table of the node selectors KubeVirt adds to the migration target pod for a named model, host-model and host-passthrough,
  • the LiveMigratable condition does not consider the CPU, and what the failure looks like,
  • host-model: same host model name, different required features, and which labels to compare,
  • host-passthrough: only the vendor is checked, so use it only with identical CPUs,
  • a named model that all nodes support as the way to migrate between different CPUs, and that model names are not validated (links Kubevirt does not validate CPU model kubevirt#16854).

Sources (kubevirt v1.9.0, pkg/virt-controller/watch/migration/migration.go):

  • L965-984: for host-model, prepareNodeSelectorForHostCpuModel adds the selectors.
  • L2528-2552: a host-model VMI that has already migrated reuses the cpu-feature/cpu-model-migration selectors of its current pod.
  • L2554-2578: getHostCpuModelFromMap turns host-model-cpu.node.kubevirt.io/<model> into cpu-model-migration.node.kubevirt.io/<model> and each host-model-required-features.node.kubevirt.io/<f> into cpu-feature.node.kubevirt.io/<f>.
  • L986 onwards: the cpu-vendor selector is added for every model ("Ensure migration happens only between nodes with the same CPU vendor").
  • L86: defaultUnschedulablePendingTimeoutSeconds = 60 * 5.

What I measured on a test cluster (KubeVirt v1.9.0, Kubernetes 1.36, two workers on different Intel CPU generations; both nodes report host model SierraForest):

VMI CPU model LiveMigratable Target pod node selectors (CPU part) Result
host-model True cpu-model-migration.node.kubevirt.io/SierraForest, 27 cpu-feature.node.kubevirt.io/*, cpu-vendor.node.kubevirt.io/Intel Target pod Unschedulable (didn't match Pod's node affinity/selector). Deleted after 5 min, migration failed. The other node lacked cpu-feature labels for ddpd-u and rfds-no, which were in the source node's required features.
host-passthrough True cpu-vendor.node.kubevirt.io/Intel Succeeded (about 7 s) between the two different CPUs
Skylake-Client-v4 True cpu-model.node.kubevirt.io/Skylake-Client-v4, cpu-vendor.node.kubevirt.io/Intel Succeeded
Cascadelake-Server-v5 (no node has it) n/a cpu-model.node.kubevirt.io/Cascadelake-Server-v5 The VMI never started; its pod stayed Pending

The nodes in this test are nested VMs. That changes which features the nodes report, but not how KubeVirt builds the selectors from the labels.

I did not build the site locally. The table uses the same Markdown table syntax as other pages (for example user_workloads/vm_templates.md).

Special notes for your reviewer:

I put this in virtual_hardware.md and not in live_migration.md because three open PRs (#1020, #1024, #1026) are editing live_migration.md. If you would like a short pointer from the Limitations list in live_migration.md, I can add it after those are merged.


Prepared with help from Claude (AI); the measurements come from my own nested test cluster.

The CPU model decides which node selectors KubeVirt puts on the migration
target pod: the model label for a named model, the host model and the
source node's required features for host-model, and only the vendor for
host-passthrough. None of this is part of the LiveMigratable condition, so
a VMI can report LiveMigratable True and still fail to migrate because the
target pod stays unschedulable.

Add a section with the selectors per model, the host-model and
host-passthrough pitfalls, and using a named model to migrate between nodes
with different CPUs.

Signed-off-by: YoungjuKim <[email protected]>
Assisted-by: Claude <[email protected]>
@kubevirt-prow kubevirt-prow Bot added the dco-signoff: yes Indicates the PR's author has DCO signed all their commits. label Oct 30, 2026
@kubevirt-prow kubevirt-prow Bot added the needs-ok-to-test Indicates a PR that requires an org member to verify it is safe to test. label Oct 30, 2026
@kubevirt-prow

kubevirt-prow Bot commented Oct 30, 2026

Copy link
Copy Markdown

Hi @fjvbn2003. Thanks for your PR.

I'm waiting for a kubevirt member to verify that this patch is reasonable to test. If it is, they should reply with /ok-to-test on its own line. Until that is done, I will not automatically test new commits in this PR, but the usual testing commands by org members will still work.

Tip

We noticed you've done this a few times! Consider joining the org to skip this step and gain /lgtm and other bot rights. We recommend asking approvers on your previous PRs to sponsor you.

Once the patch is verified, the new status will be reflected by the ok-to-test label.

I understand the commands that are listed here.

Details

Instructions for interacting with me using PR comments are available here. If you have questions or suggestions related to my behavior, please file an issue against the kubernetes-sigs/prow repository.

@kubevirt-prow kubevirt-prow Bot added the size/M label Oct 30, 2026

@dhiller dhiller left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@fjvbn2003 sound like a reasonable addition to the user guide, however the details are above me, so I'd ask @jean-edouard or @iholder101 to either take a closer look or forward this further.\

/approve

@kubevirt-prow

kubevirt-prow Bot commented Nov 3, 2026

Copy link
Copy Markdown

[APPROVALNOTIFIER] This PR is APPROVED

This pull-request has been approved by: dhiller

The full list of commands accepted by this bot can be found here.

The pull request process is described here

Details Needs approval from an approver in each of these files:

Approvers can indicate their approval by writing /approve in a comment
Approvers can cancel approval by writing /approve cancel in a comment

@kubevirt-prow kubevirt-prow Bot added the approved Indicates a PR has been approved by an approver from all required OWNERS files. label Nov 3, 2026

@dhiller dhiller left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Caution: AI generated review

Reviewed the added documentation for English wording and technical correctness against KubeVirt v1.9.0. The inline comments cover three factual corrections: the scope of the LiveMigratable CPU check, the destination labels used to determine host-model compatibility, and the timeout's default value and starting point. There is also one non-blocking English wording suggestion. Each comment includes proposed replacement text.

🤖 Assisted by Kilo using model openai/gpt-6.1-sol

Comment thread docs/compute/virtual_hardware.md Outdated
Comment on lines +291 to +292
- The `LiveMigratable` condition does not take the CPU into account. A VMI
can report `LiveMigratable: True` while no other node can run its CPU.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[P2] Correctness: narrow this to destination compatibility. The condition does take the CPU into account: calculateLiveMigrationCondition calls isHostModelMigratable, which rejects a host-model VMI when the host CPU model is unavailable, using reason CPUModeNotMigratable (v1.9.0 source, check implementation). What it does not establish is whether another node satisfies the CPU requirements.

Suggested change
- The `LiveMigratable` condition does not take the CPU into account. A VMI
can report `LiveMigratable: True` while no other node can run its CPU.
- The `LiveMigratable` condition does not verify that another node satisfies
the VMI's CPU model and feature requirements. A VMI can report
`LiveMigratable: True` even when no other node meets those requirements.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You're right, thanks. isHostModelMigratable does check the source side: a host-model VMI gets CPUModeNotMigratable when the source node has no host CPU model (vm.go L1255-L1257, L2441-L2451; same on main). It does not check the destination. I applied your wording in 4468901.

I also added one sentence: when no other node has the required labels for a host-model VMI, virt-controller records a NoSuitableNodesForHostModelMigration warning event on the VMI (migration.go L2482-L2516). In my test cluster that event appeared on the VMI in the same second the target pod was created. I can drop the sentence if you'd rather keep this item short.

(Written with help from Claude (AI).)

Comment thread docs/compute/virtual_hardware.md Outdated
Comment on lines +302 to +305
VMI started on the source node cannot be migrated there. Compare the
`host-model-cpu.node.kubevirt.io/*` and
`host-model-required-features.node.kubevirt.io/*` labels of your nodes to
see where a VMI can go.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[P2] Correctness: compare the migration selectors with the destination's compatibility labels, not the host-model identity and required-feature labels across nodes. The destination can have a different host model and still support the source model. KubeVirt translates the source's host-model and required-feature labels into cpu-model-migration.* and cpu-feature.* selectors (v1.9.0 source). The current instruction can incorrectly rule out suitable destinations. The replacement also makes the referent of "there" explicit.

Suggested change
VMI started on the source node cannot be migrated there. Compare the
`host-model-cpu.node.kubevirt.io/*` and
`host-model-required-features.node.kubevirt.io/*` labels of your nodes to
see where a VMI can go.
VMI started on the source node cannot be migrated to that other node.
To identify compatible destinations, check that each candidate node has
labels matching the migration target pod's
`cpu-model-migration.node.kubevirt.io/<model>`,
`cpu-feature.node.kubevirt.io/<feature>`, and
`cpu-vendor.node.kubevirt.io/<vendor>` selectors. For a VMI that has
already migrated, use its current pod's CPU selectors rather than
deriving new requirements from its current node's host-model labels.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Agreed, the old instruction was wrong. The node-labeller sets cpu-model-migration.node.kubevirt.io/<model> for every model the node knows, not just its own host model (node_labeller.go L258-L260). So a node with a different host model can still be a valid destination. I checked this against the labels I saved from my nodes: every node with a different host model still had the cpu-model-migration label for the other nodes' host model. Applied your wording in 4468901. It also matches the check in alertIfHostModelIsUnschedulable.

(Written with help from Claude (AI).)

Comment thread docs/compute/virtual_hardware.md Outdated
Comment on lines +294 to +295
`didn't match Pod's node affinity/selector` scheduling message, and the
migration fails once the target pod has been unschedulable for 5 minutes.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[P3] Correctness: five minutes is the default timeout, and its clock starts at target-pod creation, not when the pod first becomes unschedulable. The controller uses timeSinceCreationSeconds and supports an annotation override (timeout accounting, override handling). Qualifying the default avoids promising a fixed five-minute unschedulable interval.

Suggested change
`didn't match Pod's node affinity/selector` scheduling message, and the
migration fails once the target pod has been unschedulable for 5 minutes.
`didn't match Pod's node affinity/selector` scheduling message. By
default, the migration fails if the target pod is still unschedulable
five minutes after the pod was created.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Agreed. The timeout is the default defaultUnschedulablePendingTimeoutSeconds, and handlePendingPodTimeout measures it from the target pod's CreationTimestamp (L1717-L1758). In my run the pod was created and reported unschedulable in the same second, so the measurement could not tell the two apart. Applied your wording in 4468901.

(Written with help from Claude (AI).)

Comment thread docs/compute/virtual_hardware.md Outdated
Comment on lines +274 to +275
The CPU model decides which nodes a VMI can be live migrated to. KubeVirt
adds node selectors to the migration target pod based on the model:

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: "Determines" is more natural than "decides" for a configuration value. Rephrasing also avoids the awkward "can be live migrated to" construction and clarifies that this paragraph concerns CPU compatibility, not every prerequisite for migration.

Suggested change
The CPU model decides which nodes a VMI can be live migrated to. KubeVirt
adds node selectors to the migration target pod based on the model:
The CPU model determines CPU compatibility with potential live migration
destinations. KubeVirt adds node selectors to the migration target pod
based on the model:

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Applied as suggested in 4468901.

(Written with help from Claude (AI).)

Address review feedback on the CPU model and live migration section.

LiveMigratable does look at the CPU for host-model: virt-handler reports
CPUModeNotMigratable when the source node has no host CPU model. What it
does not check is whether another node can take the VMI, so say that.

A destination is suitable when its labels match the target pod's
cpu-model-migration, cpu-feature and cpu-vendor selectors. The node
labeller sets cpu-model-migration for every model the node knows, so a
node with a different host model can still be a valid destination.
Comparing host-model-cpu labels between nodes is therefore wrong.

The five minute limit is the default, and it counts from the creation of
the target pod. Also mention the NoSuitableNodesForHostModelMigration
warning event that virt-controller records on the VMI in this case.

Signed-off-by: YoungjuKim <[email protected]>
Assisted-by: Claude <[email protected]>
@fjvbn2003

Copy link
Copy Markdown
Contributor Author

Thanks for the review, @dhiller. I addressed all four comments in 4468901 as a separate commit so the changes are easy to review. I'm happy to squash it before merge.

@iholder101 @jean-edouard, could one of you take a look at the CPU model details when you have time?

(Written with help from Claude (AI).)

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

approved Indicates a PR has been approved by an approver from all required OWNERS files. dco-signoff: yes Indicates the PR's author has DCO signed all their commits. needs-ok-to-test Indicates a PR that requires an org member to verify it is safe to test. size/M

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants