嵌套配额驱动API¶
https://blueprints.launchpad.net/nova/+spec/nested-quota-driver-api
嵌套配额驱动程序将使 OpenStack 能够强制执行嵌套项目中的配额。
https://specs.openstack.org/openstack/keystone-specs/specs/juno/hierarchical_multitenancy.html
问题描述¶
OpenStack 正在朝着支持项目层级所有权的方向发展。在这方面,Keystone 将改变 Openstack 的组织结构,创建嵌套项目
Nova 中现有的配额驱动程序,名为 DbQuotaDriver,在项目和项目用户级别强制执行配额非常有用,前提是所有项目都在同一级别(即,层级级别不能大于 1)。
建议开发一个新的配额驱动程序,名为 NestedQuotaDriver,通过扩展现有的 DbQuotaDriver 来实现,这将允许在 Openstack 中的嵌套项目中强制执行配额。嵌套项目具有层级结构,每个项目可能包含用户和项目(可以称为子项目)。
用户可以在每个项目内拥有不同的角色:普通用户可以使用项目的资源。项目管理员,例如,可以是一个除了被允许创建子项目、将资源配额分配给这些子项目以及将项目管理员角色分配给子项目的各个用户之外,还具有其他权限的用户。根项目的资源配额只能由根项目的管理员设置。用户角色可以设置为继承,如果设置了继承,则项目的管理员会自动成为该项目下所有项目的管理员。
用例¶
参与者
Martha - 云管理员(即角色:cloud-admin) of ProductionIT
George - 经理(即角色:project-admin) of Project CMS
John - 经理(即角色:project-admin) of Project ATLAS
Peter - 经理(即角色:project-admin) of Project Operations
Sam - 经理(即角色:project-admin) of Project Services
Paul - 经理(即角色:project-admin) of Project Computing
Jim - 经理(即角色:project-admin) of Project Visualisation
项目的嵌套结构如下。
{
ProductionIT: {
CMS : {
Computing,
Visualisation
},
ATLAS: {
Operations,
Services
}
}
}
Martha 是一个基础设施提供商,为 George 的 Project CMS 和 John 的 Project ATLAS 提供云服务。CMS 在其下方有两个子项目,名为 Visualisation 和 Computing,分别由 Jim 和 Paul 管理。ATLAS 有两个子项目,名为 Services 和 Operations,分别由 Sam 和 Peter 管理。
Martha 需要能够设置 CMS 和 ATLAS 的配额,并管理整个项目(包括根项目 ProductionIT)的配额。
George 应该能够更新 Visualisation 和 Computing 的配额。
George 应该能够查看 CMS、Visualisation 和 Computing 的配额。
George 不应该能够更新 CMS 的配额,尽管他是它的经理。只有 Martha 才能做到。
George 不应该能够查看 ATLAS 的配额。只有 John 和 Martha 才能做到。
Jim,Visualisation 的经理,不应该能够查看 CMS 的配额。Jim 应该能够仅查看 Visualisation 的配额,以及在 Visualisation 下创建的任何子项目的配额。
关于不同项目中实例数量的配额信息如下:
名称
hard_limit
used
reservedProductionIT
1000
100
100
CMS
300
25
15
Computing
100
50
50
Visualisation
150
25
25
ATLAS
400
25
25
Services
100
25
25
Computing
200
50
50
假设 Martha(根项目或云管理员的管理员)将 CMS 中实例的
hard_limit增加到 400假设 Martha 将 CMS 中实例的
hard_limit增加到 500假设 Martha 删除 CMS 的配额
假设 Martha 将 CMS 中实例的
hard_limit减少到 350假设 Martha 将 CMS 中实例的
hard_limit减少到 200假设 George(CMS 的经理)将 CMS 中实例的
hard_limit增加到 400假设 George 尝试查看 ATLAS 的配额
假设 Jim 尝试将 CMS 中实例的
hard_limit减少到 400。假设 Martha 尝试将 ProductionIT 中实例的
hard_limit增加到 2000。假设 Martha 删除 Visualisation 的配额。
假设 Martha 删除项目 Visualisation。
假设公司不希望使用嵌套结构,并希望重构为只有四个项目,即 Visualisation、Computing、Services 和 Operations。
项目优先级¶
无
提议的变更¶
任何新创建项目的默认配额(硬限制)设置为 0。零的默认值确保在多个项目由管理员同时创建时数据的一致性。假设 RAM 的默认值为 1024,A 是根项目。并且管理员正在创建 B,A 的子项目,以及另一个管理员正在创建 C,同样是 A 的子项目。现在,B 和 C 的 RAM 默认值的总和超过了 A 的默认值。为了避免这种情况,默认配额设置为零。
项目只有在将配额设置为非零值后才能创建 VM(因为默认值为 0)。创建新项目后,必须通过 Nova API 调用显式设置配额值,以确保可用配额,然后才能在项目中声明资源。
在根项目中具有“cloud-admin”角色的用户,并且具有继承的角色被称为 Cloud-Admin,允许在整个层级结构中执行配额操作,包括顶级项目。Cloud-Admin 是唯一允许设置树中根项目配额的用户。
项目中具有“project-admin”角色的用户被允许对其子项目和层级中的用户进行配额操作。如果在 Keystone 中将项目的“project-admin”角色设置为可继承,则具有此角色的用户被允许从其直接子项目到项目层级下最后一个项目/用户的配额操作。
注意:像“cloud-admin”和“project-admin”这样的角色不是硬编码的。它在本 BP 中仅用于演示目的。
一个项目的总资源消耗分为
- 已用配额 - VM 在项目中使用的资源。
(不包括子项目)
保留配额 - 项目为将来保留的资源
- 包括后代。
分配配额 - 立即子项目的配额
hard_limit值之和
- 项目内可用的
free配额计算如下 free quota = hard_limit - (used + reserved + allocated)
空闲配额不存储在数据库中;它是为每个项目动态计算的。
- 项目内可用的
只有在父项目有足够的空闲配额可用时,才允许增加项目的配额值。如果父项目有空闲配额可用,则配额更新操作将导致项目
hard_limit值及其父项目的allocated值更新。因此,应该注意的是,更新项目的配额需要令牌在父级别作用域内。项目层级为 A->B->C(A 是根项目)
名称
hard_limitusedreservedallocatedA
100
0
50
50
B
50
20
0
10
C
10
10
0
0
项目的空闲配额将是
- A:Free Quota = 100 {A:hard_limit} - ( 0 {A:used} + 0 {A:reserved} +
50 {A: 分配给 B})
A: 剩余配额 = 50
- B:Free Quota = 50 {B:hard_limit} - ( 20 {B:used} + 0 {B:reserved} +
10 {B: 分配给 C})
B: 剩余配额 = 20
- C:Free Quota = 10 {C:hard_limit} - ( 10 {C:used} + 0 {C:reserved} +
0 {C: 分配})
C: 剩余配额 = 0
如果项目 C
hard_limit增加 10,则此更改将导致名称
hard_limitusedreservedallocatedA
100
0
50
50
B
50
20
0
20
C
10
10
0
0
如果项目 C hard_limit 需要进一步增加 20,则此操作将被中止,因为其父项目即项目 B 的可用空闲配额仅为 10。因此,A 的项目管理员应首先增加项目 B 的
hard_limit(使用作用域到项目 A 的令牌,因为在 A 级别执行操作),然后增加项目 C 的hard_limit(同样作用域到项目 B 的令牌)。请考虑上述用例。各种项目的配额信息,包括分配的配额如下,
ProductionIT : hard_limit=1000, used=100, reserved=100, allocated=700CMS : hard_limit=300, used=25, reserved=15, allocated=250Computing : hard_limit=100, used=50, reserved=50, allocated=0Visualisation : hard_limit=150, used=25, reserved=25, allocated=0ATLAS : hard_limit=400, used=25, reserved=25, allocated=300Services : hard_limit=100, used=25, reserved=25, allocated=0Computing : hard_limit=200, used=50, reserved=50, allocated=0假设 Martha 尝试将 CMS 中的实例配额增加到 400。由于 Martha 具有 ProductionIT 中管理员的角色,而 ProductionIT 是 CMS 的父级,因此她可以增加 CMS 的配额,前提是令牌限定为 ProductionIT。这是必需的,因为在 CMS 中增加配额限制会导致 ProductionIT 中剩余配额相应减少。
使用上述公式,ProductionIT 的剩余配额为:
ProductionIT:hard_limit 减去ProductionIT:已用 减去ProductionIT:保留 减去ProductionIT:分配 =1000 - 100 - 100 - (300 + 400) = 100.因此 CMS 的最大允许配额为 300 + 100 = 400
注意:ProductionIT:allocated = CMS:hard_limit + ATLAS:hard_limit
CMS 的最小配额为,CMS:used + CMS:reserved + CMS:allocated = 25 + 15 + 250 = 290
注意: CMS:allocated = Visualisation:hard_limit + Computing:hard_limit
由于 290 <= 400 <=400,配额操作将成功。更新后,ProductionIT 和 CMS 的配额如下:
ProductionIT : hard_limit=1000, used=100, reserved=100, allocated=800CMS : hard_limit=400, used=25, reserved=15, allocated=250假设 Martha 尝试将 CMS 中的实例配额增加到 500。那么它将不成功,因为 CMS 可用的最大配额是 400。
假设 George,CMS 的经理,将 CMS 中的实例配额增加到 400,那么它将不成功,因为 George 没有 ProductionIT 的管理员或项目管理员角色,而 ProductionIT 是 CMS 的父级。
假设 Martha 尝试将 ProductionIT 的配额增加到 2000,那么它将成功。由于 ProductionIT 是根项目,因此 ProductionIT 的最大配额没有限制。而且,Martha 具有 ProductionIT 中的管理员角色。
只有在项目有可用空闲配额的情况下,才允许减少项目的配额值,空闲配额 > 0(零),因此配额值的最大减少限制为空闲配额值。
- 项目层级为 A->B->C,其中 A 是根项目
项目 A(hard_limit = 100,used = 0,reserved = 0,allocated = 50)项目 B(hard_limit = 50,used = 20,reserved = 0,allocated = 10)项目 C(hard_limit = 10,used = 10,reserved = 0,allocated = 0)
如果项目 B hard_limit 减少 10,则此更改将导致项目 A(hard_limit = 100,used = 0,reserved = 0,allocated = 40)项目 B(hard_limit = 40,used = 20,reserved = 0,allocated = 10)项目 C(hard_limit = 10,used = 10,reserved = 0,allocated = 0)
如果项目 B 的 hard_limit 需要进一步减少 20,则此操作将被中止,因为项目 B 的空闲配额应大于或等于(20+0+10)。
假设 Martha 尝试将 CMS 中的实例配额减少到 350,它将成功,因为 CMS 所需的最小配额是 290。
假设 Martha 尝试将 CMS 的实例配额减少到 200,那么它将不成功,因为它违反了最小配额标准。
删除配额等同于将配额更新为零值。如果分配的配额为零,它将成功。身份验证逻辑与更新逻辑相同。
假设 Martha 尝试删除 CMS 的配额,那么它将不成功,因为 CMS 的分配配额不为零。
假设 Martha 删除 Visualisation 的配额,那么它将成功,因为 Visualisation 的分配配额为零。删除的 Visualisation 配额将添加到 CMS 的 free_quota。CMS 的配额将为 CMS :hard_limit=300, used=25, reserved=15, allocated=100。
假设 Martha 删除项目 Visualisation,Visualisation 的配额应释放给其父级 CMS。但在当前的设置中,Nova 不会知道项目何时从 keystone 中删除。这是因为 Keystone 服务与包括 nova 在内的其他服务没有同步。因此,即使项目已从 keystone 中删除,配额信息仍然保留在 nova 数据库中。这个问题存在于 OpenStack 当前的运行模型中。一旦 Keystone 服务同步,这将自动得到处理。目前,Martha 必须在删除该项目之前删除 Visualisation 的配额。Keystone 与其他 OpenStack 服务的同步超出了此蓝图的范围。
假设 George,CMS 的经理,尝试查看 ATLAS 的配额,它将不成功,因为 George 在 ATLAS 或 ATLAS 的父级中没有角色。
假设 Jim,Visualisation 的经理,尝试更新 CMS 的配额,它将不成功,因为他没有 CMS 的父级的管理员或项目管理员角色。
假设组织不希望使用嵌套结构,并希望只有四个项目,即 Visualisation、Computing、Services 和 Operations,那么设置将像当前设置一样,只有一个级别的项目。所有四个项目都将被视为根项目。
备选方案¶
对于项目的配额更新和删除操作,令牌可以限定到项目本身,而不是其父项目。 但是,我们避免这样做,因为子项目的配额更改会导致父项目的可用配额发生变化。 因此,根据此 bp,对于配额更新和删除操作,令牌限定到父项目。
数据模型影响¶
在表 quotas 中创建一个名为 allocated 的新列,默认值为 0。
REST API 影响¶
无
安全影响¶
无
通知影响¶
无
其他最终用户影响¶
无
性能影响¶
无
其他部署者影响¶
无
开发人员影响¶
无
实现¶
负责人¶
- 主要负责人
sajeesh
- 其他贡献者
vishy
schwicke
raildo
vinod
nirbhay
nirupma
morganfainberg
tellesnobrega
rodrigods
afaranha
工作项¶
将创建一个名为“cloud-admin”的角色,并将其分配给根项目中一个用户,并使其可继承。
将创建一个名为“project-admin”的角色。 在项目中具有“project-admin”角色的用户将能够在从其直接子项目到项目下最后一个级别项目/用户中的项目执行配额操作,前提是它是可继承的。
注意:像“cloud-admin”和“project-admin”这样的角色不是硬编码的。它在本 BP 中仅用于演示目的。
将通过扩展现有的
DbQuotaDriver来实现一个新的配额驱动程序,名为NestedQuotaDriver,以在 OpenStack 中强制执行分层多租户中的配额。将添加一个迁移脚本,以在表
quotas中创建名为allocated的新列,默认值为 0。
依赖项¶
测试¶
将为所有 REST API 调用添加单元测试。
添加与其它服务集成的单元测试。
文档影响¶
无