Smartnic 管理总体设计

https://blueprints.launchpad.net/nova/+spec/sriov-smartnic-support

本文档提出一个关于 smartnic 管理的总体设计,涉及 Nova、Neutron 和 Cyborg 的变更。本文档将介绍如何管理 smartnic 的生命周期,以及如何将 smartnic 附加到虚拟机。本文档旨在支持 VF 管理,PF 管理不在本次设计范围内。

问题描述

如今,各种设备被设计用于运行特定的工作负载,从而释放 CPU 资源。Smart-nic 是一种网络设备,可用于卸载与网络相关的负载。它超越了简单的连接,并在 NIC 上实现了网络流量处理,这在传统 NIC 的情况下必然由 CPU 执行。

在当前设计中,OpenStack 无法根据支持的特性和可读的特征自动管理和调度 smart-nic。

用例

  • 用户希望启动一个与 Cyborg 管理的 smartnic 资源关联的特定端口的虚拟机。

  • 用户希望启动利用预编程功能将工作负载卸载到 smart-nic 的虚拟机。

提议的变更

有多个项目(Nova、Neutron、Cyborg 和 Placement)参与此特性。

工作流

此工作流描述了启动具有预编程 nic 的虚拟机的基本操作。该工作流可以分为两个部分

  • 设备发现和报告。

  • 虚拟机启动时的交互。

设备发现

Cyborg 应该实现一个驱动程序,Cyborg-agent 可以定期调用该驱动程序来发现 smartnic 资源。我们将在 Cyborg 规范中详细解释这部分内容,请参考 https://review.opendev.org/#/c/759545/

设备信息报告

如何报告 physnet 特征

如我们所知,Neutron 有一个配置选项 physical_device_mappings,指示物理网络和网络设备之间的映射关系。管理员需要维护另一个配置文件(请参考流程图中的 1),其中包含设备名称和该设备关联的物理网络名称。这样,Cyborg 驱动程序可以直接从该文件读取,并在报告给 Placement 时将物理网络添加为特征。管理员负责保持 Cyborg 和 Neutron 的配置文件一致,否则会出现配置冲突。

与 Neutron 的 Guaranteed Minimum Bandwidth 功能的共存[1]

根据 Wallaby PTG 讨论 [2] 以及后续社区讨论 [3],我们建议在第一步阶段不支持与 Neutron 的 Guaranteed Minimum Bandwidth 功能在同一物理设备上的共存,这意味着一个物理设备只能被 Cyborg 或 Neutron 的 QoS 功能配置,如果它被启用。

以下流程图说明了设备发现和报告期间的工作流程

  +----------------+
  |   cyborg-api   |
  +--------+-------+
           |
           |                      +-------------+        +-------------+
+----------|---------+            |             |        |             |
|  cyborg-conductor  |----------->|  Placement  |<-------|   Neutron   |
+----------|---------+     |      |             |        |             |
           |               |      +-------------+        +-------------+
           |               |       +------------+
           |               +------>|  Cyborg DB |
  +--------|-------+               +------------+
  |  cyborg-agent  |
  +--------|-------+
           |
           |
           |                   +----------------+
  +--------|-------+     1     |                |
  | device-driver  |<----------|  device.conf   |
  +----------------+           |                |
                               +----------------+

虚拟机启动时的交互

目前,Nova 可以与 Cyborg 交互来启动具有加速器(如 FPGA、GPU)的虚拟机。其他操作,如硬/软重启、暂停/取消暂停也受支持。但是,没有机制可以让 Nova 启动与特定网络关联的 nic 的虚拟机。为了实现这一点,需要 Nova、Cyborg 和 Neutron 的变更。本文档还涵盖了关于重启/暂停/停止/启动和其他操作的场景。

在这里,我们以“启动虚拟机”场景为例。假设 Cyborg 已经报告了 nic 资源和相关的特征。建议的工作流程如下

 +-----------+      +-----------+ +-----------+   +-----------+   +---------+
 |   admin   |      |  Neutron  | |   Nova    |   | Placement |   |  Cyborg |
 +-----|-----+      +-----|-----+ +-----|-----+   +-----|-----+   +-------+-+
       |                  |             |               |                 |
       |    1.create device profile     |               |                 |
       |----------------------------------------------------------------->|
                          |             |               |                 |
                          |             |               |                 |
                          |             |               |                 |
                          |             |               |                 |
