OpenStack Ussuri 版新特性: Nova-Cyborg Interaction功能分析

OpenStack Ussuri 版新特性: Nova-Cyborg Interaction功能分析_第1张图片

摘要:OpenStack社区在Ussuri版本完成了nova-cyborg interaction功能的开发, 该功能加强了nova和cyborg的联系, 解耦了nova的PCI加速设备管理功能, 通过cyborg和placement可以让加速器资源的管理更加灵活。


概念

PR

resource provider, placement中的概念, 资源提供者。

Device Profile

Device profile是Cyborg中的概念, 它用于描述单个或多个加速设备,可以将之看作加速设备的flavor. 广义上, 它包括了两点:

  • 特定资源类的数量(resource class)
  • RP需要满足的要求(trait)

一个device profile的结构如下:

``` json
{
    'name': 'gpu-nvidia-t4',
    'description': 'Nvidia tesla t4',
    'groups': [
        {'resources:PGPU': '1',
         'CUSTOM_GPU_PRODUCT_ID_1EB8': 'required'
        },
        {'resources:PGPU': '2',
         'CUSTOM_GPU_PRODUCT_ID_1E04': 'required'
        }
    ]
    'uuid': 'd6cd5b94-f95c-4148-85c5-2ce22a38a796'
}
```

目前仅允许管理员创建/更新/删除device profiles。

ARQ

ARQ即accelerator request, 它是一个对象, 用于描述实例请求分配加速设备的状态,ARQ的创建和管理由cyborg完成, 并且数据存储在cyborg数据库中。

一个ARQ只能表示单个加速设备分配请求. `device_profile`可以有N个group, 每个group请求M个加速设备, 此时将会创建N*M个ARQ。

Cyborg初始化一个ARQ后, 该ARQ并不会和特定的计算节点主机名或RP id关联, 此时我们可以认为该ARQ处于未绑定状态(unbound). 之后, nova调用cyborg将ARQ绑定到一个计算节点主机名和一个加速设备的RP id和一个实例 id上. 如果实例孵化失败, nova不会删除这个ARQ, 而是取消绑定. nova会在删除实例时解绑和删除ARQ。

在绑定ARQ前, 每个ARQ都需要与nova选择的allocation candidate匹配。当前nova会建立RequestGroup到RPs的映射, nova中的cyborg客户端模块据此将ARQ匹配到RequestGroup上。匹配是使用RequestGroup对象中的requester_id字段进行的, 规则如下:

  • device profile中的group的顺序并不重要, 但是cyborg保留了这个顺序. 因此每个RequestGroup都有一个唯一的索引;
  • 当cyborg返回的device profile groups添加到request spec中时, 对于第N个RequestGroup, requester_id将被设置为`device_profile_`. 因为每个request spec只有一个device profile, 所以device profile的名称不需要包含在其中;
  • 当cyborg为device profile创建一个ARQ时, 它会在ARQ中嵌入group的索引, 然后将之返回给nova;
  • 匹配由以下两步完成:每个ARQ使用的requester_id字段映射到request spec的RequestGroup中;每个RequestGroup被映射到特定的RP, 与neutron bandwidth provider的逻辑一致。

一个ARQ的结构如下:

``` json
{'arqs': [
    {'uuid': 'c406129e-821c-4583-b094-d948fe6f4aa1',
     'state': 'Bound',
     'device_profile_name': 'gpu-nvidia-t4',
     'device_profile_group_id': 0,
     'hostname': 'vgpu02',
     'device_rp_uuid': '2a0c2b8f-2ec1-3364-a773-0ba4166e9a34',
     'instance_uuid': '81334887-7044-44cd-805f-0f7e206e04b8',
     'attach_handle_type': 'PCI',
     'attach_handle_info': {
        'bus': '5e',
        'device': '00',
        'domain': '0000',
        'function': '0'
      },
     'created_at': '2020-04-27T11:42:11+00:00',
     'updated_at': '2020-04-27T11:42:11+00:00'}
]}
```

虚拟机创建流程

