Cinder 卷恢复到快照

https://blueprints.launchpad.net/cinder/+spec/revert-volume-to-snapshot

能够将卷恢复到之前拍摄的快照是有意义的。恢复功能可用于将卷恢复到先前的快照,从而将卷恢复到创建快照时的状态。该功能支持恢复到最近拍摄的快照,同时 manila(共享文件系统服务)已经在 Ocata 中支持了我们提出的内容 [1]

恢复过程将覆盖卷的当前状态和数据。如果卷在快照之后被扩展,则请求将被拒绝(原因在提出的变更部分中描述)。假设执行恢复的用户正在丢弃卷的实际状态和数据。

此功能的目的在于为用户提供更方便、停机时间更短的实例和卷恢复可能性。

问题描述

目前,用户可以通过从指定快照创建卷并将其附加来恢复实例,工作流程如下

  1. 用户创建卷

  2. 用户将卷附加到实例

  3. 用户创建快照

  4. 发生一些情况(崩溃)导致需要恢复

  5. 用户从快照创建卷

  6. 用户分离旧卷

  7. 用户附加新卷

此工作流程存在以下问题

  • 要从快照创建卷,某些供应商需要将数据复制到新卷。此过程比简单地恢复到最近的快照花费更多时间。

  • 要从快照创建卷,网络配置将发生变化,这会导致大多数应用程序出现问题,需要管理员干预。

  • 如果实例是从启动卷创建的,初始定制脚本可能无法将实例配置回崩溃前的状态。

  • 它会消耗用户的配额,并且在某些情况下会占用后端中的实际空间。

另一种选择是从备份恢复数据,但该过程不能由云用户完成,这也不是常见情况(数据不一致更有可能是主要原因),此外,最终用户会期望耗时更短的操作。

如上所述,我们希望能够提供一种使用更简单的方法快速恢复实例,恢复快照可能是一个不错的选择。

用例

主要用例是实例或卷由于任何不利情况、攻击或故障而崩溃,同时存储数据仍然存在的情况。在这种情况下,将使用以下工作流程

  1. 用户创建卷。

  2. 用户将卷附加到实例。

  3. 用户创建安全点的快照。

  4. 发生一些情况导致需要恢复。

  5. 用户分离卷。

  6. 用户恢复到安全快照。

提议的变更

理论上,如果存在多个快照,存储系统可以将卷恢复到其中任何一个快照。但是,恢复到不是最新快照的快照通常会删除后续快照,这是一种数据丢失形式,可能不是用户想要的。因此,此功能将限制 cinder 恢复 cinder 知道的最新卷快照。

对于此用例,从最近的快照开始倒退时间是有意义的。只有用户才能确定卷是否可用或必须恢复,因此回到良好状态是一个手动迭代过程

Observe corruption in volume
Revert to most recent snapshot
While corruption is present in volume:
    Delete most recent snapshot
    Revert to most recent snapshot

已经提出了一种简单的 API,仅包含卷 ID 并允许 cinder 确定最新的快照,但这可能会导致潜在的并发错误

  1. 如果两个用户同时调用 volume-revert-to-snapshot 和 snapshot-create,这两个调用会发生竞争,并且一个用户可能会对用于恢复卷的快照感到惊讶。

  2. 如果两个用户同时调用 volume-revert-to-snapshot 和 snapshot-delete,这些调用会发生竞争,并且当卷恢复到比预期更早的快照时,有人可能会感到惊讶(这是一种数据丢失形式)。

为了保持 REST 接口的明确性,并避免上述竞争条件,接口将接受要恢复的快照的 ID。cinder 将通过快照对象上的 created_at 字段验证快照是否是最新快照,如果不是则返回错误。在任何时候,cinder 都不会在恢复操作期间删除任何快照,并且不会对 REST 调用中指定的快照以外的任何快照进行操作。

卷恢复有两种情况,一种是分离的卷,另一种是附加的卷。我们只会支持恢复分离的卷。

由于我们目前支持扩展卷,因此我们可能会遇到快照小于卷的情况,并且在那种情况下显然可以安全地恢复。但是,我们仍然会限制恢复到卷大小等于快照的卷,因为我们尚未支持缩小卷 [2](如果驱动程序不支持恢复到快照,则将使用该功能)。