+-----------+             |             |               |                 |
|  end user |             |             |               |                 |
+-----|-----+             |             |               |                 |
      |  2. create port   |             |               |                 |
      |------------------>|             |               |                 |
      | 3. create server with port      |               |                 |
      |-------------------------------->|               |                 |
                       4.get port details and physnet trait               |

                          |<------------|               |                 |
                                                 5. get device profile
                          |             |<------------------------------->|
                          |             |  6.sheduling  |                 |
                          |             |<------------->|                 |
                          |             |               |                 |
                          |             |               |                 |
                          |             |7.bind device and return PCI info|
                          |             |<------------------------------->|
                          |8.update port|               |                 |
                          |<------------|               |                 |
                          | binding info|               |                 |
                          |             |-----+         |                 |
                          |             |     |         |                 |
                          |             |     | 9. insert SRIOV VIF info  |
                          |             |     | to libvirt XML section    |
                          |             |     |         |                 |
                          |             |<----+         |                 |
                          |             |               |                 |

1. 首先,管理员需要创建一个设备配置文件,其中包含 smartnic 的描述,例如资源类和特征。CLI 已经支持如下所示:

GRP=”[{“resources:CUSTOM_NIC”: “1”,”trait:CUSTOM_GTV1”:”required”}]” openstack accelerator device profile create sriov_dp1 $GRP

2. 其次,用户需要通过将设备配置文件作为参数来创建端口。需要添加相关的 API 来操作此操作。此外,Neutron 需要为 Cyborg 管理的 nic 添加一个新的 vnic-type,我们可以在这里命名为“accelerator-direct”。例如,我们可以通过以下方式创建端口:openstack port create –network providernet –vnic-type accelerator-direct –device-profile sriov-dp1 sriov_port1,其中 sriov-dp1 是第一步创建的设备配置文件。请注意,端口使用的设备配置文件应该只有一个设备资源是必需的,否则在虚拟机启动过程中会抛出异常。

请求体如下

{
   "port": {
        "name": "sriov-port1",
        "network_id": "a87cc70a-3e15-4acf-8205-9b711a3531b7",
        "vnic_type":"accelerator-direct",
        "device_profile": "sriov_dp1" # new extension contains device profile
    }
}

3. 第三,用户可以通过以下方式启动虚拟机:openstack server create –image image-uuid -flavor flavor-name –nic port-id=sriov_port1 test_vm1。(如果端口使用的设备配置文件包含多个设备,此 API 请求将以 400 错误代码失败。)

4. Nova 与 Neutron 交互以获取端口的详细信息,包括 vnic 类型、neutwork_id、物理网络等。

5. 如果 vnic 类型是“accelerator-direct”,那么 Nova 需要提取 sriov_port1 的“device_profile”扩展,并调用 Cyborg API 来获取此设备配置文件的详细信息 [4],ARQ 的创建也在这一步中。

6. 在第 4 步中,Nova 从 Neutron 获取了物理网络,现在 Nova 需要将其转换为 Placement 的特征格式,并将其保存在端口的资源请求字段中,如果 vnic 类型是“accelerator-direct”。然后 Nova 需要将从 Cyborg 的设备配置文件和端口资源请求获得资源类/特征合并到一个请求组中。此请求组将合并到 request_spec 中,该 request_spec 将用于重启/暂停/启动/停止和其他支持的操作。之后,Nova 将虚拟机调度到匹配所有请求资源的可用计算节点。

7. 调度后,Nova 需要调用 Cyborg 将 ARQ 与实例 uuid 绑定,并返回 attach_handle,其中包含设备的信息,例如 PCI 地址。Cyborg 中启动了一个异步绑定作业,Cyborg 在绑定操作完成后会发送通知。

  1. Nova 等待 Cyborg 发送的通知。

  2. 一旦 Nova 收到 Cyborg 发送的通知,表明绑定操作成功,Nova 需要告诉 Neutron 更新端口绑定的信息。

  3. Libvirt 驱动程序需要将 SRIOV nic 信息插入到 XML 部分。

