12月技术周 | Nova 刚生出来的 Placement 是什么东西?


历史背景

私有云的用户,尤其是传统 IT 架构转型的私有云用户一般会拥有各式各样的存量资源系统,与这些系统对接会让 OpenStack 的资源体系变得复杂。

从用户的视角出发,或许你会希望

  • 作为使用共享存储解决方案的用户,我会希望 Nova 和 Horizon 能够正确报告共享存储磁盘资源的总量和使用量信息。

  • 作为高级的 Neutron 用户,我预期会使用外部的第三方路由网络功能,希望 Nova 能够掌握和使用特定的网络端口与特定的子网池相关联,确保虚拟机能够在该子网池上启动。

  • 作为高级的 Cinder 用户,我希望当我在 nova boot 命令中指定了 cinder volume-id 后 Nova 能够知道哪一些计算节点与 Request Volume 所在的 Cinder 存储池相关联。

所以,OpenStack 除了要处理计算节点 CPU,内存,PCI 设备、本地磁盘等内部资源外,还经常需要纳管有如 SDS、NFS 提供的存储服务,SDN 提供的网络服务等外部资源。

但在以往,Nova 只能处理由计算节点提供的资源类型。Nova Resource Tracker 假定所有资源均来自计算节点,因此在周期性上报资源状况时,Resource Tracker 只是单纯针对计算节点清单进行资源总量和使用量的加和统计。显然,这无法满足上述复杂的生产需求,也违背了 OpenStack 一向赖以自豪的开放性原则。随着 OpenStack 的定义被社区进一步升级为「一个开源基础设施集成引擎」,也意味着 OpenStack 资源体系将会由更多样的外部资源类型构成。

所以,当资源类型和提供者变得多样时,自然就需求一种高度抽象且统一的管理方法,让用户和代码能够便捷的使用、管理、监控整个 OpenStack 的系统资源,这就是 Placement(布局)

Placement

Placement 肩负着这样的使命,最早在 Newton 版本被引入 openstack/nova repo,以 API 的形式存在,所以也常被称为 Placement API。它参与到 nova-scheduler 选择目标主机的调度流程中,负责跟踪记录 Resource Provider 的 Inventory 和 Usage,并使用不同的 Resource Classes 来划分资源类型,使用不同的 Resource Traits 来标记资源特征。

NOTE:Ocata 版本的 Placement API 是一个可选项,建议用户启用并替代 CpuFilter、CoreFilter 和 DiskFilter。Pike 版本则强制要求启动 Placement API 服务,否则 nova-compute service 无法正常运行。

直至成文前段时间(2018/11),Placement API 开始了 openstack/nova repo 剥离流程,从 Placement API 蜕变为 OpenStack Placement。虽然现在的 OpenStack Placement 还不算稳定,但毋容置疑,Placement 就是 OpenStack 云平台统一资源管理的未来。

OpenStack Placement provides an HTTP service for managing, selecting, and claiming providers of classes of inventory representing available resources in a cloud.

Placement 拥有独立的 REST API。

  1. [root@control01 ~]# openstack catalog show placement

  2. +-----------+------------------------------------------+

  3. | Field     | Value                                    |

  4. +-----------+------------------------------------------+

  5. | endpoints | RegionOne                                |

  6. |           |   public: http://172.18.22.222/placement |

  7. |           |                                          |

  8. | id        | 9b5683b4a5284369bafad76944a0610f         |

  9. | name      | placement                                |

  10. | type      | placement                                |

  11. +-----------+------------------------------------------+

Placement 拥有独立的数据库和数据模型。

  1. MariaDB [(none)]> use placement


  2. MariaDB [placement]> show tables;

  3. +------------------------------+

  4. | Tables_in_placement          |

  5. +------------------------------+

  6. | alembic_version              |

  7. | allocations                  |

  8. | consumers                    |

  9. | inventories                  |

  10. | placement_aggregates         |

  11. | projects                     |

  12. | resource_classes             |

  13. | resource_provider_aggregates |

  14. | resource_provider_traits     |

  15. | resource_providers           |

  16. | traits                       |

  17. | users                        |

  18. +------------------------------+

