卷复制¶
https://blueprints.launchpad.net/cinder/+spec/volume-replication
卷复制是一项关键的存储功能,也是 OpenStack 云上运行的应用程序实现高可用性和灾难恢复等功能的必要条件。本蓝图旨在为 Cinder 添加卷复制的初始支持,被认为是首次尝试,将包括以下支持:* 复制卷(主到副方法)* 将副卷提升为主卷(并停止复制)* 重新启用复制* 测试复制是否正常运行
需要注意的是,这是卷复制的首次尝试。为驱动程序实现复制的过程发现了一些挑战,这些挑战将在未来修订的复制版本中解决,该版本将解决不同复制类型和跨多个后端复制的能力。
虽然本蓝图侧重于卷复制,但相关的蓝图侧重于一致性组,并且复制将扩展以支持它。
用例¶
问题描述¶
卷复制的主要用途是在发生故障时提供弹性。可能的故障示例包括
存储系统故障
机架级故障
数据中心级故障
这里我们特别排除媒体故障、磁盘故障等故障。此类故障通常通过本地弹性方案解决。
复制可以通过以下方式实现
基于主机的 - 需要 Nova 集成
基于存储的
典型的基于块的方法 - 在控制器上的两个现有卷(或卷组)之间指定复制。
典型的基于文件系统的方法 - 放置在目录(或组、文件集等)中的文件(在 Cinder 上下文中,表示块设备的文件)会自动复制到指定的远程位置。
假设
复制对最终用户应该是透明的,故障转移、故障恢复和测试将由云管理员执行。但是,为了测试应用程序是否正常运行,可能需要最终用户的参与,因为他们需要验证其应用程序是否与卷副本正常工作。
存储管理员将提供设置和配置,以启用存储系统之间的实际复制。这可以在存储后端或存储驱动程序级别执行,具体取决于存储后端。具体而言,存储驱动程序应报告它们可以与谁复制,并将其报告给调度程序。
云管理员将通过使用卷类型启用复制功能。
最终用户不会直接接触复制功能。选择卷类型将根据卷类型的实际额外规范定义(由云管理员定义)来确定卷是否将被复制。
配额管理:由于创建了两个卷,并且消耗空间加倍,因此配额消耗是 2 倍。我们可以在收到部署者的意见后重新审查此机制。
提议的变更¶
介绍
拟议的设计仅在 Cinder 中提供了一个框架,供后端卷驱动程序使用存储后端中的设施实现卷复制。因此,本规范提供了关于如何实现卷复制的指导,但实际实现将因所讨论的后端而异。
启用复制的关键在于向卷类型添加一个额外规范,以指示需要复制。然后,该额外规范在卷驱动程序中使用,以在下面记录的每个不同函数中设置和控制存储后端上的复制。
由于 Cinder 只是为后端卷驱动程序提供实现复制的框架,因此复制实现的细节留给后端实现。后端驱动程序开发人员需要为其存储后端决定启用复制的最佳方式。例如,一个存储提供商可能认为实现同步复制是最佳选择,而另一个存储提供商可能选择异步复制。提供商还可以选择使其成为可配置选项。以这种方式在 Cinder 中实现卷复制,为后端开发人员提供了实现复制的最大灵活性。
还需要注意的是,开发人员文档必须提供 Storwize 驱动程序中如何实现此功能的示例。这是一个重要的注意事项,因为目前无法在 Cinder 的参考实现 LVM 中演示卷复制。因此,开发人员文档将必须充当参考。
在卷类型中添加额外规范以指示复制
capabilities:replication <is> True - 如果为 True,则卷(如果后端驱动程序支持)将被复制。如果未指定或为 False,则不启用复制。此选项是启用复制所必需的。
创建启用复制的卷
希望启用复制的后端驱动程序需要更新其 create_volume() 函数以检查“capabilities:replication <is> True”额外规范。后端驱动程序开发人员有责任以与他们的存储后端兼容的方式实现复制。
创建复制卷时,卷字典应填充如下
volume['replication_status'] = 'copying'
volume['replication_extended_status'] = <驱动程序特定值>
volume['driver_data'] = <驱动程序特定值>
副本卷对最终用户是隐藏的,因为最终用户永远不需要直接与副本卷交互。与副本的任何交互都通过主卷进行。
有关上述字典字段的更多详细信息,请参阅下面的“数据模型影响”部分。
从快照创建卷
如果卷类型额外规范包含新卷的“capabilities:replication <is> True”,则驱动程序需要在卷创建时创建卷副本,并设置新创建的卷及其关联副本之间的复制。卷字典应以与创建卷相同的方式填充。
创建克隆卷
如果卷类型额外规范包含新卷的“capabilities:replication <is> True”,则驱动程序需要在克隆创建时创建卷副本,并设置新创建的卷及其关联副本之间的复制。卷字典应以与创建卷相同的方式填充。
创建副本测试卷
创建副本(辅助)卷的克隆。此克隆可用于测试复制,以确保在必要时可以执行故障转移。需要注意的是,这实际上并没有执行提升路径,因为目的不是提升副本,但它提供了一种确保副本包含数据并在需要提升时有用的方法。
管理员可以使用创建卷时的 –source-replica 选项访问此功能。
删除卷
对于启用复制的卷,副本需要与主副本一起删除。因此,如果卷类型设置了“capabilities:replication <is> True”,则驱动程序将需要执行额外的删除操作。
获取卷统计信息
如果存储后端驱动程序支持复制,则应报告以下状态:* replication = True(None 或 False 禁用复制)
重新类型化卷
更改卷类型是管理员可以用来使现有卷可复制或禁用卷复制的机制。将卷的卷类型更改为包含“capabilities:replication: <is> True”(且以前没有)的卷类型应导致向卷添加辅助副本。将卷的卷类型更改为不再包含“capabilities:replication: <is> True”的卷类型应导致删除辅助副本,同时保留主副本。
- 返回以下任一
一个布尔值,指示是否发生了重新类型化,或者一个元组 (retyped, model_update),其中 retyped 是一个布尔值,指示是否发生了重新类型化,并且 model_update 包含卷数据库的更改。
实现此功能的步骤如下所示:* 执行 diff['extra_specs'] 并查看是否包含“replication”。
如果原始 volume_type 启用了复制,但新 volume_type 未启用复制,则应禁用复制。
应删除副本。
卷字典应更新如下
volume['replication_status'] = 'disabled'
volume['replication_extended_status'] = None
volume['driver_data'] = None
如果原始 volume_type 未启用复制,但新 volume_type 启用了复制,则应启用复制。
应创建一个卷副本,并在卷和新创建的副本之间设置复制。
卷字典应更新如下:- volume['replication_status'] = 'copying' - volume['replication_extended_status'] = <驱动程序特定值> - volume['driver_data'] = <驱动程序特定值>
获取复制状态
这将用于更新主卷和辅助卷之间的复制状态。
此函数由“manager.py”中的“_update_replication_relationship_status”函数调用,是更新主副本和辅助副本之间状态复制的机制。
应返回存储后端所知道的复制的实际状态,并且应更新 Cinder 数据库以反映从存储后端报告的状态。
预计将发生以下卷模型更新
volume['replication_status'] = <error | copying | active | active-stopped | inactive>
如果复制发生错误,则为“error”。
“copying”复制数据到辅助(不一致)
“active”复制数据到辅助(一致)
“active-stopped”复制数据暂停(一致)
如果复制数据停止(不一致),则为“inactive”
volume['replication_extended_status'] = <驱动程序特定值>
volume['driver_data'] = <驱动程序特定值>
请注意,对于获取复制状态,replication_extended_status 和 driver_data 可能不需要更新。
提升副本
提升副本意味着辅助卷将接管主卷。这可以被视为“故障转移”操作。一旦提升发生,存储级别上两个卷之间的复制应该停止,副本应该可以附加,并且如果更改成功,则复制状态应该更改为“inactive”,否则应该为“error”。
返回卷的模型更新。
与上述函数一样,卷驱动程序应更新卷字典如下
volume['replication_status'] = <error | inactive>
如果复制发生错误,则为“error”。
如果复制数据暂停(不一致),则为“inactive”
volume['replication_extended_status'] = <驱动程序特定值>
volume['driver_data'] = <驱动程序特定值>
重新启用复制
重新启用复制将用于修复主卷和辅助卷之间的复制。复制需要作为故障恢复过程的一部分重新启用,以使提升的卷和旧的主卷再次保持一致。
卷驱动程序返回模型更新以反映所采取的操作。
后端驱动程序应更新以下卷字典条目
volume['replication_status'] = <error | copying | active | active-stopped | inactive>
如果复制发生错误,则为“error”。
“copying”复制数据到辅助(不一致)
“active”复制数据到辅助(一致)
“active-stopped”复制数据暂停(一致)
如果复制数据停止(不一致),则为“inactive”
volume['replication_extended_status'] = <驱动程序特定值>
volume['driver_data'] = <驱动程序特定值>
注意事项
replication_extended_status 应用于存储后端驱动程序需要跟踪复制状态的信息。例如,Storwize 驱动程序将使用 replication_extended_status 来跟踪主卷的主副本状态和同步状态,以及副本(辅助)卷的副本状态、同步状态和同步进度。
driver_data 字段可以(可选)用于包含后端驱动程序可能需要的任何额外数据。某些后端驱动程序可能不需要使用 driver_data 字段。
驱动程序 API
- promote:将处于活动或活动停止状态的副本提升为
主副本。
- reenable:在处于非活动、活动停止或错误状态的卷上重新启用复制。
活动停止或错误状态。
备选方案¶
复制可以在 Cinder 之外执行,OpenStack 可能不知道它。但是,这需要特定于供应商的脚本,并且管理员用户不可见,因为只有存储系统管理员才能看到副本和复制状态。此外,所有恢复操作(故障转移、故障恢复)都需要存储和云管理员协同工作。而在 Cinder 中复制将存储管理员的角色减少到仅设置阶段,云管理员负责故障转移和故障恢复,通常不需要云管理员的干预。
数据模型影响¶
卷表将更新
添加 replication_status 列(字符串)以指示给定卷的复制状态。可能的值为
“copying” - 数据正在卷之间复制,辅助副本不一致。
“disabled” - 卷复制已禁用。
“error” - 复制处于错误状态。
“active” - 数据正在复制到辅助副本,并且辅助副本一致。
“active-stopped” - 数据未复制到辅助副本(暂停),辅助卷一致。
“inactive” - 数据未复制到辅助副本,辅助副本不一致。
添加 replication_extended_status 列以包含有关主卷和辅助卷复制状态的详细信息。
添加 replication_driver_data 列以包含供应商驱动程序在后端实现复制可能需要的额外详细信息。
复制状态图
<start>
any error
condition +-------+
Create volume +-----+ +------------> | error |
| +---+---+
| | Storage admin to
| | fix, and status
| | check will update
+-----+-----+ |
+-------------> | copying | any state <-------+
| +-----+-----+
| |
| status |
| check | status check
| +----+-----+ +------> +----------------+
| | active | | active-stopped |
| +----+-----+ <------+ +----------------+
| | status check
| |
| | promote to primary
| |
| re-enable +----+-----+
+------------+ | inactive |
+----------+
<end>
REST API 影响¶
创建卷 API 将添加“source-replica”
{
"volume":
{
"source-replica": "Volume uuid of primary to clone",
}
}
将卷提升为主卷
将辅助副本提升为主副本。主副本将成为辅助副本,并且复制应变为非活动状态。
方法类型:POST
正常响应代码:202
预期的错误 http 响应代码
500:卷未启用复制
500:卷的复制状态必须为 active 或 active-stopped,但当前状态为:<status>
500:卷的状态必须为可用,但当前状态为:<status>
V2/<tenant id>/volumes/os-promote-replica/<volume uuid>
此 API 没有主体
重新启用主卷和辅助卷之间的复制。
重新启用主卷和辅助卷之间的复制。通常在复制上执行提升操作之后。
方法类型:POST
正常响应代码:202
预期的错误 http 响应代码
500:复制未启用
500:卷的复制状态必须为 inactive、active-stopped 或 error,但当前状态为:<status>
/v2/<tenant id>/volumes/os-reenable-replica/<volume uuid>
此 API 没有主体
安全影响¶
此更改是否涉及令牌、密钥或用户数据等敏感数据?否。
此更改是否以可能影响安全性的方式更改 API,例如访问敏感信息的新方法或登录的新方法?否。
此更改是否涉及密码学或哈希?否。
此更改是否需要使用 sudo 或任何提升的权限?否。
此更改是否涉及使用或解析用户提供的数据?这可以直接在 API 级别或间接(例如对缓存层的更改)发生。否。
此更改是否可能导致资源耗尽攻击,例如允许单个 API 交互消耗大量服务器资源?这方面的一些示例包括为每个连接启动子进程,或 XML 中的实体扩展攻击。是,启用复制会消耗云和存储资源。
通知影响¶
将添加用于提升和重新启用卷复制的通知。
其他最终用户影响¶
最终用户使用卷类型启用复制。
云管理员使用 python-cinderclient 中的 replication-promote、replication-reenable 和 create –source-replica 命令执行故障转移、故障恢复和测试。
性能影响¶
添加到重新类型化、快照操作等中的识别复制是否存在额外的数据库调用将为这些功能增加少量延迟。
其他部署者影响¶
添加了卷类型的选项(参见上文)
添加新的驱动程序功能,需要卷驱动程序支持,这可能意味着更改驱动程序配置选项。
此更改需要云管理员明确启用(供用户使用)。
开发人员影响¶
驱动程序 API 的更改如上所述。希望启用复制的第三方后端需要向其驱动程序添加复制支持。
API 将扩展以包含一致性组,前提是 Cinder 中合并了一致性组支持。
实现¶
负责人¶
- 主要负责人
ronenkat
- 其他贡献者
Jay Bryant - 电子邮件: jsbryant@us.ibm.com IRC: jungleboyj
工作项¶
Cinder 复制的公共(管理员)API
复制的数据库架构更新
Cinder 驱动程序 API 的复制添加
Cinder 管理器复制更新
测试
依赖项¶
相关蓝图:一致性组 https://blueprints.launchpad.net/cinder/+spec/consistency-groups
LVM 在单独的贡献中支持使用 DRBD 进行复制。
测试¶
由于以下考虑,不支持在门禁中进行测试
LVM 没有复制支持,将在单独的贡献中使用 DRBD 解决。
需要使用 DRBD 设置至少两个节点
应在添加 LVM 支持时讨论/解决。
第三方驱动程序 CI 将负责测试复制。
文档影响¶
公共(管理员)API 更改。
详细说明如何通过利用卷类型使用复制。
驱动程序文档解释了如何为每个驱动程序设置复制。
提供 Storwize 后端的卷复制实现示例。
参考资料¶
- 关于文档改进的 Etherpad