Guest CPU selection with hypervisor consideration

https://blueprints.launchpad.net/nova/+spec/cpu-selection-with-hypervisor-consideration

通过引入两个新的基于 QEMU 和 libvirt 的 CPU 配置 API:baselineHypervisorCPU()compareHypervisorCPU(),使 Nova 的 guest CPU 选择方法更有效、更可靠。与 Nova 当前使用的现有 libvirt API 相比,这些新的 API 更加“了解 hypervisor”。也就是说,新的 API 会考虑“host hypervisor”(即:KVM、QEMU 以及 libvirt 了解的主机)的功能。

利用这些较新的 API,Nova 在确定不同主机上兼容的 CPU 模型时,可以做出更明智的决策。

问题描述

Nova 当前使用的 libvirt guest CPU 配置 API,compareCPU()baselineCPU(), “用处不大”(引用引入较新 API 的 libvirt 补丁系列的介绍信 [1]),因为它们没有考虑“host hypervisor”(KVM、QEMU 以及 libvirt 了解的主机)的功能。更具体地说,使用现有的 API,compareCPU()baselineCPU(),无法询问给定的 CPU 模型加上 CPU flags 组合是否受主机上的 KVM 和特定 QEMU 二进制文件支持。

例如,目前操作员必须小心地配置 libvirt 驱动程序,关于 cpu_modelcpu_model_extra_flags,因为错误的组合(例如,host hypervisor 不支持的无效 CPU flag)可能导致实例无法启动。也就是说,操作员必须手动验证他们提供给 Nova 的额外的 CPU flags 是否确实受给定的计算主机支持。

本 spec 将允许 Nova [2] 对给定的 CPU 模型加上 CPU flags,针对特定的 QEMU 二进制文件(以及 KVM)进行细粒度验证,从而做出明智的 guest CPU 配置决策。并且,利用这两个新的 libvirt API 还可以计算更准确的 baseline guest CPU,从而允许在多个计算节点之间进行实时迁移。并更清晰地了解获得 Meltdown 和 Spectre 缓解措施所需的 CPU 功能。

用例

通过利用这两个 CPU 配置 API,baselineHypervisorCPU()compareHypervisorCPU(),Nova 现在可以做出有意义的决策,以确定 guest CPU 模型及其功能

  • 在确定 guest CPU 模型时,Nova 可以考虑其他几个方面,例如虚拟化的类型(纯模拟与硬件加速)、QEMU 二进制文件的功能、guest 机器类型和 CPU 架构,以构建更完善的 guest CPU。

  • Nova 能够对 CPU 模型和 flags 进行更细粒度的验证,即回答诸如:“Intel 的 IvyBridge CPU 模型加上 CPU flags pcidssbd 的组合是否受 host hypervisor 支持?”

  • 凭借以上两点,Nova 还可以更好地报告更准确的 CPU 特性。(即,改进 _get_cpu_traits() 方法。)

  • 操作员可以更准确地了解他们的 guest 可以现实地期望的 CPU 模型和功能。

提议的变更

通过利用两个新的 libvirt API:baselineHypervisorCPU()compareHypervisorCPU() [3],使 Nova 的 CPU 选择策略更有效。这些 API 提供了更有效的方法来确定 CPU 变体之间的兼容模型,并消除了旧的 CPU 配置 libvirt API 中的错误。

通过此更改,libvirt 驱动程序将自动验证某个 CPU 模型 + flags 组合是否可以在给定的计算主机上工作——例如,Nova 现在可以回答:“‘IvyBridge’加上 CPU flags ‘pcid’ & ‘pdpe1gb’ 的组合是否受主机上的 KVM、QEMU 和 libvirt 支持?”如果给定的 CPU 模型加上 flags 组合无效,nova-compute 服务将拒绝启动,并提供可操作的日志消息。

这将允许操作员设置 CPU 模型加上 flags,并让 Nova 处理验证。

这两个 API 的简要描述

baselineHypervisorCPU()

目的:此 API 计算最丰富的“baseline”CPU(包括 CPU 模型加上附加功能),该 CPU (a) 与所有给定的 host CPU 兼容(如 XML 文档中所述),以便可以在所述 host 之间进行实时迁移;并且 (b) 受 host hypervisor 支持。它是旧的 baselinCPU() 的一个更有用的版本,后者在计算 baseline CPU 时不考虑任何 hypervisor 功能。

在考虑参数时,baselineCPU()baselineHypervisorCPU() API 的比较

