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

摘要: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_<N>`. 因爲每個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
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章