RAID 配置的新驱动程序接口

https://bugs.launchpad.net/ironic/+bug/1526400

该提案介绍了创建 RAID 配置新驱动程序接口所需的工作。它还提出了一种方法,使 RAID 配置作为 zapping 或 cleaning 的一部分可用。

注意

虽然 RAID 配置适合 zapping,但它也可以用作 cleaning 的一部分。Zapping 和 cleaning 遵循类似的机制(zap 步骤是优先级为 0 的 clean 步骤)。对于软件 RAID(其中安全磁盘擦除也会擦除磁盘上的软件 RAID 配置),将 RAID 配置作为 cleaning 的一部分是有意义的。由操作员决定 RAID 配置是否应作为 zapping 或 cleaning 的一部分,并且它将在实现它的驱动程序中可配置。

问题描述

  • 目前 Ironic 中没有支持 RAID 配置的功能。

  • 此特定任务集需要在驱动程序上使用单独的接口。新的 RAID 接口将允许操作员为节点指定 RAID 配置。不同的驱动程序可以为操作员提供相同的 RAID 配置接口。

提议的变更

  • 在节点注册后,并且可用的基本硬件信息后,操作员可以定义 RAID 配置。此配置将在 zapping 或 cleaning 期间应用。

  • 操作员可以通过 REST API 或 CLI 以 JSON 数据形式将 RAID 配置信息传递给 Ironic 驱动程序。RAID 配置信息将包含每个逻辑磁盘的属性,以及可选的提示,以供 Ironic 查找所需的后端物理磁盘。

    属性可以分为 4 种不同的类型

    1. 强制属性 - 这些属性必须为每个逻辑磁盘指定,并且没有默认值。

      • size_gb - 要创建的逻辑磁盘的大小(以 GiB 为单位)。如果逻辑磁盘应使用后端物理磁盘上所有可用空间,则可以指定 MAX。仅当指定了后端物理磁盘时(如下所示)才能使用此选项。

      • raid_level - 逻辑磁盘的 RAID 等级。Ironic 将支持的 RAID 等级定义为 0、1、2、5、6、1+0、5+0、6+0。驱动程序可以通过在 RAIDInterface 中的 get_logical_disk_properties 方法中覆盖值来覆盖这些值。

    2. 可选属性 - 这些属性具有默认值,并且可以覆盖任何逻辑磁盘的规范。

      • volume_name - 卷的名称。应在节点内唯一。如果未指定,则将自动生成卷名称。

      • is_root_volume - 如果这是根卷,则设置为 true。只能用于一个逻辑磁盘。如果驱动程序能够检索它,将保存 根设备提示。默认值为 false

    3. 后端物理磁盘提示 - 这些提示为每个逻辑磁盘指定,以让 Ironic 找到 RAID 配置所需的磁盘。这是与机器无关的信息。这适用于操作员不想为每个裸机节点提供单独详细信息的情况。

      • share_physical_disks - 如果此逻辑磁盘可以与其他逻辑磁盘共享物理磁盘,则设置为 true。如果未提供此选项,驱动程序将假定为 false

      • disk_type - hddssd。如果未指定此选项,则磁盘类型将不会被视为查找后端物理磁盘的标准。

      • interface_type - satascsisas。如果未指定此选项,则接口类型将不会被视为查找后端物理磁盘的标准。

      • number_of_physical_disks - 整数,用于逻辑磁盘的磁盘数量。默认为特定 RAID 等级所需的磁盘的最小数量。

      上述后端物理磁盘提示由 Ironic 定义,每个驱动程序都必须实现它们。通过在 RAIDInterface.get_logical_disk_properties() 方法中使用,可以覆盖上述提示的受支持值和默认值。

      除了上述提示之外,驱动程序还可以在 get_logical_disk_properties 方法中定义自己的提示。有关更多详细信息,请参阅驱动程序 API 影响部分。它们可能的用例包括

      • 按特定供应商过滤磁盘

      • 按型号过滤磁盘

      • 按固件版本过滤磁盘。

    4. 后端物理磁盘 - 这些是实际的与机器相关的信息。这适用于操作员希望基于更广泛的属性(例如 S.M.A.R.T. 状态、物理位置)使用第三方工具自动选择物理磁盘的环境。

      • controller - 驱动程序读取的控制器的名称。

      • physical_disks - 驱动程序读取的要用作物理磁盘的物理磁盘列表。

      注意

      这些属性的值取决于硬件。

    注意

    应仅指定“后端物理磁盘提示”或“后端物理磁盘”中的属性。如果同时指定了两者,则它们应相互一致。如果它们不一致,则 RAID 配置将失败(因为找不到合适的后端物理磁盘)。

    一些示例

    示例 1(使用后端物理磁盘提示)

    {
      "logical_disks":
        [
          {
            "size_gb": 50,
            "raid_level": "1+0",
            "disk_type": "hdd",
            "interface_type": "sas",
            "volume_name": "root_volume",
            "is_root_volume": "true"
          },
          {
            "size_gb": 100,
            "number_of_physical_disks": 3,
            "raid_level": "5",
            "disk_type": "hdd",
            "interface_type": "sas"
            "volume_name": "data_volume"
          }
        ]
    }
    

    示例 2(使用后端物理磁盘)

    {
      "logical_disks":
        [
          {
            "size_gb": 50,
            "raid_level": "1+0",
            "controller": "RAID.Integrated.1-1",
            "volume_name": "root_volume",
            "is_root_volume": "true"
            "physical_disks": [
                               "Disk.Bay.0:Encl.Int.0-1:RAID.Integrated.1-1",
                               "Disk.Bay.1:Encl.Int.0-1:RAID.Integrated.1-1"
                              ]
          },
          {
            "size_gb": 100,
            "raid_level": "5",
            "controller": "RAID.Integrated.1-1",
            "volume_name": "data_volume"
            "physical_disks": [
                               "Disk.Bay.2:Encl.Int.0-1:RAID.Integrated.1-1",
                               "Disk.Bay.3:Encl.Int.0-1:RAID.Integrated.1-1",
                               "Disk.Bay.4:Encl.Int.0-1:RAID.Integrated.1-1"
                              ]
          }
        ]
    }
    
  • RAID 配置信息以 JSON 形式存储在 node.target_raid_config 字段中。操作员可以使用 REST API(或 CLI)随时在此处放置一个新值,该值将在 zapping 和 cleaning 期间与 node.raid_config 进行比较,并且驱动程序可能仅在这些阶段应用更改。有关更多详细信息,请参阅 REST API 影响部分。

  • 将为 RAID 配置提供名为 RAIDInterface 的新驱动程序接口。有关更多详细信息,请参阅驱动程序 API 影响部分。

  • 作为 zapping 的一部分,RAIDInterface 中的新方法 create_configurationdelete_configuration 将可用。操作员可以选择在 zap 步骤中调用它们。相应的 zap 步骤将是 node.raid.create_configurationnode.raid.delete_configuration

  • ironic.common.raid 中将提供一个名为 update_raid_info 的新方法。此方法可供实现 RAID 支持的驱动程序使用,以更新节点数据库中的 RAID 信息。这将促进驱动程序异步执行 RAID 配置。此方法将执行以下操作

    • node.raid_config 设置为驱动程序返回的值。

    • 根卷的根设备提示将在 node.properties 中更新(如 根设备提示 所述),并且根卷的大小将在 node.properties.local_gb 中更新。驱动程序可以选择要指定的根设备提示。此外,驱动程序甚至没有必要选择任何 root_device_hint。

    • 根卷的 RAID 等级将更新为 node.properties.capabilities 中的 raid_level

  • 将创建新的 REST API,用于检索可以在 RAID 配置中指定的属性。有关详细信息,请参阅下面的 REST API 影响部分。

  • 将创建 REST API 以 PUT RAID 配置,并添加一个新的 REST 资源以检索请求的实际 RAID 配置。

