Provisioning Improvements¶
包含您的 Launchpad 蓝图的 URL
https://blueprints.launchpad.net/cinder/+spec/provisioning-improvements
Cinder 的配置仍然是每个人(最终用户、管理员和开发人员)的痛点。多种因素促成了我们目前的情况,例如信息分散在不同的规格、开发人员参考甚至代码中,但我们也有文档解释错误、文档未跟上项目演进,甚至存在误导性或不正确的文档的情况。
本规格将建立在其之前关于同一主题的规格之上 [1] [2] 以及其他相关主题的规格 [3],以提供一个整合和更新的视图,并添加一些小的改进并修复一些问题,希望我们能够为所有相关人员提供更好的体验。
问题描述¶
我们目前的情况非常混乱,基于不正确的容量计算而失败的卷创建,如果只是收到后端统计信息的更新,本可以成功。驱动程序正在报告不正确的统计数据,并且在应该允许创建卷时,卷无法创建。
在进一步进行之前,我们需要首先定义我们将使用的术语,以确保它们对我们所有人具有相同的含义,因为这是我们当前问题的一些根源。
对这些术语的映射及其描述存在分歧是可以理解的,但为了相互理解,我们将以下描述视为真实,因为它们在我们的规格和大部分代码中被定义为如此。
可以稍后讨论对术语和字段名使用的改进,并在规格、文档和代码中相应地更新。
为了完整起见,并消除可能导致驱动程序不同实现的任何误解(我们目前确实存在),这些描述还将包括一些澄清和示例,这些示例可能会参考当前的 Cinder 代码。
术语¶
- GB
尽管这正式被称为千兆字节的符号表示——十进制测量单位——但我们将始终在规格和代码中使用它作为千兆字节的符号——国际电工委员会 (IEC) 定义的二进制测量单位,符号为 GiB。因此,当我们谈论 1GB 时,我们谈论的是 1024MB,TB 和 MB 也是如此。
- 总容量
如果没有任何卷存在,那么将可用于存储阵列池的物理总容量。
驱动程序当前将其报告为 total_capacity_gb,顾名思义,应以 GB 为单位报告,且精度不超过 2 位小数。
如果存储阵列有 5TB 的空间,但 Cinder 中使用的池限制为 1TB,那么驱动程序应报告 total_capacity_gb 为 1024GB。
- 卷大小
卷在存储阵列中可以采用的最大物理大小。
这在代码中引用为 volume_size。
对于厚卷,volume_size 将与配置时丢失的可用容量相同,而对于薄卷,它将大于存储阵列中卷使用的空间,直到卷完全填满。
- 可用容量
Cinder 使用的存储阵列池中当前可用的物理容量。已由 Cinder 或直接在存储阵列中配置的薄卷和厚卷的数量和大小在这里无关紧要。
驱动程序当前将其报告为 free_capacity_gb,顾名思义,应以 GB 为单位报告,且精度不超过 2 位小数。
如果存储阵列有 5TB 的空间,总共有 3TB 可用于所有池,但 Cinder 使用一个限制为 1TB 的池,其中已经使用了 400GB,并且有人手动创建了当前使用 124GB 空间的卷,那么驱动程序应报告 free_capacity_gb 为 500GB (1TB = 1024GB = 400GB + 124GB + 500GB)。
- 已配置容量
如果 Cinder 中所有卷都已完全填满,那么将使用的存储阵列池的容量。
驱动程序当前将其报告为 provisioned_capacity_gb,顾名思义,应以 GB 为单位报告,且精度不超过 2 位小数。这是一个必需字段,必须始终存在。
这包括由 Cinder 创建的卷以及后端中的所有其他现有卷,但不包括快照。
让我们扩展“可用容量”中之前的示例,其中 1TB 的可用空间中已经使用了 524GB,假设外部创建的 124GB 全部由 1GB 厚卷使用,并且 Cinder 使用 400GB 的 400 个 1GB 厚卷和 20 个 20GB 的空薄卷。在这种情况下,我们报告的 provisioned_capacity_gb 值应为 924GB ((124 * 1GB) + (400 * 1GB) + (20 * 20GB))。
如果驱动程序未报告 provisioned_capacity_gb 数据,我们将使用自动计算的 allocated_capacity_gb,如下所述。
- 已分配容量
与名称可能暗示的相反,这并非指存储阵列上的“已分配”空间,而是指 Cinder 使用的存储阵列池中存在的特定 Cinder Volume 后端进程配置的卷,并且仍然存在。
重要的是要注意,这指的是特定的服务后端,因此,如果您正在运行一个多后端 Cinder 服务或多个 Cinder Volume 服务,其中多个后端配置为使用相同的存储阵列池,那么每个后端将仅报告其创建的卷的 volume_size 的总和,而不是 Cinder 服务创建的所有卷的 volume_size 的总和。
Volume 服务当前将其报告为 allocated_capacity_gb,顾名思义,应以 GB 为单位报告。
如果创建了两个卷,一个厚卷和一个薄卷,每个卷均为 1GB,那么您将报告 2GB 作为 allocated_capacity_gb,但是如果您取消管理其中一个卷,那么您将仅报告 1GB,即使该卷仍然存在并且仍将计入 provisioned_capacity_gb。
Cinder 核心代码直接计算此字段,驱动程序不应在其 get_volume_stats 方法中计算或报告此信息。
- 超额订阅率
表示“已配置容量”与“总容量”的比率,以实数表示。比率为 1.0 表示“已配置容量”不能超过“总容量”,而值为 5.0 表示 Cinder 后端允许创建多达存储阵列池“总容量”的 5 倍的卷。
这仅在创建薄配置卷时有效,并且对于厚配置卷将被忽略。
驱动程序当前将其报告为 max_over_subscription_ratio,其值大于或等于 1.0,最好精度不超过 2 位小数。
此值是可选的,如果驱动程序的状态报告中缺少该值,则接收请求的 Cinder 调度程序中定义的 [DEFAULT] 部分中的值将被使用。因此,供应商应确保在其驱动程序中正确返回此值(如果他们支持薄配置),并且管理员应确保在所有调度程序节点上具有一致的 max_over_subscription_ratio 默认值。
请注意,此比率取决于驱动程序实现,可以是每个后端或每个池。
- 保留百分比
表示存储阵列的“总容量”中保留的百分比,不应将其用于计算。它由一个从 0 到 100 的整数值表示。
驱动程序当前将其报告为 reserved_percentage,其值大于或等于 1.0,最好精度不超过 2 位小数。
如果后端的状态报告中缺少该字段,或者用户未在 Cinder 配置中定义该字段,则默认值为 0。这取决于驱动程序实现,可以是每个后端或每个池。
- 配置支持
Cinder 后端最多可以支持两种配置类型,薄卷和厚卷,并且预计驱动程序至少在其功能报告中指示其能够支持其中一种。
报告对这些的支持的方法是设置布尔字段 thin_provisioning_support 和/或 thick_provisioning_support 为 true。未报告的配置类型将默认为 false。
Cinder 后端可以同时支持两种配置类型。
- 卷配置类型
对于仅支持一种配置类型的 Cinder 后端,在其上创建的所有卷都将是该类型,我们可以使用卷类型的额外规格来过滤掉不支持特定配置类型的后端。
‘thin_provisioning_support’: ‘<is> True’ 或 ‘<is> False’
‘thick_provisioning_support’: ‘<is> True’ 或 ‘<is> False’
但是,如果我们的部署正在使用同时支持两种配置类型的后端,我们需要使用卷类型的额外规格 provisioning:type 并将其设置为 thin 或 thick 来明确我们想要的卷的类型。
如果未为卷定义 provisioning:type,它将默认设置为薄卷(如果后端能够支持),并且预计驱动程序将遵守此假设。
不正确的报告¶
鉴于以上术语,这些术语最初在其各自的规格中定义,即使本规格中还有其他评论,我们可以确定有许多 Cinder 驱动程序不遵循这些定义并报告将是不正确的值。
报告不正确的值意味着在异构云中,您将拥有不一致的调度,并且管理员将无法理解卷的统计信息。
为了说明这一点,以下是不同驱动程序对 provisioned_capacity_gb 的一些解释
所有卷的最大大小之和,这是正确的。
所有卷的物理磁盘使用量之和,这是错误的。
Cinder 卷的物理磁盘使用量之和,这是错误的。
类似的情况也发生在 allocated_capacity_gb 上,驱动程序会直接报告该值,而不是让 Cinder 核心代码负责处理。
Cinder 卷的物理磁盘使用量之和,这是正确的。
物理磁盘使用量之和,这是错误的。
所有卷的最大大小之和,这是错误的。
配置计算¶
一些创建失败是基于 provisioned_capacity_gb 值不正确,但还有其他情况是 Cinder 的超配置计算与行业标准定义不匹配,这给一些管理员带来了困惑和不期望的行为。
检查卷的 volume_size 是否合适的标准配置计算是
((provisioned_capacity_gb + volume_size) <=
(total_capacity_gb
x (1 - (reserved_percentage / 100.0))
x max_over_subscription_ratio))
而 Cinder 的计算,这些计算被认为是更安全的计算,如下所示
(volume_size <=
(free_capacity_gb
- (total_capacity_gb x reserved_percentage / 100.0))
x max_over_subscription_ratio)
计算最大超额订阅率¶
大多数部署都有非常动态的工作负载,每个工作负载都有不同的物理存储需求,这意味着一个月我们可能需要许多卷,几乎不使用任何空间,而下个月我们可能需要较少的卷,但使用大部分已配置的容量。
这使得在部署时准确建模我们的存储需求几乎不可能,而这正是我们必须为 Cinder 后端设置 max_over_subscription_ratio 的时候。
当需求发生变化时,一种选择是更改配置并重新启动我们的 Cinder Volume 服务,但由于 Cinder 也位于数据路径中,因此重新启动可能需要很长时间,并且会对我们的云用户产生相当大的影响。
无法提前确定最佳 max_over_subscription_ratio 并且无法轻松重新启动 Cinder 服务是大多数使用支持薄配置的后端的运营商的常见痛点。
用例¶
修复状态报告的基本情况是,我们希望我们的后端提供一致的报告,以便管理员在日志中查看,并供调度程序使用。
任何使用薄配置存储并希望优化其存储使用率并动态调整其云的动态需求的运营商。
至于替代计算,对于接近其完全容量的后端或创建通常未完全填满的大型卷的后端,这将非常有益。
提议的变更¶
不正确的报告¶
由于我们已将所有文档整合到一个地方,即本规格,我们明确说明了预期的驱动程序行为,所有驱动程序维护人员都将被敦促使其驱动程序符合该规范。这意味着他们需要调整其驱动程序以遵循本文档对 provisioned_capacity_gb 的定义,并停止报告 allocated_capacity_gb 字段。
自动超额订阅率计算¶
为了允许自动超额订阅率计算,我们将现有的配置选项 max_over_subscription_ratio 更改为多态选项,该选项不仅接受整数和浮点数,还接受一个新的字符串值 auto,该值将指示 Cinder 使用我们的默认值 20 作为后端为空时的起始参考,然后在有数据时,在每次驱动程序统计报告中使用以下公式计算当前值
ratio = 1 + (`provisioned_capacity_gb` /
(`total_capacity_gb` - `free_capacity_gb` + 1))
如果驱动程序未报告 provisioned_capacity_gb,我们将继续使用 allocated_capacity_gb。
ratio = 1 + (`allocated_capacity_gb` /
(`total_capacity_gb` - `free_capacity_gb` + 1))
我们没有在此公式中考虑保留容量,因为调度程序的容量过滤器已经在计算虚拟可用容量时考虑了它。
已经有一些驱动程序在执行此操作,Pure 和 Kaminario 的 K2,但配置选项不同,分别为 pure_automatic_max_oversubscription_ratio 和 auto_calc_max_oversubscription_ratio。因此,如果已配置,这些配置选项将优先于此新功能,但我们将鼓励供应商弃用这些选项。
以不兼容方式使用 max_over_subscription_ratio 的驱动程序将引发错误并无法启动,如果配置了此新功能,将记录相应的消息。
资源调配计算¶
与其继续与管理员和开发人员争论哪种方法更好——标准计算还是 Cinder 的计算——我们将添加一个新的配置选项,名为 over_provisioning_calculation,它将接受 standard 和 cinder 值,并默认设置为 cinder 以保持向后兼容性。 CapacityFilter 将使用此选项来确定使用哪种机制。
此配置选项也将影响 CapacityWeigher,因为它需要根据标准定义进行空闲空间计算。
可以假设,厚配置将不会对其行为进行任何修改。
备选方案¶
不支持标准的资源超额配置计算。
不要修改 CapacityFilter 和 CapacityWeigher,而是创建 2 个新的类。
不要添加 over_provisioning_calculation 配置选项,而是让过滤器使用 scheduler_json_config_location 提供的选项 JSON 文件。目前,某些操作(如迁移、扩展)似乎缺少此数据,因此需要进行更改。
数据模型影响¶
N/A
REST API 影响¶
受影响的唯一 API 将是 get_pools API,它能够返回 2 个新字段,total_used_capacity_gb 和 cinder_used_capacity_gb,当驱动程序的 get_volume_stats 方法报告这些字段时。如果驱动程序未报告这些字段,则这些字段将不存在。
安全影响¶
N/A
通知影响¶
N/A
其他最终用户影响¶
用户在调用 cinderclient 的 get_pools 时可能会看到新字段。
性能影响¶
根据驱动程序和存储阵列的不同,性能可能会提高或降低,因为获取配置大小而不是物理大小可能更快或更慢。
其他部署者影响¶
由于 Cinder 后端返回的 allocated_capacity_gb 和 provisioned_capacity_gb 值发生了变化,我们可能会在创建卷时遇到故障,直到我们将云中的 reserved_percentage 和 max_over_subscription_ratio 值更正为正确的值为止,因为我们可能使用了不正确的值。
将修改一个配置选项
max_over_subscription_ratio:将其类型从 Float 更改为 String,并添加一个新的可能值,auto,这将启用此新功能。
将添加一个新的配置选项
over_provisioning_calculation:将允许选择 CapacityFilter 执行哪种类型的计算来确定后端是否有足够的空间来容纳一个卷。可接受的值为 standard 和 cinder。默认值为 cinder。
开发人员影响¶
驱动程序维护者需要验证并修复(如果需要)其 allocated_capacity_gb 和 provisioned_capacity_gb 的统计报告,如果他们以不兼容的方式使用 max_over_subscription_ratio,则应修复其驱动程序以支持此功能。
实现¶
负责人¶
- 主要负责人
无
- 其他贡献者
无
工作项¶
为不符合要求的驱动程序提交错误报告。
修复驱动程序统计报告。
在调度器、get_pools API 和客户端中添加对 3 个新字段的支持,即 provisioned_capacity_precission、total_used_capacity_gb 和 cinder_used_capacity_gb。
修改 CapacityFilter 以支持标准的资源超额配置计算。
修改 CapacityWeigher 以支持标准的资源超额配置计算。
为不报告 provisioned_capacity_gb 的驱动程序在卷管理器中添加估算机制。
更新所有开发人员参考文档,以确保不再对统计报告需要返回的内容感到困惑,并确保有关如何贡献驱动程序的 wiki 页面链接到该文档,解释在编写驱动程序时遵循该文档的重要性。
依赖项¶
N/A
测试¶
将添加新的单元测试来测试更改后的代码。
文档影响¶
由于我们当前的文档在这方面缺乏内容,因此将添加和更新它,以反映驱动程序在统计报告中需要的内容。
也应更新最终用户文档。