NOTE:本篇主要分析、记录 1.0 版本的 Placement 实现。

  1. [root@control01 ~]# openstack versions show --service placement

  2. +-------------+--------------+---------+---------+---------------------------------+------------------+------------------+

  3. | Region Name | Service Type | Version | Status  | Endpoint                        | Min Microversion | Max Microversion |

  4. +-------------+--------------+---------+---------+---------------------------------+------------------+------------------+

  5. | RegionOne   | placement    | 1.0     | CURRENT | http://172.18.22.222/placement/ | 1.0              | 1.30             |

  6. +-------------+--------------+---------+---------+---------------------------------+------------------+------------------+

基本概念

Resource Provider:资源提供者,实际提供资源的实体,例如:Compute Node、Storage Pool、IP Pool 等。

Resource Class:资源种类,即资源的类型,Placement 为 Compute Node 缺省了下列几种类型,同时支持 Custom Resource Classes。

  1. [root@control01 ~]# export OS_PLACEMENT_API_VERSION=1.17


  2. [root@control01 ~]# openstack resource class list

  3. +----------------------------+

  4. | name                       |

  5. +----------------------------+

  6. | VCPU                       |

  7. | MEMORY_MB                  |

  8. | DISK_GB                    |

  9. | PCI_DEVICE                 |

  10. | SRIOV_NET_VF               |

  11. | NUMA_SOCKET                |

  12. | NUMA_CORE                  |

  13. | NUMA_THREAD                |

  14. | NUMA_MEMORY_MB             |

  15. | IPV4_ADDRESS               |

  16. | VGPU                       |

  17. | VGPU_DISPLAY_HEAD          |

  18. | NET_BW_EGR_KILOBIT_PER_SEC |

  19. | NET_BW_IGR_KILOBIT_PER_SEC |

  20. +----------------------------+

Inventory:资源清单,资源提供者所拥有的资源清单,例如:Compute Node 拥有的 vCPU、Disk、RAM 等 inventories。

Provider Aggregate:资源聚合,类似 HostAggregate 的概念,是一种聚合类型。

Traits:资源特征,不同资源提供者可能会具有不同的资源特征。Traits 作为资源提供者特征的描述,它不能够被消费,但在某些 Workflow 或者会非常有用。例如:标识可用的 Disk 具有 SSD 特征,有助于 Scheduler 灵活匹配 Launch Instance 的请求。

Resource Allocations:资源分配状况,包含了 Resource Class、Resource Provider 以及 Consumer 的映射关系。记录消费者使用了该类型资源的数量。

数据模型解析

Data Models

  • ResourceProvider:资源提供者

  • Inventory:资源提供者的资源清单

  • ResourceClass:资源种类

  • ResourceProviderAggregate:资源聚合,实际上是资源提供者和主机聚合的映射关系

  • Trait:资源特征描述类型

  • ResourceProviderTrait:资源提供者和特征描述的对应关系

  • Allocation:分配给消费者的资源状况

  • Consumer:消费者,本质是一串 UUID

  • User:Keystone User

Resource Provider Inventory 的属性

  1. MariaDB [nova_api]> desc inventories;

  2. +----------------------+----------+------+-----+---------+----------------+

  3. | Field                | Type     | Null | Key | Default | Extra          |

  4. +----------------------+----------+------+-----+---------+----------------+

  5. | created_at           | datetime | YES  |     | NULL    |                |

  6. | updated_at           | datetime | YES  |     | NULL    |                |

  7. | id                   | int(11)  | NO   | PRI | NULL    | auto_increment |

  8. | resource_provider_id | int(11)  | NO   | MUL | NULL    |                |

  9. | resource_class_id    | int(11)  | NO   | MUL | NULL    |                |

  10. | total                | int(11)  | NO   |     | NULL    |                |  总大小

  11. | reserved             | int(11)  | NO   |     | NULL    |                |  保留大小

  12. | min_unit             | int(11)  | NO   |     | NULL    |                |  最小分配单位

  13. | max_unit             | int(11)  | NO   |     | NULL    |                |  最大分配单位

  14. | step_size            | int(11)  | NO   |     | NULL    |                |  步长

  15. | allocation_ratio     | float    | NO   |     | NULL    |                |  超分比

  16. +----------------------+----------+------+-----+---------+----------------+

