刷新配额使用情况

https://blueprints.launchpad.net/nova/+spec/refresh-quotas-usage

由于某些原因[*],配额使用情况可能会不同步。当配额被错误地达到时,用户将无法启动新的虚拟机。此“刷新”功能允许操作员快速解除用户阻塞,而无需手动对数据库运行查询或临时增加配额。

问题描述

配额使用情况在 quota_usages 表中可能不同步。已用资源的数量可能无法反映实际使用情况。例如,我们可能会看到使用了 7 个核心,而实际使用情况仅为 4 个。

用例

如果某个资源的配额被错误地达到,最终用户可能会被阻止。

如果在 Nova 中实现了刷新配额使用情况功能,操作员可以在不直接在数据库上运行 SQL 查询的情况下更正使用情况。

项目优先级

提议的变更

目前,“刷新配额使用情况”功能隐藏在 SQLAlchemy 实现中。如“替代方案”段落所述,函数 nova.db.sqlalchemy.api.quota_reserve() 可以在某些情况下刷新数据库。

更改包括

  • 在 DB API 中创建一个刷新配额使用情况的函数:nova.db.api.quota_usage_refresh()

  • nova.db.sqlalchemy.api.quota_reserve() 进行“提取函数”重构,以实现上述 quota_usage_refresh() DB API。即:nova.db.sqlalchemy.api.quota_usage_refresh()

  • 通过 nova-manage 命令公开 nova.db.api.quota_usage_refresh() 功能。

nova-manage 命令如下所示

$ nova-manage project quota_usage_refresh --project <Project name>
    --user <User name> [--key <Quota key>]

如果省略 --key,将刷新所有配额资源。

示例

$ nova-manage project quota_usage_refresh --project demo --user john_doe
    --key cores

$ nova-manage project quota_usage_refresh
    --project f85aa788e8ee48fca3da27e0579d3597
    --user 62d8d1ca423d41d3970b9ec53a340678
    --key cores

备选方案

另一个 nova-manage 命令

另一个 nova-manage 命令可以使用已经实现的 nova.quota.usage_reset() 函数。

这是该函数的文档字符串,请注意“针对特定用户”

Reset the usage records for a particular user on a list of
resources.  This will force that user's usage records to be
refreshed the next time a reservation is made.

Note: this does not affect the currently outstanding
reservations the user has; those reservations must be
committed or rolled back (or expired).

:param context: The request context, for access checks.
:param resources: A list of the resource names for which the
                  usage must be reset.

“重置”意味着“在数据库中设置为 -1”。

生成的命令将是

$ nova-manage project quota_usage_reset --project <Project name>
    --user <User name> [--key <Quota key>]

如果省略 --key,将重置所有配额资源。

优点

仅修改 nova/cmd/manage.py。与 quota_usage_refresh 不同,不需要在数据库 API 级别进行更改。

缺点

与 quota_usage_refresh 的主要区别在于,用户在下一次预订之前看不到实际的配额使用情况。

鸣谢:此命令由 Joe Gordon 提出(参见补丁集 2)

配置 Nova

我们可以在 nova.conf 中启用配额“自动刷新”,方法如下

  • until_refresh (IntOpt) 达到刷新使用情况的预订次数

  • max_age (IntOpt) 后续使用情况刷新之间的秒数

这两个设置(默认禁用)允许刷新配额使用情况,但仅在配额预订期间。算法如下

  1. 检查配额

  2. 达到 until_refresh 或 max_age 阈值?

  3. 如果是:刷新

举例说明:在租户上设置了 10 个实例的配额。

配额被错误地达到

  • nova absolute-limits 显示 totalInstancesUsed = 10

  • nova quota-show 显示 instances = 10

实际实例数量为 9 个。

当用户运行 nova boot 时,他将收到错误:“Quota exceeded”。 许多用户将在此处停止并联系他们的支持人员。 实际上,如果第一次刷新了配额使用情况(取决于 until_refresh 或 max_age 阈值),第二次 nova boot 可能会成功。 我们需要改进此行为,但此处与主题无关。

请注意,在 Horizon 上,用户将无法启动实例(对应于第一次 nova boot),因为当达到配额时按钮将被禁用。

总结

  • 需要启用 until_refresh 或 max_age,但云操作员可能不想启用它们,如果只有少数租户遇到配额使用情况错误。

  • 即使启用了这两个设置,我们也不能强制刷新。

数据模型影响

REST API 影响

策略更改

安全影响

通知影响

其他最终用户影响

性能影响

该功能以与 nova.db.sqlalchemy.api.quota_reserve() 触发刷新时相同的方式命中表 quota_usages。

其他部署者影响

开发人员影响

nova.db.api 的其他实现应实现 nova.db.api.quota_usage_refresh()

处理嵌套项目? https://blueprints.launchpad.net/nova/+spec/nested-quota-driver-api

实现

负责人

主要负责人

romain-hardouin

其他贡献者

<launchpad-id 或 None>

工作项

不是很大的变化,此 BP 可以作为一个整体提交。

两个子任务

  • 更改 DB API

  • 实现 nova-manage 命令

依赖项

测试

待根据规范反馈定义。

文档影响

记录新的 nova-manage 命令。

参考资料

作为参考,在 Horizon 侧