备选方案

  • 操作员可以在将节点置于 MANAGEABLE 状态后,随时手动更改 RAID 配置。但这必须为每个节点完成。

数据模型影响

节点对象中的以下字段将被更新

  • 将添加一个新的数据库字段 node.target_raid_config,它将存储要在 zapping 或 cleaning 期间应用的挂起 RAID 配置。这将是一个 JSON 字典。此字段将是只读的。

  • 将添加一个新的数据库字段 node.raid_config,它将存储上次应用的 RAID 配置。它还将包含应用此配置的时间戳。这将是一个 JSON 字典。此字段将是只读的。

  • node.properties.local_gb 将在将 RAID 配置应用于根卷的大小后更新。

  • node.properties.root_device 将使用驱动程序返回的根设备提示更新,如 根设备提示 规范中所述。

  • 将在 node.properties.capabilities 中添加一个新的功能 raid_level。这将包含根卷的 RAID 等级。

状态机影响

无。

REST API 影响

将引入两个新的 REST API 端点作为此更改的一部分。

  • 要获取可以定义的 RAID 属性及其可能的值

    GET /drivers/<driver>/raid/logical_disk_properties
    

    该操作将返回属性和每个属性的可能值的文本描述

    {
     'raid_level': 'RAID level for the logical disk. Supported values are
                    0, 1, 2, 5, 6, 1+0, 5+0, 6+0. Required.',
     'size_gb': 'Size of the logical disk in GiB. Required.',
     'disk_type': 'Disk Type. Supported values are `hdd` or `sdd`. Optional',
     .
     .
     .
     .
    }
    
  • 要设置目标 RAID 配置,用户将

    PUT /v1/nodes/NNNN/states/raid
    

    使用包含 RAID 配置 JSON 描述的主体。

    如果驱动程序接受,此信息将存储在 node.target_raid_config 字段中,并以与电源和配置状态相同的方式公开。换句话说,可以通过详细视图中的 node 或以下任一方式检索它

    GET /v1/nodes/NNNN
    GET /v1/nodes/NNNN/states
    

    注意

    对于保持与电源和配置状态一致,我们仅允许 GET /v1/nodes/NNNN 和 GET /v1/nodes/NNNN/states,因此可能没有必要使用 GET /v1/nodes/NNNN/states/raid。