每个 Compute Node 缺省有 3 条 inventories 记录 0,1,2 分别对应 3 种资源种类 CPU(s)、RAM(MB) 和 DISK(GB)

  1. MariaDB [nova_api]> select * from resource_providers;

  2. +---------------------+---------------------+-----+--------------------------------------+------------------------------------------------------+------------+----------+

  3. | created_at          | updated_at          | id  | uuid                                 | name                                                 | generation | can_host |

  4. +---------------------+---------------------+-----+--------------------------------------+------------------------------------------------------+------------+----------+

  5. | 2018-05-03 09:07:01 | 2018-07-02 07:03:57 |   1 | e367ded8-9501-42b1-a18d-e7f3bab233c6 | domain-c69.22bebe01-eb68-4a5c-839d-11398df43232      |        252 |     NULL |


  6. MariaDB [nova_api]> select * from inventories;

  7. +---------------------+---------------------+----+----------------------+-------------------+--------+----------+----------+----------+-----------+------------------+

  8. | created_at          | updated_at          | id | resource_provider_id | resource_class_id | total  | reserved | min_unit | max_unit | step_size | allocation_ratio |

  9. +---------------------+---------------------+----+----------------------+-------------------+--------+----------+----------+----------+-----------+------------------+

  10. | 2018-05-03 09:07:07 | 2018-07-02 07:03:57 |  1 |                    1 |                 0 |     42 |        0 |        1 |       42 |         1 |                2 |

  11. | 2018-05-03 09:07:07 | 2018-07-02 07:03:57 |  2 |                    1 |                 1 | 407562 |     2048 |        1 |   407562 |         1 |                1 |

  12. | 2018-05-03 09:07:07 | 2018-07-02 07:03:57 |  3 |                    1 |                 2 |    736 |        2 |        1 |      736 |         1 |                1 |

如何查看消费者使用了哪一个资源提供者的哪几种资源种类及数量?e.g. 消费者(虚拟机 648bda64-1d7a-44d2-ba38-20c84959dabe)使用了资源提供者 97 的 1U/256M/1G 的 CPU/RAM/DISK 资源。

  1. MariaDB [nova_api]> select * from allocations;

  2. +---------------------+------------+-----+----------------------+--------------------------------------+-------------------+------+

  3. | created_at          | updated_at | id  | resource_provider_id | consumer_id                          | resource_class_id | used |

  4. +---------------------+------------+-----+----------------------+--------------------------------------+-------------------+------+

  5. | 2018-05-23 10:40:49 | NULL       |  97 |                   97 | 648bda64-1d7a-44d2-ba38-20c84959dabe |                 0 |    1 |

  6. | 2018-05-23 10:40:49 | NULL       |  98 |                   97 | 648bda64-1d7a-44d2-ba38-20c84959dabe |                 1 |  256 |

  7. | 2018-05-23 10:40:49 | NULL       |  99 |                   97 | 648bda64-1d7a-44d2-ba38-20c84959dabe |                 2 |    1 |

如何查看消费者分配了的资源状况?e.g. 查看分配给消费者(虚拟机 648bda64-1d7a-44d2-ba38-20c84959dabe)的资源状况。

  1. MariaDB [nova_api]> select * from allocations;

  2. +---------------------+------------+----+----------------------+--------------------------------------+-------------------+------+

  3. | created_at          | updated_at | id | resource_provider_id | consumer_id                          | resource_class_id | used |

  4. +---------------------+------------+----+----------------------+--------------------------------------+-------------------+------+

  5. | 2018-08-01 10:52:15 | NULL       |  7 |                    1 | f8d55035-389c-47b8-beea-02f00f25f5d9 |                 0 |    1 |

  6. | 2018-08-01 10:52:15 | NULL       |  8 |                    1 | f8d55035-389c-47b8-beea-02f00f25f5d9 |                 1 |  512 |

  7. | 2018-08-01 10:52:15 | NULL       |  9 |                    1 | f8d55035-389c-47b8-beea-02f00f25f5d9 |                 2 |    1 |

  8. +---------------------+------------+----+----------------------+--------------------------------------+-------------------+------+


  9. # consumer_id 消费者

  10. # resource_class_id 资源类型

  11. # resource_provider_id 资源提供者

  12. # used 分配的数量

