孤立资源分配

问题

在 Placement 服务中存在孤立资源分配,这可能导致资源提供者

  • 向调度器显示比实际更多的利用率

  • 阻止删除计算服务

一种可能发生这种情况的场景是,计算服务主机遇到问题,管理员强制其下线并从其上撤离服务器。请注意,在这种情况下,“撤离”指的是服务器 evacuate 操作,而不是从正在运行的计算服务中实时迁移所有服务器。假设计算主机已下线并已隔离。

在这种情况下,服务器的分配在 Placement 中针对已下线的源计算节点和其当前目标计算主机进行跟踪。例如,这里有一个服务器 vm1,它已从节点 devstack1 撤离到节点 devstack2

$ openstack --os-compute-api-version 2.53 compute service list --service nova-compute
+--------------------------------------+--------------+-----------+------+---------+-------+----------------------------+
| ID                                   | Binary       | Host      | Zone | Status  | State | Updated At                 |
+--------------------------------------+--------------+-----------+------+---------+-------+----------------------------+
| e3c18c2d-9488-4863-b728-f3f292ec5da8 | nova-compute | devstack1 | nova | enabled | down  | 2019-10-25T20:13:51.000000 |
| 50a20add-cc49-46bd-af96-9bb4e9247398 | nova-compute | devstack2 | nova | enabled | up    | 2019-10-25T20:13:52.000000 |
| b92afb2e-cd00-4074-803e-fff9aa379c2f | nova-compute | devstack3 | nova | enabled | up    | 2019-10-25T20:13:53.000000 |
+--------------------------------------+--------------+-----------+------+---------+-------+----------------------------+
$ vm1=$(openstack server show vm1 -f value -c id)
$ openstack server show $vm1 -f value -c OS-EXT-SRV-ATTR:host
devstack2

现在,服务器在 Placement 服务中的 devstack1devstack2 资源提供者上都有分配

$ devstack1=$(openstack resource provider list --name devstack1 -f value -c uuid)
$ devstack2=$(openstack resource provider list --name devstack2 -f value -c uuid)
$ openstack resource provider show --allocations $devstack1
+-------------+-----------------------------------------------------------------------------------------------------------+
| Field       | Value                                                                                                     |
+-------------+-----------------------------------------------------------------------------------------------------------+
| uuid        | 9546fce4-9fb5-4b35-b277-72ff125ad787                                                                      |
| name        | devstack1                                                                                                 |
| generation  | 6                                                                                                         |
| allocations | {u'a1e6e0b2-9028-4166-b79b-c177ff70fbb7': {u'resources': {u'VCPU': 1, u'MEMORY_MB': 512, u'DISK_GB': 1}}} |
+-------------+-----------------------------------------------------------------------------------------------------------+
$ openstack resource provider show --allocations $devstack2
+-------------+-----------------------------------------------------------------------------------------------------------+
| Field       | Value                                                                                                     |
+-------------+-----------------------------------------------------------------------------------------------------------+
| uuid        | 52d0182d-d466-4210-8f0d-29466bb54feb                                                                      |
| name        | devstack2                                                                                                 |
| generation  | 3                                                                                                         |
| allocations | {u'a1e6e0b2-9028-4166-b79b-c177ff70fbb7': {u'resources': {u'VCPU': 1, u'MEMORY_MB': 512, u'DISK_GB': 1}}} |
+-------------+-----------------------------------------------------------------------------------------------------------+
$ openstack --os-placement-api-version 1.12 resource provider allocation show $vm1
+--------------------------------------+------------+------------------------------------------------+----------------------------------+----------------------------------+
| resource_provider                    | generation | resources                                      | project_id                       | user_id                          |
+--------------------------------------+------------+------------------------------------------------+----------------------------------+----------------------------------+
| 9546fce4-9fb5-4b35-b277-72ff125ad787 |          6 | {u'VCPU': 1, u'MEMORY_MB': 512, u'DISK_GB': 1} | 2f3bffc5db2b47deb40808a4ed2d7c7a | 2206168427c54d92ae2b2572bb0da9af |
| 52d0182d-d466-4210-8f0d-29466bb54feb |          3 | {u'VCPU': 1, u'MEMORY_MB': 512, u'DISK_GB': 1} | 2f3bffc5db2b47deb40808a4ed2d7c7a | 2206168427c54d92ae2b2572bb0da9af |
+--------------------------------------+------------+------------------------------------------------+----------------------------------+----------------------------------+