API 调用

  1. Nova 调用 Neutron 获取端口详细信息。

  • 请求 URL:/v2.0/ports/{port_id}

  • 方法:GET

  • 响应示例(应返回新的扩展 device_profile

    {
      "port": {
          ...
          "binding_profile": {},
          "name": "sriov-port",
          "network_id": "a87cc70a-3e15-4acf-8205-9b711a3531b7",
          "qos_network_policy_id": "174dd0c1-a4eb-49d4-a807-ae80246d82f4",
          "qos_policy_id": "29d5e02e-d5ab-4929-bee4-4a9fc12e22ae",
          "device_profile":"sriov-dp1" # new extension
          ...
      }
     }
    
  1. Nova 调用 Cyborg 获取设备配置文件详细信息。[5]

  2. Nova 调用 Cyborg 创建和绑定 ARQ。

  • 创建 ARQ [6]

  • 绑定 ARQ [7]

  • 等待 Cyborg 发送“绑定成功”通知。

  1. Nova 调用 Neutron 使用接口信息更新端口绑定配置文件。[8]

Neutron

在 Neutron 侧,需要添加一个新的 vnic 类型“accelerator-direct”,以及一个新的端口扩展“device_profile”。请参阅 Neutron 的 RFE [9] 以获取详细信息。

建议的更改包括

  • 添加一个新的 vnic 类型“accelerator-direct”,指示与 Cyborg 管理的设备关联的端口。

  • 在 neutorn lib 中定义设备配置文件扩展端口。

  • 在 Neutron 中实现设备配置文件扩展端口。

  • 从 DB 侧,我们需要添加一个新的表来存储端口和 device_profile 之间的映射关系

    +---------------------------------------+------------------------+
    | port_uuid                             | device_profile         |
    +=======================================+========================+
    | 20f78856-0f73-4cf4-bcd0-1389086eb038  | sriov_dev_profile      |
    +---------------------------------------+------------------------+
    

请参考

  • 端口资源请求定义 [10]

  • neutron-lib port-resource-request Commits [11]

  • neutron plugin port-resource-request Commits [12]

Nova

  • Nova API:Nova 调用 Neutron API 获取端口详细信息,包括 vnic 类型、物理网络等。“device_profile”应作为返回值返回。

  • Nova API:Nova 需要检查 vnic 类型是否为“accelerator-direct”。如果是,Nova 将从 neutron 端口获取设备配置文件的名称,并调用 Cyborg API 获取此设备配置文件的详细信息。同时,Nova 需要为物理网络生成一个特征,例如,Nova 从 Neutorn 获取“physnet1”作为物理网络,该特征应类似于“CUSTOM_PHYSNET_PHYSNET1”,这与 Cyborg 报告的内容一致。

  • Nova API:一旦 Nova 获取了所有资源类和特征,Nova 应该检查是否创建了带有 port_resource_request 的 RequestGroup,如果是,我们应该将资源和特征添加到此请求组,如果不是,我们应该生成一个新的资源组。Nova 应该有一个单一的请求组来调度到单个 nic 资源提供程序 [13]。此请求组存储调度程序使用的请求资源信息,以及其他操作,例如重启/暂停/取消暂停/启动/停止,将使用此请求组来执行调度。

  • Nova Compute:Nova 应该使用 sriov nic 的信息(例如 pci 地址等)更新端口绑定配置文件,以便 libvirt 驱动程序可以生成相关的 xml 部分。

Cyborg

  • Cyborg 中需要添加一个新的驱动程序,以便发现、编程和绑定设备。更多详细信息请参见 Cyborg 规范。

  • Cyborg 需要实现一个设备配置文件来配置 nic 的名称、pci 地址、physnet 名称等,这些用于 Cyborg 驱动程序生成资源提供程序、特征等。

    [dev-type]
    physical_device_mappings = physnet1:eth2|eth3
    function_device_mappings = GTPv1:eth3|eth2
    

备选方案

谁报告 physnet 特征

  • Placement CLI 添加特征。

    管理员需要手动将 physnet 特征添加到资源提供程序,这将在 Cyborg 将资源报告给 Placement 之后完成。这将导致冗余的 Placement API 调用。

  • Neutron 报告 Cyborg 创建的资源提供程序的特征。

    这样,Neutron 应该首先通过 Placement API 获取 Cyborg 创建的资源提供程序,Neutron 还应该根据 nic 的资源找到正确的 physnet 属性,这需要 Neutron 进行更多更改。

  • 让 Neutron 创建 RP 和 physnet 特征。

    如我们所知,Neutron 在配置最小带宽 QoS 时会创建 RP 和相关的特征。我们建议 Neutron 始终报告 RP 和 physnet 特征,无论是否配置了带宽 qos。这样,Cyborg 将仅使用一些命名约定找到 Neutron 创建的 RP,并将加速器相关的特征添加到此 RP。

    但是,我们应该考虑 Neutron 报告时 RP 树结构的样子,它应该直接位于计算节点 RP 下方,还是仍然位于像带宽 qos 功能那样的 Agent RP 下方。

Nova 如何使用请求设备生成 request_spec

  • Neutron 调用 Cyborg API 获取设备配置文件详细信息,并将所有 RC 和特征合并到 port_resource_request 中,然后返回给 Nova。通过从 Neutron 中的 Cyborg 检索设备配置文件,允许 Neutron 验证设备配置文件包含一个设备请求。此检查将由 Nova 代替执行。

    这需要 Neutron 更改以与 Cyborg 交互,这似乎 Cyborg 是 Neutron 的子组件。最好让 Nova 与 Cyborg 和 Neutron 平等交互。

  • 实现一个新的 DeviceProfileRequest 来存储设备配置文件的请求组,并将其作为 Nova 生成 request_spec 时的新的参数传递。

    似乎拥有一个新的请求对象是多余的。

其他

  • Cyborg 为其支持的 NIC 提供自己的 SRIOV ML2 驱动程序。

    Cyborg 维护一个 Neutron 插件驱动程序,超出了 Cyborg 项目的范围。

  • ARQ 的消费者可以是端口而不是实例 uuid。

    在 ARQ 绑定期间,Nova 等待来自 Cyborg 的外部事件,该事件由实例 uuid 查询。我们需要保持它与来自 flavor.extra_specs 的请求流程相同。

数据模型影响

Neutron DB 中需要添加一个新的表 device_profile

REST API 影响

  • 一个新的扩展“device_profile”将被添加到 Neutron 端口,Neutron API 需要更改。Neutron API 还应该禁止用户在端口与一个实例绑定后修改“device_profile”字段(Neutron API 需要检查绑定:host-id 在更新“device profile”字段之前)。此修改仅在端口未绑定时允许。

  • 更改 Nova API 以支持更多操作。我们计划支持创建/删除、启动/停止、暂停/取消暂停、重建、重启、锁定/解锁、救援/取消救援,对于具有“accelerator-direct” vnic 类型端口的虚拟机,

  • 由于 neutron 端口不能关联到多个 NIC,因此只有包含一个设备组的设备配置文件才能被接受到端口。否则,将以 HTTP 400 错误引发异常。

  • 如果操作不支持,将以 HTTP 400 错误被拒绝。情况 1:如果存在服务版本过旧的计算节点不支持此功能,则带有 device_profile 的端口的服务器生命周期操作将以 HTTP 400 错误被拒绝。情况 2:对于我们不支持的操作,例如对具有“accelerator-direct” vnic 类型端口的 VM 执行撤离、调整大小、迁移、shelve/unshelve 操作,以及将“accelerator-direct” vnic 类型端口附加/分离到/从 VM,也将返回 HTTP 400 错误。

安全影响

通知影响

其他最终用户影响

其他部署者影响

开发人员影响

性能影响

升级影响

  • Nova 需要适应新的 Neutron API 扩展,该扩展在端口中引入了 device_profile。

  • Nova 计算服务版本需要更新,如果所有计算服务的最低版本不满足最低要求,则对带有 device_profile 端口的服务器进行生命周期操作时将被拒绝。

实现

负责人

Yongli He(yongli.he@intel.com)

王欣然(xin-ran.wang@intel.com)

功能联络人

工作项

  • 在 Neutron 中添加新的端口扩展。

  • 在 Cyborg 中实现特定 nic 的新驱动程序。

  • 在 Cyborg 中添加一个配置文件来处理 physnet。

  • 解析并将请求合并到 Nova 中的请求规范中。

  • 将 ARQ 绑定到实例 uuid 并更新端口绑定配置文件。

  • 重用当前的 sriov nic xml 生成代码。

依赖项

测试

  • 需要在相关项目中添加 UT(单元测试)。

  • Nova 中的功能测试。

  • 如果需要,在 Nova 中进行 Tempest 测试。

  • 在 cyborg-tempest-plugin 中进行 Tempest 测试。

文档影响

需要添加文档。

参考资料

历史

修订

发布名称

描述

Wallaby

已批准

Xena

重新提出