Command Line

Placement CLI 以 OS Client Placement Plugin 的形式提供,是 openstack 指令的扩展。

Installation

  1. pip install python-openstackclient

  2. pip install osc-placement

EXAMPLE

  1. [root@control01 ~]# export OS_PLACEMENT_API_VERSION=1.17


  2. [root@control01 ~]# openstack resource provider list

  3. +--------------------------------------+-----------+------------+--------------------------------------+----------------------+

  4. | uuid                                 | name      | generation | root_provider_uuid                   | parent_provider_uuid |

  5. +--------------------------------------+-----------+------------+--------------------------------------+----------------------+

  6. | 5c5a578f-51b0-481c-b38c-7aaa3394e585 | control01 |         25 | 5c5a578f-51b0-481c-b38c-7aaa3394e585 | None                 |

  7. +--------------------------------------+-----------+------------+--------------------------------------+----------------------+


  8. [root@control01 ~]# openstack resource provider inventory list 5c5a578f-51b0-481c-b38c-7aaa3394e585

  9. +----------------+------------------+----------+----------+-----------+----------+-------+

  10. | resource_class | allocation_ratio | max_unit | reserved | step_size | min_unit | total |

  11. +----------------+------------------+----------+----------+-----------+----------+-------+

  12. | VCPU           |             16.0 |       32 |        0 |         1 |        1 |    32 |

  13. | MEMORY_MB      |              1.5 |    40959 |      512 |         1 |        1 | 40959 |

  14. | DISK_GB        |              1.0 |       49 |        0 |         1 |        1 |    49 |

  15. +----------------+------------------+----------+----------+-----------+----------+-------+


  16. [root@control01 ~]# openstack resource provider usage show 5c5a578f-51b0-481c-b38c-7aaa3394e585

  17. +----------------+-------+

  18. | resource_class | usage |

  19. +----------------+-------+

  20. | VCPU           |     5 |

  21. | MEMORY_MB      |  3648 |

  22. | DISK_GB        |     7 |

  23. +----------------+-------+


  24. [root@control01 ~]# openstack allocation candidate list --resource VCPU=1

  25. +---+------------+--------------------------------------+-------------------------+--------------------------------------------------------------+

  26. | # | allocation | resource provider                    | inventory used/capacity | traits                                                       |

  27. +---+------------+--------------------------------------+-------------------------+--------------------------------------------------------------+

  28. | 1 | VCPU=1     | 5c5a578f-51b0-481c-b38c-7aaa3394e585 | VCPU=5/512              | HW_CPU_X86_SSE2,HW_CPU_X86_SSE,HW_CPU_X86_MMX,HW_CPU_X86_SVM |

  29. +---+------------+--------------------------------------+-------------------------+--------------------------------------------------------------+

更多详细请浏览 Command Line Reference。

NOTE:这里指定 micro-version 为 1.17,通过环境变量 OS_PLACEMENT_API_VERSION 指定,也可以通过 request header OpenStack-API-Version:placement 1.17 指定。

Placement Web Application

要分析 Placement 的实现,实际是分析 placement-api service 的实现,当前 Placement 只提供单一的 API 服务。placement-api 是一个标准的 WSGI 实现,WSGI Script placement-api 存放在 usr/bin 或 /usr/local/bin 目录下,被 WSGI-capable web servers 加载启动。e.g.

  1. /usr/bin/uwsgi --procname-prefix placement --ini /etc/placement/placement-uwsgi.ini