一种查找所有从 devstack1 撤离的服务器的方法是

$ nova migration-list --source-compute devstack1 --migration-type evacuation
+----+--------------------------------------+-------------+-----------+----------------+--------------+-------------+--------+--------------------------------------+------------+------------+----------------------------+----------------------------+------------+
| Id | UUID                                 | Source Node | Dest Node | Source Compute | Dest Compute | Dest Host   | Status | Instance UUID                        | Old Flavor | New Flavor | Created At                 | Updated At                 | Type       |
+----+--------------------------------------+-------------+-----------+----------------+--------------+-------------+--------+--------------------------------------+------------+------------+----------------------------+----------------------------+------------+
| 1  | 8a823ba3-e2e9-4f17-bac5-88ceea496b99 | devstack1   | devstack2 | devstack1      | devstack2    | 192.168.0.1 | done   | a1e6e0b2-9028-4166-b79b-c177ff70fbb7 | None       | None       | 2019-10-25T17:46:35.000000 | 2019-10-25T17:46:37.000000 | evacuation |
+----+--------------------------------------+-------------+-----------+----------------+--------------+-------------+--------+--------------------------------------+------------+------------+----------------------------+----------------------------+------------+

尝试删除 devstack1 的资源提供者将在其上存在分配时失败

$ openstack resource provider delete $devstack1
Unable to delete resource provider 9546fce4-9fb5-4b35-b277-72ff125ad787: Resource provider has allocations. (HTTP 409)

解决方案

使用上面的示例资源,从 devstack1 资源提供者中删除服务器 vm1 的分配。如果您拥有 osc-placement 1.8.0 或更高版本,可以使用 openstack resource provider allocation unset 命令从资源提供者 devstack1 中删除消费者 vm1 的分配

$ openstack --os-placement-api-version 1.12 resource provider allocation \
    unset --provider $devstack1 $vm1
+--------------------------------------+------------+------------------------------------------------+----------------------------------+----------------------------------+
| resource_provider                    | generation | resources                                      | project_id                       | user_id                          |
+--------------------------------------+------------+------------------------------------------------+----------------------------------+----------------------------------+
| 52d0182d-d466-4210-8f0d-29466bb54feb |          4 | {u'VCPU': 1, u'MEMORY_MB': 512, u'DISK_GB': 1} | 2f3bffc5db2b47deb40808a4ed2d7c7a | 2206168427c54d92ae2b2572bb0da9af |
+--------------------------------------+------------+------------------------------------------------+----------------------------------+----------------------------------+

如果您拥有 osc-placement 1.7.x 或更早版本,则 unset 命令不可用,您必须改用覆盖分配。请注意,我们这里不使用 openstack resource provider allocation delete,因为这将从所有资源提供者(包括 devstack2,服务器现在正在运行的地方)删除服务器的分配;相反,我们使用 openstack resource provider allocation set 来覆盖分配并仅保留 devstack2 提供者的分配。如果您删除了给定服务器的所有分配,稍后可以修复它们。有关详细信息,请参阅 使用 heal_allocations

$ openstack --os-placement-api-version 1.12 resource provider allocation set $vm1 \
    --project-id 2f3bffc5db2b47deb40808a4ed2d7c7a \
    --user-id 2206168427c54d92ae2b2572bb0da9af \
    --allocation rp=52d0182d-d466-4210-8f0d-29466bb54feb,VCPU=1 \
    --allocation rp=52d0182d-d466-4210-8f0d-29466bb54feb,MEMORY_MB=512 \
    --allocation rp=52d0182d-d466-4210-8f0d-29466bb54feb,DISK_GB=1