如果驱动程序不支持 RAID 配置,则这两个 API 调用将返回 HTTP 400(错误请求)。否则,API 将返回 HTTP 200(确定)。

客户端 (CLI) 影响

将在 Ironic CLI 中提供一个新的选项,用于获取可以在 RAID 配置中指定的属性

$ ironic node-raid-logical-disk-properties <node-uuid>

将添加一种新方法来设置目标 RAID 属性

RPC API 影响

将创建两个新的 RPC API。

  • get_raid_logical_disk_properties - 此方法将在 GET /drivers/<driver>/raid/logical_disk_properties 中调用。

  • set_target_raid_config - 此方法将在 PUT /v1/nodes/NNNN/states/raid 中调用。

驱动程序 API 影响

将提供一个新的 RAIDInterface,供驱动程序实现 RAID 配置。它将具有以下方法

  • create_configuration() - 该方法的驱动程序实现必须从 node.target_raid_config 读取请求的 RAID 配置,并在裸机上创建 RAID 配置。如果未设置 node.target_raid_config,驱动程序实现应引发错误。驱动程序必须确保在此过程结束时调用 ironic.common.raid.update_raid_info(),以更新节点的 raid_config。实现细节取决于驱动程序的同步/异步性。

    raid_config 将包括以下内容

    • 对于每个逻辑磁盘(除了传入的参数)

      • controller - 驱动程序读取的用于逻辑磁盘的控制器的名称。

      • physical_disks - 驱动程序读取的用于逻辑磁盘的物理磁盘的标识符列表。

      • root_device_hint - Ironic 用于查找要部署映像的磁盘的根设备提示字典。驱动程序决定要提供的根设备提示。

    • 包含以下详细信息的系统上所有物理磁盘的列表

      • controller - 物理磁盘的 RAID 控制器。

      • id - 驱动程序读取的物理磁盘的 ID

      • disk_type - hddssd

      • interface_type - sassatascsi

      • size_gb

      • state - 状态字段指示物理磁盘的当前状态。它可以是以下之一:

        • active 如果磁盘是阵列的一部分

        • ready 如果磁盘准备好成为卷的一部分

        • failed 如果磁盘遇到了一些错误

        • hotspare 如果磁盘是热备件并且是某个阵列的一部分

        • offline 如果由于其他原因磁盘不可用于 raid,但未失败

        • non_raid 如果磁盘不是 raid 的一部分并且可以直接看到

      上述详细信息可用于后续 RAID 配置的后端物理磁盘提示。

      注意

      对于新注册的节点或 RAID 配置从未完成的节点,可以通过硬件内省填充有关物理磁盘和控制器的信息。这不在本规范的范围内。

    函数定义如下

    def create_configuration(task, create_root_volume=False,
                      create_nonroot_volumes=False):
        """Create RAID configuration on the node.
    
        This method creates the RAID configuration as read from
        node.target_raid_config.  This method
        by default will create all logical disks.
    
        :param task: TaskManager object containing the node.
        :param create_root_volume: Setting this to False indicates
            not to create root volume that is specified in the node's
            target_raid_config. Default value is True.
        :param create_nonroot_volumes: Setting this to False indicates
            not to create non-root volumes (all except the root volume) in
            the node's target_raid_config.  Default value is True.
        :returns: states.CLEANWAIT if RAID configuration is in progress
            asynchronously or None if it is complete.
        """
    
  • delete_configuration() - 删除 RAID 配置。

    函数定义如下

    def delete_configuration(task):
        """Delete RAID configuration on the node.
    
        :param task: TaskManager object containing the node.
        :returns: states.CLEANWAIT if deletion is in progress
            asynchronously or None if it is complete.
        """
    
  • validate() - 验证 RAID 配置。这将用于验证驱动程序接口。它将从 node.properties.target_raid_config 读取目标 RAID 配置,并调用 validate_raid_config 来验证目标 RAID 配置。

    函数定义如下

    def validate(task):
        """Validates the RAID interface.
    
        :param task: TaskManager object containing the node.
        :raises: InvalidParameterValue, if RAID configuration is invalid.
        :raises: MissingParameterValue, if RAID configuration has some
            missing parameters.
        """
    
  • validate_raid_config() - 验证目标 RAID 配置。此函数将在 RPC 调用 set_target_raid_config() 期间被调用,以验证目标 RAID 配置。它还将在 validate() 期间被调用。

    函数定义如下

    def validate_raid_config(task, raid_config):
        """Validates the given RAID configuration.
    
        :param task: TaskManager object containing the node.
        :param raid_config: The target RAID config to validate.
        :raises: InvalidParameterValue, if RAID configuration is invalid.
        """
    
  • get_logical_disk_properties() - 获取驱动程序定义的 RAID 属性。

    函数定义如下

    def get_logical_disk_properties():
        """Gets the RAID properties defined by the driver.
    
        :returns: A dictionary of properties and a textual description.
        """
    