WSGI(Web Server Gateway Interface,Web 服务器网关接口) 指代一种编程规范,将 Web 系统抽象为 Web Server、Middleware 和 Application 三个层次,实现让不同协议之间的实现可以互相通信,故称之为 “网关”。实现了 WSGI 规范的程序可称为 WSGI 组件,常见的 WSGI 组件有 mod_wsgi、uwsgi 等,Python 代码可以运行在 Apache、Nginx 等 HTTP Server 上也得益于此。简而言之,WSGI 定义了 Web Server 如何与 Python Web Application 进行交互的规则。OpenStack 项目常使用 Apache + WSGI 的组合来支撑 REST API 服务。

NOTE:如果是 Devstack 部署的环境,应用了 Apache ProxyPass 机制将 http://<ip>/placement的访问重定向到 devstack@placement-api service 处理。所以从 catalog 看见的 URL 才会长成这个样子。

  1. ProxyPass "/placement" "unix:/var/run/uwsgi/placement-api.socket|uwsgi://uwsgi-uds-placement-api/" retry=0.

当然了,这种部署方式对于开发调试有着诸多不便,所以开发者可以直接执行指令 placement-api 来启动一个用于测试的 API 服务进程。

  1. [root@control01 placement]# placement-api

  2. ...

  3. ********************************************************************************

  4. STARTING test server placement.wsgi.init_application

  5. Available at http://control01:8000/

  6. DANGER! For testing only, do not use in production

  7. ********************************************************************************

回到正题,这里我们只关注 Web Application 层面的实现。通过 setup.cfg 我们可以找到 placement-api 的程序入口。

  1. wsgi_scripts =

  2.    placement-api = placement.wsgi:init_application

顺着入口往下撸,很快就能找到 placement-api 的实现模块和 Application 类:

  1. # file: /opt/master/placement/placement/handler.py


  2. class PlacementHandler(object):

  3.    """Serve Placement API.


  4.    Dispatch to handlers defined in ROUTE_DECLARATIONS.

  5.    """


  6.    def __init__(self, **local_config):

  7.        self._map = make_map(ROUTE_DECLARATIONS)

  8.        self.config = local_config['config']

API 的 URL Routes、HTTP Method 以及 View function 的 Mapping 实现到了 ROUTE_DECLARATIONS 字典类型对象,所有的 API Resources Class 都被封装在 plcement.handlers 包下,是一个风格非常经典的 REST API 实现。不多赘述。

Placement 参与主机调度

12月技术周 | Nova 刚生出来的 Placement 是什么东西?图1. Launch Instance 调度流程图

上图可见(红色部分)Placement 主要参与了 nova-scheduler 选择目标主机的过程。以此切入,继续深究其中的调用细节。

12月技术周 | Nova 刚生出来的 Placement 是什么东西?图2. nova-scheduler 调度主机 UML 图

对于上面整个流程,我们主要关心 nova-scheduler 对 placement-api 的两次调用。第一次,nova-scheduler 向 placement-api 请求获取一组 Allocation Candidates(分配候选人),所谓 Allocation Candidates 就是能够满足资源需求的 Resource Provider。

Example

  1. GET /allocation_candidates?resources=VCPU:1,MEMORY_MB:2048,DISK_GB:100

NOTE:获取 Allocation Candidates 的实现是一系列复杂的数据库级联查询,以 query params 作为过滤条件。该例子传递了 Launch Instance 所需的 vCPU、RAM 和 Disk 资源,除此之外,还可以提供 required 和 member_of 参数,分别用于指定 Resource Traits 和 Resource Provider Aggregate 特性,使 Allocation Candidates 的获取方式更加灵活。

  1. [root@control01 ~]# openstack allocation candidate list --resource VCPU=1,MEMORY_MB=2048,DISK_GB=10 --required HW_CPU_X86_SSE2

  2. +---+----------------------------------+--------------------------------------+----------------------------------------------+--------------------------------------------------------------+

  3. | # | allocation                       | resource provider                    | inventory used/capacity                      | traits                                                       |

  4. +---+----------------------------------+--------------------------------------+----------------------------------------------+--------------------------------------------------------------+

  5. | 1 | VCPU=1,MEMORY_MB=2048,DISK_GB=10 | 5c5a578f-51b0-481c-b38c-7aaa3394e585 | VCPU=5/512,MEMORY_MB=3648/60670,DISK_GB=7/49 | HW_CPU_X86_SSE2,HW_CPU_X86_SSE,HW_CPU_X86_MMX,HW_CPU_X86_SVM |

  6. +---+----------------------------------+--------------------------------------+----------------------------------------------+--------------------------------------------------------------+

