最稳妥的选择是custom模式,因其主动收窄暴露给虚拟机的指令集以保障跨不同型号宿主机(如E5-2680 v3/v4)热迁移兼容性;host-passthrough因透传全部CPU flag易因目标机缺失任一特性而失败;需严格按cpu_map.xml选用Haswell-noTSX等稳定model并禁用hle、rtm等高危扩展,同时统一宿主机微码版本。

热迁移失败最常卡在 CPU 指令集不兼容上,custom 模式是跨不同型号宿主机(比如 Intel Xeon E5-2680 v3 和 v4)做热迁移时最稳妥的选择——它主动收窄暴露给虚拟机的指令集,而不是靠运气碰源/目标 CPU 的兼容性。
为什么不能直接用 host-passthrough 做热迁移
因为 host-passthrough 会把宿主机 CPU 的所有 feature flags(比如 avx512f、sha_ni、movdir64b)原样透传给虚拟机。一旦目标宿主机缺失其中任意一个 flag,迁移就会在最后阶段报错:internal error: unable to serialize domain state for migration 或直接卡在 migration: waiting for destination to accept。这不是配置问题,是硬件事实不匹配。
custom 模式下怎么选 CPU model 才真正兼容
不能随便填个名字就完事。必须从 /usr/share/libvirt/cpu_map.xml 里挑一个已知稳定、指令集收敛的命名模型,并显式关闭所有高版本扩展。常见安全组合如下:
- 对 Intel 平台,优先用
Skylake-Client-noTSX或Haswell-noTSX:它们默认禁用 TSX(Transactional Synchronization Extensions),而 TSX 在很多老 BIOS 或微码更新不全的机器上是不稳定来源 - 避免用
qemu64或pentium3:前者在新 QEMU 版本中已被标记为 deprecated;后者缺少基本的 PAE 支持,启动时会报unsupported configuration: CPU does not support PAE - 必须加
require='no'属性,否则 libvirt 会强制校验宿主机是否支持该 model——这反而破坏了custom的“向下兼容”本意
XML 片段示例(嵌入 <cpu></cpu> 节点内):
<cpu mode='custom' match='exact'> <model fallback='forbid'>Haswell-noTSX</model> <feature policy='disable' name='hle'/> <feature policy='disable' name='rtm'/> <feature policy='disable' name='avx512f'/> </cpu>
libvirt_cpu_mode 和 libvirt_cpu_model 在 OpenStack Nova 中怎么配
OpenStack 不直接操作 XML,而是通过 nova.conf 控制全局策略。关键不是写死 model 名,而是让 nova-compute 启动时生成的 XML 自动套用你指定的 custom 配置:
- 设置
libvirt_cpu_mode = custom:强制所有新建虚拟机走 custom 流程 - 设置
libvirt_cpu_model = Haswell-noTSX:注意这里不能带后缀如-noTSX的拼写错误,大小写和连字符必须与cpu_map.xml完全一致 - 必须同步设置
libvirt_cpu_config_extra = feature=+vmx,feature=-hle,feature=-rtm:这是唯一能批量禁用特定 feature 的方式;+表示启用(如强制透传vmx),-表示禁用 - 改完后重启
nova-compute服务,再创建虚拟机,用virsh dumpxml <vm-name> | grep -A5 '<cpu> 验证是否生效</cpu></vm-name>
真正容易被忽略的是微码(microcode)版本差异:同一款 CPU 型号,宿主机 BIOS 更新过微码后可能新增或移除某些 feature flag,导致 custom 模式下仍出现迁移失败。所以生产环境务必统一宿主机 BIOS 和 microcode 版本,别只盯着 libvirt 配置。

















