代码改变世界

OpenStack Placement Project

2018-10-09 12:09  云物互联  阅读(2200)  评论(0编辑  收藏  举报

目录

背景

私有云的用户,尤其是传统 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,并计划在 Stein 版本中成为独立项目,期望最终能替代 nova-scheduler service。虽然现在的 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。

[root@control01 ~]# openstack catalog show placement
+-----------+------------------------------------------+
| Field     | Value                                    |
+-----------+------------------------------------------+
| endpoints | RegionOne                                |
|           |   public: http://172.18.22.222/placement |
|           |                                          |
| id        | 9b5683b4a5284369bafad76944a0610f         |
| name      | placement                                |
| type      | placement                                |
+-----------+------------------------------------------+

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

MariaDB [(none)]> use placement

MariaDB [placement]> show tables;
+------------------------------+
| Tables_in_placement          |
+------------------------------+
| alembic_version              |
| allocations                  |
| consumers                    |
| inventories                  |
| placement_aggregates         |
| projects                     |
| resource_classes             |
| resource_provider_aggregates |
| resource_provider_traits     |
| resource_providers           |
| traits                       |
| users                        |
+------------------------------+

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

[root@control01 ~]# openstack versions show --service placement
+-------------+--------------+---------+---------+---------------------------------+------------------+------------------+
| Region Name | Service Type | Version | Status  | Endpoint                        | Min Microversion | Max Microversion |
+-------------+--------------+---------+---------+---------------------------------+------------------+------------------+
| RegionOne   | placement    | 1.0     | CURRENT | http://172.18.22.222/placement/ | 1.0              | 1.30             |
+-------------+--------------+---------+---------+---------------------------------+------------------+------------------+

基本概念

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

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

[root@control01 ~]# export OS_PLACEMENT_API_VERSION=1.17

[root@control01 ~]# openstack resource class list
+----------------------------+
| name                       |
+----------------------------+
| VCPU                       |
| MEMORY_MB                  |
| DISK_GB                    |
| PCI_DEVICE                 |
| SRIOV_NET_VF               |
| NUMA_SOCKET                |
| NUMA_CORE                  |
| NUMA_THREAD                |
| NUMA_MEMORY_MB             |
| IPV4_ADDRESS               |
| VGPU                       |
| VGPU_DISPLAY_HEAD          |
| NET_BW_EGR_KILOBIT_PER_SEC |
| NET_BW_IGR_KILOBIT_PER_SEC |
+----------------------------+

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 的属性

MariaDB [nova_api]> desc inventories;
+----------------------+----------+------+-----+---------+----------------+
| Field                | Type     | Null | Key | Default | Extra          |
+----------------------+----------+------+-----+---------+----------------+
| created_at           | datetime | YES  |     | NULL    |                |
| updated_at           | datetime | YES  |     | NULL    |                |
| id                   | int(11)  | NO   | PRI | NULL    | auto_increment |
| resource_provider_id | int(11)  | NO   | MUL | NULL    |                |
| resource_class_id    | int(11)  | NO   | MUL | NULL    |                |
| total                | int(11)  | NO   |     | NULL    |                |  总大小
| reserved             | int(11)  | NO   |     | NULL    |                |  保留大小
| min_unit             | int(11)  | NO   |     | NULL    |                |  最小分配单位
| max_unit             | int(11)  | NO   |     | NULL    |                |  最大分配单位
| step_size            | int(11)  | NO   |     | NULL    |                |  步长
| allocation_ratio     | float    | NO   |     | NULL    |                |  超分比
+----------------------+----------+------+-----+---------+----------------+

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

MariaDB [nova_api]> select * from resource_providers;
+---------------------+---------------------+-----+--------------------------------------+------------------------------------------------------+------------+----------+
| created_at          | updated_at          | id  | uuid                                 | name                                                 | generation | can_host |
+---------------------+---------------------+-----+--------------------------------------+------------------------------------------------------+------------+----------+
| 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 |

MariaDB [nova_api]> select * from inventories;
+---------------------+---------------------+----+----------------------+-------------------+--------+----------+----------+----------+-----------+------------------+
| created_at          | updated_at          | id | resource_provider_id | resource_class_id | total  | reserved | min_unit | max_unit | step_size | allocation_ratio |
+---------------------+---------------------+----+----------------------+-------------------+--------+----------+----------+----------+-----------+------------------+
| 2018-05-03 09:07:07 | 2018-07-02 07:03:57 |  1 |                    1 |                 0 |     42 |        0 |        1 |       42 |         1 |                2 |
| 2018-05-03 09:07:07 | 2018-07-02 07:03:57 |  2 |                    1 |                 1 | 407562 |     2048 |        1 |   407562 |         1 |                1 |
| 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 资源。

MariaDB [nova_api]> select * from allocations;
+---------------------+------------+-----+----------------------+--------------------------------------+-------------------+------+
| created_at          | updated_at | id  | resource_provider_id | consumer_id                          | resource_class_id | used |
+---------------------+------------+-----+----------------------+--------------------------------------+-------------------+------+
| 2018-05-23 10:40:49 | NULL       |  97 |                   97 | 648bda64-1d7a-44d2-ba38-20c84959dabe |                 0 |    1 |
| 2018-05-23 10:40:49 | NULL       |  98 |                   97 | 648bda64-1d7a-44d2-ba38-20c84959dabe |                 1 |  256 |
| 2018-05-23 10:40:49 | NULL       |  99 |                   97 | 648bda64-1d7a-44d2-ba38-20c84959dabe |                 2 |    1 |

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

MariaDB [nova_api]> select * from allocations;
+---------------------+------------+----+----------------------+--------------------------------------+-------------------+------+
| created_at          | updated_at | id | resource_provider_id | consumer_id                          | resource_class_id | used |
+---------------------+------------+----+----------------------+--------------------------------------+-------------------+------+
| 2018-08-01 10:52:15 | NULL       |  7 |                    1 | f8d55035-389c-47b8-beea-02f00f25f5d9 |                 0 |    1 |
| 2018-08-01 10:52:15 | NULL       |  8 |                    1 | f8d55035-389c-47b8-beea-02f00f25f5d9 |                 1 |  512 |
| 2018-08-01 10:52:15 | NULL       |  9 |                    1 | f8d55035-389c-47b8-beea-02f00f25f5d9 |                 2 |    1 |
+---------------------+------------+----+----------------------+--------------------------------------+-------------------+------+

# consumer_id 消费者
# resource_class_id 资源类型
# resource_provider_id 资源提供者
# used 分配的数量

Command Line

Placement CLI 以 OS Client Placement Plugin 的形式提供,是 openstackclient 子命令的扩展。

Installation

pip install python-openstackclient
pip install osc-placement

EXAMPLE

[root@control01 ~]# export OS_PLACEMENT_API_VERSION=1.17

[root@control01 ~]# openstack resource provider list
+--------------------------------------+-----------+------------+--------------------------------------+----------------------+
| uuid                                 | name      | generation | root_provider_uuid                   | parent_provider_uuid |
+--------------------------------------+-----------+------------+--------------------------------------+----------------------+
| 5c5a578f-51b0-481c-b38c-7aaa3394e585 | control01 |         25 | 5c5a578f-51b0-481c-b38c-7aaa3394e585 | None                 |
+--------------------------------------+-----------+------------+--------------------------------------+----------------------+

[root@control01 ~]# openstack resource provider inventory list 5c5a578f-51b0-481c-b38c-7aaa3394e585
+----------------+------------------+----------+----------+-----------+----------+-------+
| resource_class | allocation_ratio | max_unit | reserved | step_size | min_unit | total |
+----------------+------------------+----------+----------+-----------+----------+-------+
| VCPU           |             16.0 |       32 |        0 |         1 |        1 |    32 |
| MEMORY_MB      |              1.5 |    40959 |      512 |         1 |        1 | 40959 |
| DISK_GB        |              1.0 |       49 |        0 |         1 |        1 |    49 |
+----------------+------------------+----------+----------+-----------+----------+-------+

[root@control01 ~]# openstack resource provider usage show 5c5a578f-51b0-481c-b38c-7aaa3394e585
+----------------+-------+
| resource_class | usage |
+----------------+-------+
| VCPU           |     5 |
| MEMORY_MB      |  3648 |
| DISK_GB        |     7 |
+----------------+-------+

[root@control01 ~]# openstack allocation candidate list --resource VCPU=1
+---+------------+--------------------------------------+-------------------------+--------------------------------------------------------------+
| # | allocation | resource provider                    | inventory used/capacity | traits                                                       |
+---+------------+--------------------------------------+-------------------------+--------------------------------------------------------------+
| 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 |
+---+------------+--------------------------------------+-------------------------+--------------------------------------------------------------+

更多详细请浏览 Command Line Reference

NOTE:这里指定 micro-version 为 1.17,通过环境变量 OS_PLACEMENT_API_VERSION 指定,也可以通过 request header OpenStack-API-Version: placement 1.17 指定。详细的版本 ChangeLog 请浏览 Placement API

Placement Web Application 的实现与分析

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

/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 服务。
— — 范桂飓’s 博客

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

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

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

[root@control01 placement]# placement-api
...
********************************************************************************
STARTING test server placement.wsgi.init_application
Available at http://control01:8000/
DANGER! For testing only, do not use in production
********************************************************************************

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

wsgi_scripts =
    placement-api = placement.wsgi:init_application

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

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

class PlacementHandler(object):
    """Serve Placement API.

    Dispatch to handlers defined in ROUTE_DECLARATIONS.
    """

    def __init__(self, **local_config):
        self._map = make_map(ROUTE_DECLARATIONS)
        self.config = local_config['config']

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

Placement 在启动虚拟机时的调度过程

在这里插入图片描述

图1. Launch Instance 流程图

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

在这里插入图片描述
图2. nova-scheduler 调度主机 UML 图

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

EXAMPLE

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 的获取方式更加灵活。更多详情请浏览 Allocation candidates

PS:版本较新的 placement-api 还支持 allocation candidate 指令行操作。

[root@control01 ~]# openstack allocation candidate list --resource VCPU=1,MEMORY_MB=2048,DISK_GB=10 --required HW_CPU_X86_SSE2
+---+----------------------------------+--------------------------------------+----------------------------------------------+--------------------------------------------------------------+
| # | allocation                       | resource provider                    | inventory used/capacity                      | traits                                                       |
+---+----------------------------------+--------------------------------------+----------------------------------------------+--------------------------------------------------------------+
| 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 |
+---+----------------------------------+--------------------------------------+----------------------------------------------+--------------------------------------------------------------+

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 逻辑中也发挥着重要的作用。

{
  "allocation_requests": [
    <ALLOCATION_REQUEST_1>,
    ...
    <ALLOCATION_REQUEST_N>
  ],
  "provider_summaries": {
    <COMPUTE_NODE_UUID_1>: <PROVIDER_SUMMARY_1>,
    ...
    <COMPUTE_NODE_UUID_N>: <PROVIDER_SUMMARY_N>,
  }
}
  • allocation_requests:包含了所有能够满足需求的 resource provider 及其预期分配的资源清单。
"allocation_requests": [
        {
            "allocations": {
                "a99bad54-a275-4c4f-a8a3-ac00d57e5c64": {
                    "resources": {
                        "DISK_GB": 100
                    }
                },
                "35791f28-fb45-4717-9ea9-435b3ef7c3b3": {
                    "resources": {
                        "VCPU": 1,
                        "MEMORY_MB": 1024
                    }
                }
            }
        },
        {
            "allocations": {
                "a99bad54-a275-4c4f-a8a3-ac00d57e5c64": {
                    "resources": {
                        "DISK_GB": 100
                    }
                },
                "915ef8ed-9b91-4e38-8802-2e4224ad54cd": {
                    "resources": {
                        "VCPU": 1,
                        "MEMORY_MB": 1024
                    }
                }
            }
        }
    ],

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

  • provider_summaries:包含了所有满足需求的 resource providers 的各项资源总量和使用量信息。
 "provider_summaries": {
        "a99bad54-a275-4c4f-a8a3-ac00d57e5c64": {
            "resources": {
                "DISK_GB": {
                    "used": 0,
                    "capacity": 1900
                }
            },
            "traits": ["MISC_SHARES_VIA_AGGREGATE"],
            "parent_provider_uuid": null,
            "root_provider_uuid": "a99bad54-a275-4c4f-a8a3-ac00d57e5c64"
        },
        "35791f28-fb45-4717-9ea9-435b3ef7c3b3": {
            "resources": {
                "VCPU": {
                    "used": 0,
                    "capacity": 384
                },
                "MEMORY_MB": {
                    "used": 0,
                    "capacity": 196608
                }
            },
            "traits": ["HW_CPU_X86_SSE2", "HW_CPU_X86_AVX2"],
            "parent_provider_uuid": null,
            "root_provider_uuid": "35791f28-fb45-4717-9ea9-435b3ef7c3b3"
        },
        "915ef8ed-9b91-4e38-8802-2e4224ad54cd": {
            "resources": {
                "VCPU": {
                    "used": 0,
                    "capacity": 384
                },
                "MEMORY_MB": {
                    "used": 0,
                    "capacity": 196608
                }
            },
            "traits": ["HW_NIC_SRIOV"],
            "parent_provider_uuid": null,
            "root_provider_uuid": "915ef8ed-9b91-4e38-8802-2e4224ad54cd"
        },
        "f5120cad-67d9-4f20-9210-3092a79a28cf": {
            "resources": {
                "SRIOV_NET_VF": {
                    "used": 0,
                    "capacity": 8
                }
            },
            "traits": [],
            "parent_provider_uuid": "915ef8ed-9b91-4e38-8802-2e4224ad54cd",
            "root_provider_uuid": "915ef8ed-9b91-4e38-8802-2e4224ad54cd"
        }
    }

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

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

MariaDB [nova_api]> select * from allocations;
+---------------------+------------+----+----------------------+--------------------------------------+-------------------+------+
| created_at          | updated_at | id | resource_provider_id | consumer_id                          | resource_class_id | used |
+---------------------+------------+----+----------------------+--------------------------------------+-------------------+------+
| 2018-08-01 10:52:15 | NULL       |  7 |                    1 | f8d55035-389c-47b8-beea-02f00f25f5d9 |                 0 |    1 |
| 2018-08-01 10:52:15 | NULL       |  8 |                    1 | f8d55035-389c-47b8-beea-02f00f25f5d9 |                 1 |  512 |
| 2018-08-01 10:52:15 | NULL       |  9 |                    1 | f8d55035-389c-47b8-beea-02f00f25f5d9 |                 2 |    1 |
+---------------------+------------+----+----------------------+--------------------------------------+-------------------+------+

# consumer_id 消费者
# resource_class_id 资源类型
# resource_provider_id 资源提供者
# used 分配的数量
# 上述记录表示为虚拟机分配了 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
[root@control01 ~]# openstack aggregate create --zone nova host_aggregate_1
+-------------------+----------------------------+
| Field             | Value                      |
+-------------------+----------------------------+
| availability_zone | nova                       |
| created_at        | 2018-12-08T05:49:55.051678 |
| deleted           | False                      |
| deleted_at        | None                       |
| id                | 1                          |
| name              | host_aggregate_1           |
| updated_at        | None                       |
+-------------------+----------------------------+

[root@control01 ~]# openstack aggregate add host host_aggregate_1 control01
+-------------------+---------------------------------+
| Field             | Value                           |
+-------------------+---------------------------------+
| availability_zone | nova                            |
| created_at        | 2018-12-08T05:49:55.000000      |
| deleted           | False                           |
| deleted_at        | None                            |
| hosts             | [u'control01']                  |
| id                | 1                               |
| metadata          | {u'availability_zone': u'nova'} |
| name              | host_aggregate_1                |
| updated_at        | None                            |
+-------------------+---------------------------------+

[root@control01 ~]# openstack aggregate show host_aggregate_1
+-------------------+----------------------------+
| Field             | Value                      |
+-------------------+----------------------------+
| availability_zone | nova                       |
| created_at        | 2018-12-08T05:49:55.000000 |
| deleted           | False                      |
| deleted_at        | None                       |
| hosts             | [u'control01']             |
| id                | 1                          |
| name              | host_aggregate_1           |
| properties        |                            |
| updated_at        | None                       |
+-------------------+----------------------------+

[root@control01 ~]# openstack resource provider list
+--------------------------------------+-----------+------------+--------------------------------------+----------------------+
| uuid                                 | name      | generation | root_provider_uuid                   | parent_provider_uuid |
+--------------------------------------+-----------+------------+--------------------------------------+----------------------+
| 5c5a578f-51b0-481c-b38c-7aaa3394e585 | control01 |         26 | 5c5a578f-51b0-481c-b38c-7aaa3394e585 | None                 |
+--------------------------------------+-----------+------------+--------------------------------------+----------------------+

[root@control01 ~]# openstack resource provider aggregate list 5c5a578f-51b0-481c-b38c-7aaa3394e585
+--------------------------------------+
| uuid                                 |
+--------------------------------------+
| 5eea7084-0207-44f0-bbeb-c759e8c766a1 |
+--------------------------------------+
  • List allocation cadidates filter by aggregates
# REQ
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" \
-X GET \
-H 'Content-type: application/json' \
-H 'Accept: application/json' \
-H 'X-Auth-Project-Id: admin' \
-H 'OpenStack-API-Version: placement 1.21' \
-H 'X-Auth-Token:gAAAAABcC12qN3GdLvjYXSSUODi7Dg9jTHUfcnF7I_ljmcffZjs3ignipGLj6iqDvDJ1gXkzGIDW6rRRNcXary-wPfgsb3nCWRIEiAS8LrReI4SYL1KfQiGW7j92b6zTz7RoSEBXACQ9z7UUVfeJ06n8WqVMBaSob4BeFIuHiVKpYCJNv7LR6cI'

# RESP
{
	"provider_summaries": {
		"5c5a578f-51b0-481c-b38c-7aaa3394e585": {
			"traits": ["HW_CPU_X86_SSE2", "HW_CPU_X86_SSE", "HW_CPU_X86_MMX", "HW_CPU_X86_SVM"],
			"resources": {
				"VCPU": {
					"used": 5,
					"capacity": 512
				},
				"MEMORY_MB": {
					"used": 3648,
					"capacity": 60670
				},
				"DISK_GB": {
					"used": 7,
					"capacity": 49
				}
			}
		}
	},
	"allocation_requests": [{
		"allocations": {
			"5c5a578f-51b0-481c-b38c-7aaa3394e585": {
				"resources": {
					"VCPU": 1,
					"MEMORY_MB": 512,
					"DISK_GB": 5
				}
			}
		}
	}]
}

Resource traits 功能测试

Resource traits 特征标签功能,用于标识 Resource Provider 的特征性质,每个 Resource Provider 有着其各自的缺省 traits,也支持为指定的 Resource Provider 自定义 traits。

Resource traits 是非常灵活的一种设计,类似于 “标签” 的作用,用户可以建立起 “标签云” 并决定为某一个 Resource Provider 贴上 “标签”,是一种资源归纳分类需求的辅助工具。

  • List traits
curl -i "http://172.18.22.222/placement/traits" \
-X GET \
-H 'Content-type: application/json' \
-H 'Accept: application/json' \
-H 'X-Auth-Project-Id: admin' \
-H 'OpenStack-API-Version: placement 1.21' \
-H 'X-Auth-Token:gAAAAABcC12qN3GdLvjYXSSUODi7Dg9jTHUfcnF7I_ljmcffZjs3ignipGLj6iqDvDJ1gXkzGIDW6rRRNcXary-wPfgsb3nCWRIEiAS8LrReI4SYL1KfQiGW7j92b6zTz7RoSEBXACQ9z7UUVfeJ06n8WqVMBaSob4BeFIuHiVKpYCJNv7LR6cI'
  • Create custom traits
curl -i "http://172.18.22.222/placement/traits/CUSTOM_FANGUIJU_HOST" \
-X PUT \
-H 'Content-type: application/json' \
-H 'Accept: application/json' \
-H 'X-Auth-Project-Id: admin' \
-H 'OpenStack-API-Version: placement 1.21' \
-H 'X-Auth-Token:gAAAAABcC12qN3GdLvjYXSSUODi7Dg9jTHUfcnF7I_ljmcffZjs3ignipGLj6iqDvDJ1gXkzGIDW6rRRNcXary-wPfgsb3nCWRIEiAS8LrReI4SYL1KfQiGW7j92b6zTz7RoSEBXACQ9z7UUVfeJ06n8WqVMBaSob4BeFIuHiVKpYCJNv7LR6cI'

NOTE:自定义 traits 建议以 CUSTOM_ 开头。

  • Update all traits for a specific resource provider
curl -i "http://172.18.22.222/placement/resource_providers/5c5a578f-51b0-481c-b38c-7aaa3394e585/traits" \
-X PUT \
-H 'Content-type: application/json' \
-H 'Accept: application/json' \
-H 'X-Auth-Project-Id: admin' \
-H 'OpenStack-API-Version: placement 1.21' \
-H 'X-Auth-Token:gAAAAABcC12qN3GdLvjYXSSUODi7Dg9jTHUfcnF7I_ljmcffZjs3ignipGLj6iqDvDJ1gXkzGIDW6rRRNcXary-wPfgsb3nCWRIEiAS8LrReI4SYL1KfQiGW7j92b6zTz7RoSEBXACQ9z7UUVfeJ06n8WqVMBaSob4BeFIuHiVKpYCJNv7LR6cI' \
-d '{"resource_provider_generation": 28, "traits": ["HW_CPU_X86_SSE2", "HW_CPU_X86_SSE", "HW_CPU_X86_MMX", "HW_CPU_X86_SVM", "CUSTOM_FANGUIJU_HOST"]}'
  • Return all traits associated with a specific resource provider
[root@control01 ~]# openstack resource provider trait list 5c5a578f-51b0-481c-b38c-7aaa3394e585
+----------------------+
| name                 |
+----------------------+
| HW_CPU_X86_SSE2      |
| HW_CPU_X86_SSE       |
| HW_CPU_X86_MMX       |
| HW_CPU_X86_SVM       |
| CUSTOM_FANGUIJU_HOST |
+----------------------+
  • List allocation cadidates filter by traits
# REQ
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&required=CUSTOM_FANGUIJU_HOST" \
-X GET \
-H 'Content-type: application/json' \
-H 'Accept: application/json' \
-H 'X-Auth-Project-Id: admin' \
-H 'OpenStack-API-Version: placement 1.21' \
-H 'X-Auth-Token:gAAAAABcC12qN3GdLvjYXSSUODi7Dg9jTHUfcnF7I_ljmcffZjs3ignipGLj6iqDvDJ1gXkzGIDW6rRRNcXary-wPfgsb3nCWRIEiAS8LrReI4SYL1KfQiGW7j92b6zTz7RoSEBXACQ9z7UUVfeJ06n8WqVMBaSob4BeFIuHiVKpYCJNv7LR6cI'

# RESP
{
	"provider_summaries": {
		"5c5a578f-51b0-481c-b38c-7aaa3394e585": {
			"traits": ["HW_CPU_X86_SSE2", "HW_CPU_X86_SSE", "HW_CPU_X86_MMX", "HW_CPU_X86_SVM", "CUSTOM_FANGUIJU_HOST"],
			"resources": {
				"VCPU": {
					"used": 5,
					"capacity": 512
				},
				"MEMORY_MB": {
					"used": 3648,
					"capacity": 60670
				},
				"DISK_GB": {
					"used": 7,
					"capacity": 49
				}
			}
		}
	},
	"allocation_requests": [{
		"allocations": {
			"5c5a578f-51b0-481c-b38c-7aaa3394e585": {
				"resources": {
					"VCPU": 1,
					"MEMORY_MB": 512,
					"DISK_GB": 5
				}
			}
		}
	}]
}

最后

至此,对目前最新的 Placement 实现做一个概括性的介绍和分析。笔者认为 Placement 的核心价值还是在于其高度的 “灵活性” 上,可以适配用户在生产环境中的复杂多样的资源管理需求,也为云平台开发者带来了一种代码方案的可行性。如果以后能够提供 API 来支持可视化的资源管理面板,相信也会是一个不错的用户爽点。美中不足的是,笔者认为 Placement 的数据库设计似乎缺乏弹性,哪怕追加一个 metadata 字段,对开发者而言也算是只一种慰藉。

扩展阅读

《OpenStack 2018 年终盘点》