placement-api 返回给 nova-scheduler 的 JSON object with a list of allocation requests and a JSON object of provider summary objects 数据结构如下,关键在于 allocation_requests 和 provider_summaries 两个字段,它们在后续的 Scheduler Filters 逻辑中也发挥着重要作用。

  1. {

  2.  "allocation_requests": [

  3.    <ALLOCATION_REQUEST_1>,

  4.    ...

  5.    <ALLOCATION_REQUEST_N>

  6.  ],

  7.  "provider_summaries": {

  8.    <COMPUTE_NODE_UUID_1>: <PROVIDER_SUMMARY_1>,

  9.    ...

  10.    <COMPUTE_NODE_UUID_N>: <PROVIDER_SUMMARY_N>,

  11.  }

  12. }


  • allocation_requests:包含了所有能够满足需求的 resource provider 及其预期分配的资源清单。

  1. "allocation_requests": [

  2.        {

  3.            "allocations": {

  4.                "a99bad54-a275-4c4f-a8a3-ac00d57e5c64": {

  5.                    "resources": {

  6.                        "DISK_GB": 100

  7.                    }

  8.                },

  9.                "35791f28-fb45-4717-9ea9-435b3ef7c3b3": {

  10.                    "resources": {

  11.                        "VCPU": 1,

  12.                        "MEMORY_MB": 1024

  13.                    }

  14.                }

  15.            }

  16.        },

  17.        {

  18.            "allocations": {

  19.                "a99bad54-a275-4c4f-a8a3-ac00d57e5c64": {

  20.                    "resources": {

  21.                        "DISK_GB": 100

  22.                    }

  23.                },

  24.                "915ef8ed-9b91-4e38-8802-2e4224ad54cd": {

  25.                    "resources": {

  26.                        "VCPU": 1,

  27.                        "MEMORY_MB": 1024

  28.                    }

  29.                }

  30.            }

  31.        }

  32.    ],

NOTE:有趣的是,可以看见提供 VCPU/MEMORY 和 DISK 的 resource provider 并不相同,说明一台虚拟机的资源并非只能由一个 ComputeNode 提供,也可以是 ComputeNode 与外部 Storage Pool 组合提供。

  • provider_summaries:包含了所有满足需求的 resource providers 的各项资源总量和使用量信息。

  1. "provider_summaries": {

  2.        "a99bad54-a275-4c4f-a8a3-ac00d57e5c64": {

  3.            "resources": {

  4.                "DISK_GB": {

  5.                    "used": 0,

  6.                    "capacity": 1900

  7.                }

  8.            },

  9.            "traits": ["MISC_SHARES_VIA_AGGREGATE"],

  10.            "parent_provider_uuid": null,

  11.            "root_provider_uuid": "a99bad54-a275-4c4f-a8a3-ac00d57e5c64"

  12.        },

  13.        "35791f28-fb45-4717-9ea9-435b3ef7c3b3": {

  14.            "resources": {

  15.                "VCPU": {

  16.                    "used": 0,

  17.                    "capacity": 384

  18.                },

  19.                "MEMORY_MB": {

  20.                    "used": 0,

  21.                    "capacity": 196608

  22.                }

  23.            },

  24.            "traits": ["HW_CPU_X86_SSE2", "HW_CPU_X86_AVX2"],

  25.            "parent_provider_uuid": null,

  26.            "root_provider_uuid": "35791f28-fb45-4717-9ea9-435b3ef7c3b3"

  27.        },

  28.        "915ef8ed-9b91-4e38-8802-2e4224ad54cd": {

  29.            "resources": {

  30.                "VCPU": {

  31.                    "used": 0,

  32.                    "capacity": 384

  33.                },

  34.                "MEMORY_MB": {

  35.                    "used": 0,

  36.                    "capacity": 196608

  37.                }

  38.            },

  39.            "traits": ["HW_NIC_SRIOV"],

  40.            "parent_provider_uuid": null,

  41.            "root_provider_uuid": "915ef8ed-9b91-4e38-8802-2e4224ad54cd"

  42.        },

  43.        "f5120cad-67d9-4f20-9210-3092a79a28cf": {

  44.            "resources": {

  45.                "SRIOV_NET_VF": {

  46.                    "used": 0,

  47.                    "capacity": 8

  48.                }

  49.            },

  50.            "traits": [],

  51.            "parent_provider_uuid": "915ef8ed-9b91-4e38-8802-2e4224ad54cd",

  52.            "root_provider_uuid": "915ef8ed-9b91-4e38-8802-2e4224ad54cd"

  53.        }

  54.    }