``` graph
+------+        +----------+       +----------------+     +--------------+       +--------+
| User |        | Nova api |       | Nova conductor |     | Nova Compute |       | Cyborg |
+--+---+        +----+-----+       +-------+--------+     +-------+------+       +---+----+
   |                 |                     |                      |                  |
   | Create Instance |                     |                      |                  |
   +---------------->+                     |                      |                  |
   |                 |                     |                      |                  |
   |                 | Get Device Profile  |                      |                  |
   |                 +<------------------------------------------------------------->+
   |                 |                     |                      |                  |
   |                 |   Scheduler and     |                      |                  |
   |                 +-------------------->+                      |                  |
   |                 |   build instance    |                      |                  |
   |                 |                     |  Create ARQs         |                  |
   |                 |                     +---------------------------------------->+
   |                 |                     |                      |                  |
   |                 |                     |  Bind ARQs           |                  |
   |                 |                     +---------------------------------------->+
   |                 |                     |                      |                  |
   |                 |                     |  Spawn instance      |                  |
   |                 |                     +--------------------->+                  |
   |                 |                     |                      |                  |
   |                 |                     |                      |  Notify bind end |
   |                 |                     |                      +<-----------------+
   |                 |                     |                      |                  |
   |                 |                     |                      | Get ARQs info    |
   |                 |                     |                      +<---------------->+
   |                 |                     |                      |                  |
   |                 |                     |                      |                  |
   |                 |                     |                      +-----+            |
   |                 |                     |                      |     |Spawn       |
   |                 |                     |                      |     |Instace     |
   |                 |                     |                      +<----+            |
   |                 |                     |                      |                  |
```

1. nova-api收到创建虚机的请求

`nova.compute.api.API._provision_instances`会尝试解析flavor extra specs,若`flavor.extra_specs.get('accel:device_profile')`属性不为`None`, 该属性应当为device profile的名称, 调用`nova.accelerator.cyborg.get_device_profile_request_groups`获取该deviceprofile中的groups值:

cyborg API返回的数据结构如下:

``` json
    {
        "device_profiles": [
            {
                "name": "gpu-nvidia-t4",
                "groups": [
                    {
                        "trait:CUSTOM_GPU_PRODUCT_ID_1EB8": "required",
                        "resources:PGPU": "1"
                    }
                ]
            }
        ]
    }
    ```

该调用返回列表:`nova.objects.request_spec.RequestGroup`, 需要注意此处只使用到了`groups`的`trait`, `resources`相关属性, `accel`并未被使用:

 ``` list
    [
        RequestGroup(requester_id='device_profile_0',
                     resources={'PGPU': 1},
                     required_traits={'CUSTOM_GPU_PRODUCT_ID_1EB8'})
    ]
    ```

返回的RequestGroup合并到RequestSpec.required_resources中, 用于接下来的调度和创建实例。

2. nova-conductor/nova-scheduler调度

nova conductor调用nova-scheduler调度, nova-scheduler使用RequestSpec中的信息向placement查询合适的RP, 这些流程没有变动。

3. nova-conductor创建ARQ(accelerator request)

`nova.conductor.manager.ComputeTaskManager.schedule_and_build_instances`在调度完成后调用`_creaet_and_bind_arqs`创建并绑定ARQ。

首先调用`nova.accelerator.cyborg.create_arqs_and_match_resource_providers`,为该device profile创建ARQs, 获取新建的ARQs, 并按照group的索引,ResourceGroup及RPs的映射, 将ARQ的`device_rp_uuid`重置为对应的RP id并返回。

之后调用`nova.accelerator.cyborg.bing_arqs`将ARQ与计算节点主机名, 实例id,加速设备RP id绑定. Cyborg会依据不同的设备类型进行绑定, 例如FPGA在绑定时可能会烧写镜像。Cyborg绑定完成后会向nova发送一个ExternalEvent的notification, 其结构如下:

``` list
    [
        {
            'name': 'accelerator-request-bound',
            'server_uuid': 'instance_uuid',
            'tag': 'arq_uuid',
            'status': 'arq_bind_status'
        }
    ]
    ```

Cyborg的绑定是异步的, 所以nova可以继续通过RPC调用`nova.compute.ComputeManager.build_and_run_instance`, ARQ uuids作为参数`accel_uuids`传入。

4. nova-compute孵化实例

在`nova.compute.ComputeManager._bild_and_run_instance`中调用`_build_resources`, 该方法尝试调用`_get_bound_arq_resources`以等待上述的notification发送. 若收到notification, 则尝试通过cyborg client获取ARQs详情并返回; 若在`CONF.arq_binding_timeout`内未收到notification, 则抛出异常。
    
在`nova.virt.libvirt.driver.LibvirtDriver.spawn`中调用`_get_guest_xml`,最后在`_get_guest_config`和`_guest_add_accel_pci_devices`方法中解析设备相关信息并挂载到实例上。

参考文献

  • https://specs.openstack.org/openstack/cyborg-specs/specs/train/approved/device-profiles.html
  • https://specs.openstack.org/openstack/nova-specs/specs/ussuri/approved/nova-cyborg-interaction.html
  • https://github.com/openstack/nova/blob/63380a6b494e0f0f220b67b197edec836f1c5a42/nova/objects/request_spec.py#L777

你可能感兴趣的:(社区更新)