+--------------------------------------+------------+------------------------------------------------+----------------------------------+----------------------------------+
| resource_provider                    | generation | resources                                      | project_id                       | user_id                          |
+--------------------------------------+------------+------------------------------------------------+----------------------------------+----------------------------------+
| 52d0182d-d466-4210-8f0d-29466bb54feb |          4 | {u'VCPU': 1, u'MEMORY_MB': 512, u'DISK_GB': 1} | 2f3bffc5db2b47deb40808a4ed2d7c7a | 2206168427c54d92ae2b2572bb0da9af |
+--------------------------------------+------------+------------------------------------------------+----------------------------------+----------------------------------+

一旦使用上述任何一种方法删除了 devstack1 资源提供者的分配,就可以删除 devstack1 资源提供者

$ openstack resource provider delete $devstack1

以及相关的计算服务(如果需要)

$ openstack --os-compute-api-version 2.53 compute service delete e3c18c2d-9488-4863-b728-f3f292ec5da8

有关本指南中使用的资源提供者命令的更多详细信息,请参阅 osc-placement 插件文档

使用 heal_allocations

如果您有一个特别棘手的分配消费者,只想从所有提供者中删除其分配,可以使用 openstack resource provider allocation delete 命令,然后使用 heal_allocations 命令 修复消费者的分配。例如

$ openstack resource provider allocation delete $vm1
$ nova-manage placement heal_allocations --verbose --instance $vm1
Looking for instances in cell: 04879596-d893-401c-b2a6-3d3aa096089d(cell1)
Found 1 candidate instances.
Successfully created allocations for instance a1e6e0b2-9028-4166-b79b-c177ff70fbb7.
Processed 1 instances.
$ openstack resource provider allocation show $vm1
+--------------------------------------+------------+------------------------------------------------+
| resource_provider                    | generation | resources                                      |
+--------------------------------------+------------+------------------------------------------------+
| 52d0182d-d466-4210-8f0d-29466bb54feb |          5 | {u'VCPU': 1, u'MEMORY_MB': 512, u'DISK_GB': 1} |
+--------------------------------------+------------+------------------------------------------------+

请注意,删除分配然后依赖 heal_allocations 可能并非总是最佳解决方案,因为修复分配并不能考虑某些事项

  • 基于迁移的分配如果在调整大小期间手动删除,将会丢失。这些是在迁移期间在源计算服务上跟踪的迁移资源记录的分配。

  • 修复分配仅部分支持嵌套分配。从 20.0.0 (Train) 版本开始,由于 Neutron 端口具有 QoS 策略而导致的嵌套分配受支持。但是,由于 flavor 中 vGPU 或 Cyborg 设备配置文件请求而导致的嵌套分配不受支持。此外,如果您在计算主机上使用 provider.yaml 文件来定义其他资源,如果这些资源在子资源提供者上定义,则使用这些资源的实例不受支持。

如果您使用 heal_allocations 命令清理特定麻烦实例的分配,建议记录分配在删除它们之前是什么,以防以后需要手动重置它们。使用 openstack resource provider allocation show 命令在删除它们之前获取消费者的分配,例如:

$ openstack --os-placement-api-version 1.12 resource provider allocation show $vm1

使用 Placement 审计

如果您遇到过去已删除的实例存在孤立分配的情况,例如日志消息

Instance <uuid> has allocations against this compute host but is not found in the database.

您可以使用 nova-manage placement audit 工具来查找并选择性地删除孤立的 Placement 分配。此工具将调用 Placement API 来修改分配。

要列出与现有实例或迁移 UUID 无关的所有分配

$ nova-manage placement audit --verbose

要删除所有资源提供者上与现有实例或迁移 UUID 无关的所有分配

$ nova-manage placement audit --verbose --delete

要删除特定资源提供者上与现有实例或迁移 UUID 无关的所有分配

$ nova-manage placement audit --verbose --delete --resource-provider <uuid>