在执行 RAID 配置(创建或删除)后,驱动程序可能会使用 raid_config 调用 ironic.common.raid.update_raid_info()。该方法的详细信息如上所述。该方法的定义如下所示

def update_raid_info(node, raid_config):
    "Updates the necessary fields of the node after RAID configuration.

    This method updates the current RAID configuration in
    node.properties.raid_config.  If root device hint was passed,
    it will update node.properties.local_gb, node.properties.root_device_hint
    and node.properties.capabilities['raid_level'].

    :param node: a node object
    :param raid_config: The current RAID configuration on the bare metal
        node.
    """

Nova 驱动程序影响

无。

Ramdisk 影响

N/A

安全影响

无。

其他最终用户影响

Nova 用户可以通过计算能力选择根卷所需的 RAID 级别。例如

nova flavor-key ironic-test set capabilities:raid_level="1+0"

可扩展性影响

无。

性能影响

RAID 配置可能会延长节点擦除或清理所需的时间,但这对于性能和可靠性至关重要。

其他部署者影响

操作员可以使用 node.raid.create_configurationnode.raid.delete_configuration 作为擦除或清理任务来执行 RAID 管理。

开发人员影响

开发人员可以为各自的驱动程序实现 RAIDInterface

实现

负责人

主要负责人

rameshg87

其他贡献者

ifarkas

工作项

  • 创建 RAID 配置的 REST API 端点。

  • 创建 RAIDInterface 并创建 RAIDInterface 的模拟实现。

  • 在 ironic.common.raid 中实现 update_raid_info

  • 实现 Ironic CLI 变更。

  • 编写单元测试。

依赖项

测试

  • 将为代码添加单元测试。将提供 RAIDInterface 的模拟实现用于测试目的,并且可以在擦除过程中运行。

  • 将添加 Tempest API 覆盖,使用上述模拟驱动程序。

  • 每个驱动程序负责提供第三方 CI 来测试 RAID 配置。

升级和向后兼容性

无。

文档影响

将提供有关如何配置节点以进行 RAID 的文档。

参考资料

其他参考资料