+-----------+--------------------+-----------------------------+
|           | baselineCPU()      | baselineHypervisorCPU()     |
+-----------+--------------------+-----------------------------+
|           | XML document       | XML document describing     |
|           | describing one     | one or more host CPUs       |
|           | or more host CPUs  |                             |
|           +--------------------+-----------------------------+
|           |                    | path to the QEMU binary     |
|           |                    +-----------------------------+
|Parameters |                    | the type of virtualization  |
|           |                    | (e.g. KVM, QEMU)            |
|           |                    +-----------------------------+
|           |                    | guest machine type          |
|           |                    +-----------------------------+
|           |                    | CPU architecture            |
+-----------+--------------------+-----------------------------+
compareHypervisorCPU()

目的:此 API 将给定的 CPU 描述与 host hypervisor 能够提供的 CPU 功能进行比较。它是现有 compareCPU() 的一个更有用的版本,后者将 CPU 定义与 host CPU 进行比较,而不考虑任何特定的 hypervisor 及其能力。

在考虑参数时,compareCPU()compareHypervisorCPU() API 的比较

+-----------+--------------------+-----------------------------+
|           | compareCPU()       | compareHypervisorCPU()      |
+-----------+--------------------+-----------------------------+
|           | XML describing the | XML describing the CPU      |
|           | CPU to be compared | to be compared              |
|           +--------------------+-----------------------------+
|           |                    | path to the QEMU binary     |
|           |                    +-----------------------------+
|Parameters |                    | the type of virtualization  |
|           |                    | (e.g. KVM, QEMU)            |
|           |                    +-----------------------------+
|           |                    | guest machine type          |
|           |                    +-----------------------------+
|           |                    | CPU architecture            |
+-----------+--------------------+-----------------------------+

通过让 Nova 使用上述两个 API,它现在可以对 CPU 模型加上 flags 兼容性进行更高级的验证,从而确保无法使用主机 CPU 中不存在的 CPU 功能启动实例。

备选方案

我们可以“原地不动”并继续使用现有的旧 libvirt API,baselineCPU()compareCPU()

但这将对我们的用户造成损害,因为我们拥有更可靠的 API,可以提供更完善的 guest CPU 配置。

数据模型影响

无。

REST API 影响

无。

安全影响

这隐式地提高了安全性——也就是说,使用这些新的 API,您应该能够更好地了解获得 Meltdown 和 Spectre 缓解措施所需的 CPU 功能。

通知影响

无。

其他最终用户影响

无。

性能影响

无。

其他部署者影响

以下 libvirt 和 QEMU 版本

  • 对于 x86_64:QEMU >= 2.9,libvirt >= 4.4.0

  • 对于 s390x:QEMU >= 2.9,libvirt 工作正在上游积极进行中 [4]

开发人员影响

无。

升级影响

对于 x86_64,用户应该具有 libvirt 和 QEMU 的最低所需版本分别为 4.4.0 和 2.9。

实现

负责人

主要负责人

<kashyapc>

工作项

  • 为 libvirt 的 baselineHypervisorCPU() API 引入 Nova 包装方法 baseline_hypervisor_cpu()。

  • 为 libvirt 的 compareHypervisorCPU() API 引入 Nova 包装方法 compare_hypervisor_cpu()。

  • 重构 libvirt 驱动程序中的 _get_guest_cpu_model_config() 方法,以便利用对 CPU 模型加上功能的细粒度验证(针对给定的 QEMU 二进制文件),如果给定计算主机上可用。

  • 重写 libvirt 驱动程序中 _compare_cpu() 方法的逻辑,以利用 compareHypervisorCPU()。(顺便说一句,将其重命名为 _compare_hypervisor_cpu()。)

  • 更新 libvirt 驱动程序中的 check_can_live_migrate_destination() 方法,以使用新的包装 API。

  • 更新 nova/virt/libvirt/host.py 中的 get_capabilities() 方法,以利用 baseline_hypervisor_cpu(),如果给定计算主机上可用。

  • 可以单独完成,但为了完整起见而说明:更新 _get_cpu_traits() 方法以使用 baselineHypervisorCPU()。(s390x 的支持不应阻止开始此操作。)

依赖项

这不是严格的依赖项,但如前所述,libvirt 的 compareHypervisorCPU() 和 baselineHypervisorCPU() 的 s390x 支持仍在上游进行中。

测试

  • 为 baselineHypervisorCPU() 和 compareHypervisorCPU() API 引入“假 libvirt”方法,具有最低所需的功能(因为复制 libvirt 的逻辑很复杂,并且复制它不会增加太多价值)。

  • 单元测试。

  • 可能需要几个功能测试。

文档影响

考虑在 Nova 管理指南中添加一个部分,介绍新的 API 如何实现更可靠的 guest CPU 配置。并明确指出我们建议坚持使用 host-model,这是 libvirt 驱动程序的默认 CPU 模式。

参考资料

历史

修订

发布名称

描述

Train

引入