Virt 镜像属性启动时间覆盖

https://blueprints.launchpad.net/nova/+spec/virt-image-props-boot-override

此规范扩展 Nova 启动 API,以便在实例创建时覆盖任何镜像元数据属性。这避免了为了在特殊用例中设置略有不同的属性而多次将相同的镜像上传到 Glance 的需要。

问题描述

Nova 具有使用 Glance 中记录的各种元数据属性的能力,以定制实例在启动时的配置方式。例如,它可以自定义暴露的硬件设备类型,设置特定的 NUMA 拓扑,或指定内核命令行参数。

这通常效果很好,但有很多场景需要使用各种不同的属性启动相同的镜像。目前处理这种情况的唯一方法是将相同的镜像多次上传到 Glance,并为每次上传设置不同的属性。这根本无法扩展,尤其是在需要为每个启动的实例使用不同的属性时。

用例

租户用户可能希望将 Nova 计算作为服务用于构建磁盘镜像。这将涉及在虚拟实例中运行操作系统安装程序,例如 Fedora 的 Anaconda。有两种方式可以启动此类安装程序。首先,它们可以从 CDROM 启动,在这种情况下,租户用户会看到一个交互式 BIOS 控制台,可以在其中自定义安装程序使用的内核启动参数。其次,它们可以从 kernel+initrd 启动,在这种情况下,可以以编程方式传递内核启动参数。如果希望实现安装过程的任何程度的自动化,则需要后者方法。这需要能够以每个实例为基础自定义内核参数。

具有 NFV 应用程序的租户用户希望对虚拟硬件策略的各个方面进行精细控制,特别是 NUMA、hugepages 和 CPU pinning 策略的使用。虽然他们使用的一些镜像具有要应用的标准策略,但通常希望在实例启动时更改策略的某些方面,以适应特定的部署需求。例如,根据他们启动的资源关联风味的大小,他们可能希望使用不同的 hugepage 大小,或创建不同数量的 NUMA 节点。

提议的变更

Nova 启动 API 将扩展以包含一个新参数,该参数接受一个字典参数。此字典中的键将与 nova.objects.ImageMetaProps 对象字段允许的键匹配。

在 Nova 计算管理器中,镜像的元数据属性将通过启动 API 提供的属性进行扩充/覆盖。此合并后的属性集将记录为实例的镜像系统元数据。这样,无需对 virt 驱动程序中的下游代码进行任何更改。virt 驱动程序将自动看到每个实例自定义的集合。

Nova 客户端 API 将扩展以允许将这些新参数传递给 API,并且 shell 将获得一个新的 –image-prop-override 参数来设置此参数

nova boot \
    --image IMAGE-ID \
    --image-prop-override "hw_os_command_line=console=ttyS0" \
    --image-prop-override "hw_numa_nodes=2" \
    --flavour m1.small \
    ...other args...

备选方案

与其允许任意覆盖镜像元数据属性,不如可以定义启动时间 API 的一组较小的允许属性。这种方法的目的是具有更严格的实例自定义。这种方法的问题在于决定在启动时间允许覆盖哪些属性。这可能会导致用户不断请求添加支持“仅再一个”属性。因此,仅允许覆盖 ImageMetaProps 对象定义的任何属性被认为更简单。

与其进行镜像元数据属性覆盖,不如特殊处理所需的功能。例如,启动 API 可以获得一个新的“内核命令行”参数。这将非常小众,并且最终需要向启动 API 添加许多额外的参数来涵盖所有场景。这反过来会导致计算管理器和 virt 驱动程序中更多的特殊情况代码。只需自定义现有的已定义镜像元数据属性,则要简单得多。

为 Glance 添加支持软克隆和引用计数的功能,以便能够以低成本创建具有不同元数据的多个镜像,所有镜像共享相同的底层内容。这在某些场景下可能很有用,您将重复使用相同的镜像元数据属性集来启动多个 VM。当您在每次启动尝试时都使用完全一次性的镜像元数据属性时,每次在 Glance 中创建然后删除镜像对用户来说是不必要的负担。

什么都不做始终是一种选择。在这种情况下,租户用户将不得不继续使用当前的解决方法,即上传同一镜像的多个副本并为每个副本设置不同的属性。Glance 可能会增强其功能,以识别何时上传了相同的镜像内容并取消重复磁盘空间。但是,对于用户来说,这仍然是一种繁琐的方法,尤其是在每个实例都需要略微不同的覆盖时,例如在使用 Nova 自动运行发行版 OS 安装程序时。

数据模型影响

计算管理器启动代码将从启动 API 获取新参数,并将它们合并到存储在系统元数据表中的现有镜像元数据字典中。因此,不需要新的存储。

REST API 影响

‘/servers’ 位置上的 POST 方法将扩展以获得一个新的 ‘image_props_override’ 参数。这将是一个简单的键/值字符串字典。允许的键将是 nova.objects.ImageMetaProps 对象允许的任何键。

以先前的 ‘nova boot’ 示例为例,传递到请求中的 JSON 如下所示

{
    'server' : {
        'accessIPv4': '1.2.3.4',
        'accessIPv6': '80fe::',
        'name' : 'new-server-test',
        'imageRef' : 'http://glance.openstack.example.com/images/70a599e0-31e7-49b7-b260-868f441e862b',
        'flavorRef' : 'http://openstack.example.com/flavors/1',
        'metadata' : {
          'My Server Name' : 'Apache1'
        },
        'image_props_override' : {
          'hw_os_command_line' : 'console=ttyS0',
          'hw_numa_nodes' : '2',
        }
    }
}

这将需要一个新的 API 微版本

安全影响

Glance 具有设置镜像属性保护的功能,以防止租户用户在镜像上设置特定属性。由于镜像属性覆盖完全在 Nova 中完成,因此 Glance 的访问控制规则对此不可见。为了解决这个问题,将提供一个 nova.conf 属性,该属性用于白名单/黑名单可以在实例启动时覆盖哪些属性。

通知影响

其他最终用户影响

Nova 客户端 API 将支持新参数,并且 ‘boot’ shell 命令将获得一个 ‘–image-prop-override’ 参数来指定镜像属性覆盖。

性能影响

其他部署者影响

当管理员在 Glance 中设置属性保护时,他们还需要考虑是否需要更新 nova.conf 属性覆盖白名单。

开发人员影响

实现

负责人

主要负责人

berrange

其他贡献者

工作项

  • 扩展 Nova 服务器资源创建方法以接受新参数

  • 扩展 Nova 计算管理器以将启动时间覆盖与镜像元数据属性合并,并将结果存储在系统元数据中

  • 扩展 python nova 客户端以传递新参数

依赖项

这取决于计算管理器转换为使用 ImageMetaProps 对象,该对象正在完成中

测试

需要新的 Tempest 测试来启动具有镜像元属性覆盖的客户机,并验证客户机配置是否相应更改。

文档影响

需要记录新的 Nova 客户端 ‘boot’ 命令参数

参考资料

以前相关的蓝图

此蓝图源自对先前规范的反馈,这些规范被认为过于特殊化和过于通用。