NOTE:可以看出 SRIOV_NET_VF 亦被当做为一种资源类型,由专门的 resource provider 提供。

nova-scheduler 在获得了 Allocation Candidates 之后再进一步通过 Filtered 和 Weighed 机制来最终确定目标主机。然后再根据 allocation requests 和 provider summaries 数据结构来扣除目标主机对应的 resource provider 的资源使用量,这就是 nova-scheduler 第二次调用 placement-api 所做的事情。

这里不妨回顾一下 allocations tables 的内容:

  1. MariaDB [nova_api]> select * from allocations;

  2. +---------------------+------------+----+----------------------+--------------------------------------+-------------------+------+

  3. | created_at          | updated_at | id | resource_provider_id | consumer_id                          | resource_class_id | used |

  4. +---------------------+------------+----+----------------------+--------------------------------------+-------------------+------+

  5. | 2018-08-01 10:52:15 | NULL       |  7 |                    1 | f8d55035-389c-47b8-beea-02f00f25f5d9 |                 0 |    1 |

  6. | 2018-08-01 10:52:15 | NULL       |  8 |                    1 | f8d55035-389c-47b8-beea-02f00f25f5d9 |                 1 |  512 |

  7. | 2018-08-01 10:52:15 | NULL       |  9 |                    1 | f8d55035-389c-47b8-beea-02f00f25f5d9 |                 2 |    1 |

  8. +---------------------+------------+----+----------------------+--------------------------------------+-------------------+------+


  9. # consumer_id 消费者

  10. # resource_class_id 资源类型

  11. # resource_provider_id 资源提供者

  12. # used 分配的数量

  13. # 上述记录表示为虚拟机分配了 vCPU 1颗,RAM 512MB,Disk 1GB

显然,其中的 Consumer 就是要创建的虚拟机了。

Resource provider aggregates