因此,我们需要进行以下更改才能支持卷恢复到快照。

  • 添加卷恢复到快照 API.

    我们将添加一个恢复到快照的 API,在 API 层,将对快照和卷进行验证(存在性、状态和大小),以及快照是否是最新快照。

    只有当卷的状态为“available”时,cinder 才会接受请求。

  • 在 cinder 卷服务中实现恢复到快照.

    在快照恢复期间,有两个对象受到影响,其状态必须反映出来。卷的状态为“reverting”,快照的状态也为“restoring”。在恢复期间,不允许对这两个对象进行任何其他操作。

    如果 cinder 驱动程序不支持恢复功能,它将使用通用实现来运行恢复过程。

    成功恢复后,两个对象的状态将再次设置为恢复之前的状态。如果恢复失败,卷将被设置为“error”,快照将被设置为“available”。

  • 创建快照以进行备份

    卷的恢复过程可能会失败,为了防止数据丢失,在恢复过程之前,我们将创建一个快照进行备份,并在操作成功后删除它,最终用户可以利用该快照来恢复他们的数据。

  • 在 cinder 驱动程序中实现恢复到快照.

    添加一个函数,供应商可以使用该函数通过优化的版本覆盖默认的 revert_to_snapshot 函数。供应商可以在其驱动程序中实现恢复快照功能的优化版本

    def revert_to_snapshot(self, context, volume, snapshot):
        """Is called to perform revert volume from snapshot.
    
        :param context: Our working context.
        :param volume: the volume to be reverted.
        :param snapshot: the snapshot data revert to volume.
        :return None
        """
    

    如果此函数引发任何内部错误,将捕获并存储该错误。

  • 添加一个通用的恢复到快照实现函数.

    如果 cinder 驱动程序不支持恢复到快照功能,则框架将使用通用方法来实现恢复快照功能。

    1. 从快照创建临时卷(如果后端支持挂载快照,我们将直接挂载快照,并且不需要创建和挂载临时卷)。

    2. 将临时卷挂载到主机。

    3. 将数据从临时卷或快照复制到原始卷。

    4. 删除临时卷。

备选方案

  • 另一种选择是从快照创建新卷(已经实现并使用)。但这有一些缺点,如“问题描述”部分所述。

  • 实现快照恢复,允许恢复到卷拥有的任何快照。

数据模型影响

卷对象的新状态“reverting”和快照对象的新状态“restoring”。

REST API 影响

向卷操作集合添加一个新的恢复操作,需要“volume_id”和“snapshot_id”。

URL = /v3/{tenant_id}/volumes/{volume_id}/action

Method: POST

Body = {
           'revert': {
               'snapshot_id': <snapshot_id>
           }
       }

Normal Response: Status code 202 with empty response body

Error responses:

1. 404, if the volume is not found.
2. 409, if volume and snapshot's status are not 'available' or
   the sizes of volume and snapshot are not equal.
3. 400, if the snapshot is not found or not belongs to the specified
   volume or is not the latest one.

调用此方法会将卷恢复到指定的快照。它旨在供租户和管理员使用,policy.json 文件将更新以反映所有允许的使用情况。

安全影响

通知影响

将添加有关恢复过程(开始、结束、错误)以及相关更改通知的通知。

Cinder 客户端影响

cinder-client 将添加命令以公开恢复 API

usage: cinder revert-to-snapshot <snapshot>

Revert a volume to the specified snapshot.

snapshot: Name or ID of the snapshot to restore.

OpenStack-client 影响

openstack-client 将添加命令以公开恢复 API

usage: openstack volume snapshot restore <snapshot>

Revert a volume to the specified snapshot.

snapshot: Name or ID of the snapshot to restore.

其他最终用户影响

此功能也将实现到 cinder-ui。

性能影响

实际的恢复过程可能会锁定存储并消耗很长时间,具体取决于卷的大小。

确定最新的快照需要对数据库进行查询,该查询按时间戳(快照对象上的 created_at 字段)排序。这比不关心结果排序的查询稍慢。

其他部署者影响

开发人员影响

将有一个新的驱动程序入口点 revert_to_snapshot,驱动程序维护者可以实现此功能的优化版本。驱动程序还应注意这些情况。

  1. 在恢复过程中,指定的快照不能被删除(这意味着如果后端删除了该快照,则应在 revert_to_snapshot 中重新创建该快照)。

实现

负责人

主要负责人

工作项

  • 创建 API

  • 创建 RPC 调用

  • 添加通用的 revert_to_snapshot 函数。

  • 添加 revert_to_snapshot 接口和 lvm 的实现

  • 实现单元测试和功能测试

  • 实现 tempest 测试

  • 实现 cinder 客户端

  • 实现 OSC

  • 实现 cinder UI

  • 添加 API 文档

  • 更新开发参考和支持矩阵

依赖项

测试

单元测试和手动测试,以及针对这些提出的 API 的 tempest 测试。

  1. 为了保证卷恢复实际发生,需要一个新的场景测试,该测试将数据写入卷,创建快照,修改卷,恢复快照,并确保原始数据存在于卷中。

  2. 为了保证此功能可以在 HA 部署模式下工作。

文档影响

  • API 参考:添加有关 API 的内容。

  • 将恢复到快照功能添加到开发参考。

  • 将 RevertToSnapshot 功能添加到 cinder 支持矩阵。

参考资料