Resource provider aggregates 是一个类似于 Host Aggregate 的功能,获取 Allocation Candidates 时,支持通过 member_of request query parameter 从特定的 Aggregate 中获取。Resource provider aggregates 非常适用于拥有不同主机聚合( e.g. 高性能主机聚合,大存储容量主机聚合)类型的生产场景中。

  • Create resource provider aggregates

  1. [root@control01 ~]# openstack aggregate create --zone nova host_aggregate_1

  2. +-------------------+----------------------------+

  3. | Field             | Value                      |

  4. +-------------------+----------------------------+

  5. | availability_zone | nova                       |

  6. | created_at        | 2018-12-08T05:49:55.051678 |

  7. | deleted           | False                      |

  8. | deleted_at        | None                       |

  9. | id                | 1                          |

  10. | name              | host_aggregate_1           |

  11. | updated_at        | None                       |

  12. +-------------------+----------------------------+


  13. [root@control01 ~]# openstack aggregate add host host_aggregate_1 control01

  14. +-------------------+---------------------------------+

  15. | Field             | Value                           |

  16. +-------------------+---------------------------------+

  17. | availability_zone | nova                            |

  18. | created_at        | 2018-12-08T05:49:55.000000      |

  19. | deleted           | False                           |

  20. | deleted_at        | None                            |

  21. | hosts             | [u'control01']                  |

  22. | id                | 1                               |

  23. | metadata          | {u'availability_zone': u'nova'} |

  24. | name              | host_aggregate_1                |

  25. | updated_at        | None                            |

  26. +-------------------+---------------------------------+


  27. [root@control01 ~]# openstack aggregate show host_aggregate_1

  28. +-------------------+----------------------------+

  29. | Field             | Value                      |

  30. +-------------------+----------------------------+

  31. | availability_zone | nova                       |

  32. | created_at        | 2018-12-08T05:49:55.000000 |

  33. | deleted           | False                      |

  34. | deleted_at        | None                       |

  35. | hosts             | [u'control01']             |

  36. | id                | 1                          |

  37. | name              | host_aggregate_1           |

  38. | properties        |                            |

  39. | updated_at        | None                       |

  40. +-------------------+----------------------------+


  41. [root@control01 ~]# openstack resource provider list

  42. +--------------------------------------+-----------+------------+--------------------------------------+----------------------+

  43. | uuid                                 | name      | generation | root_provider_uuid                   | parent_provider_uuid |

  44. +--------------------------------------+-----------+------------+--------------------------------------+----------------------+

  45. | 5c5a578f-51b0-481c-b38c-7aaa3394e585 | control01 |         26 | 5c5a578f-51b0-481c-b38c-7aaa3394e585 | None                 |

  46. +--------------------------------------+-----------+------------+--------------------------------------+----------------------+


  47. [root@control01 ~]# openstack resource provider aggregate list 5c5a578f-51b0-481c-b38c-7aaa3394e585

  48. +--------------------------------------+

  49. | uuid                                 |

  50. +--------------------------------------+

  51. | 5eea7084-0207-44f0-bbeb-c759e8c766a1 |

  52. +--------------------------------------+


  • List allocation cadidates filter by aggregates

  1. # REQ

  2. curl -i "http://172.18.22.222/placement/allocation_candidates?resources=VCPU:1,MEMORY_MB:512,DISK_GB:5&member_of=5eea7084-0207-44f0-bbeb-c759e8c766a1"

  3. -X GET

  4. -H 'Content-type: application/json'

  5. -H 'Accept: application/json'

  6. -H 'X-Auth-Project-Id: admin'

  7. -H 'OpenStack-API-Version: placement 1.21'

  8. -H 'X-Auth-Token:gAAAAABcC12qN3GdLvjYXSSUODi7Dg9jTHUfcnF7I_ljmcffZjs3ignipGLj6iqDvDJ1gXkzGIDW6rRRNcXary-wPfgsb3nCWRIEiAS8LrReI4SYL1KfQiGW7j92b6zTz7RoSEBXACQ9z7UUVfeJ06n8WqVMBaSob4BeFIuHiVKpYCJNv7LR6cI'


  9. # RESP

  10. {

  11.    "provider_summaries": {

  12.        "5c5a578f-51b0-481c-b38c-7aaa3394e585": {

  13.            "traits": ["HW_CPU_X86_SSE2", "HW_CPU_X86_SSE", "HW_CPU_X86_MMX", "HW_CPU_X86_SVM"],

  14.            "resources": {

  15.                "VCPU": {

  16.                    "used": 5,

  17.                    "capacity": 512

  18.                },

  19.                "MEMORY_MB": {

  20.                    "used": 3648,

  21.                    "capacity": 60670

  22.                },

  23.                "DISK_GB": {

  24.                    "used": 7,

  25.                    "capacity": 49

  26.                }

  27.            }

  28.        }

  29.    },

  30.    "allocation_requests": [{

  31.        "allocations": {

  32.            "5c5a578f-51b0-481c-b38c-7aaa3394e585": {

  33.                "resources": {

  34.                    "VCPU": 1,

  35.                    "MEMORY_MB": 512,

  36.                    "DISK_GB": 5

  37.                }

  38.            }

  39.        }

  40.