添加卷重新镜像 API

https://blueprints.launchpad.net/cinder/+spec/add-volume-re-image-api

此蓝图建议添加卷重新镜像 API,以实现重新镜像特定卷的能力。

问题描述

目前,用户可以使用特定镜像创建卷,但一旦创建此卷,就无法再更改此卷的镜像。如果用户想要重新镜像特定卷,他们只能使用新镜像创建新卷,然后删除旧卷,这不太方便。但是,如果基于镜像的卷已经用作已附加到服务器的启动卷,则情况会更加复杂,因为更改附加的根卷中的镜像不受支持

此外,如 nova spec ‘volume-backend-server-rebuild’ 中所述 [1],如果用户想要重建基于卷的服务器,他们可以使用重新镜像 API 完成,这样就不需要具有新卷 ID 的新卷,我们不必担心类型、配额问题等。

根据 Yoga PTG 期间的讨论结果 [2],这个想法仍然有意义,我们将提出一个新的 API 来支持它。

用例

  • 用户希望重新镜像卷,而无需重新创建具有新卷 ID 的新卷。

  • Nova 需要一个新的 API 来重新镜像服务器重建期间附加的根卷。

提议的变更

此规范建议向卷操作 API 添加一个新的 ‘os-reimage’ 操作。

  • 向卷操作 API 添加一个新的 ‘os-reimage’ 操作。

  • 如果 cinder 微版本不足以支持 ‘os-reimage’ 操作,则请求将被拒绝。

如上所述,此规范的主要目的是用于 Nova 的重建用例。当 Nova 调用 cinder 进行重新镜像时,cinder 将执行以下步骤

  1. 有关 nova 侧操作,请参阅 nova spec 中的 ‘volume-backend-server-rebuild’ [1]

  2. 接收来自 nova 的重新镜像请求,并检查卷是否处于 reserved 状态。

  3. 执行重新镜像操作。在此期间,卷将过渡到 downloading 状态,类似于从镜像创建可启动卷时的状态(本节后面会提供更详细的信息)。

  4. 添加一个新的 ‘volume-reimaged’ 外部事件,并在重新镜像操作完成后使用它来通知 nova,就像我们用于 volume-extend 一样。有关详细信息,请参阅 perform_resize_volume_online

  5. 重新镜像操作成功完成后,nova 将调用 cinder 以使用连接器信息更新附件。

  6. Cinder 将更新附件并将连接信息返回给 Nova。

  7. Nova 完成与 brick 的连接后,Nova 将发出完成附件调用,将卷标记为 in-use

因此,我们建议添加一个新的微版本来支持用户使用新镜像 ID 重新镜像特定卷。只有 reservedavailableerror 卷可以被重新镜像。reserved 卷只有在 reimage_reserved 参数为 True 时才能被重新镜像。卷状态将首先更改为 downloading

将引入两个单独的策略,一个用于重新镜像 availableerror 卷,另一个用于重新镜像 reserved 卷,这些新操作的默认策略为 SYSTEM_ADMIN_OR_PROJECT_MEMBER

如果镜像状态不是 active,镜像大小或镜像 min_disk 大小大于卷大小,将引发 InvalidInput (400) 错误。

  • 添加一个新的 reimage cast rpc。此 rpc 用于从 cinder API 向 cinder-volume 服务或集群投递异步消息。

  • 添加卷管理器的新的方法。卷管理器将有一个名为 ‘reimage’ 的新方法,该方法将首先从 glance 下载镜像,然后执行重新镜像操作。

  • 添加一个外部事件 volume-reimaged 并调用它以通过 nova API 通知重新镜像操作完成。

我们建议在此规范中仅支持基本实现,重新镜像方法将调用驱动程序的 ‘copy_image_to_volume’ 以使用新镜像重写特定卷。如果特定镜像已加密,则它将调用驱动程序的 ‘copy_image_to_encrypted_volume’。这与我们从镜像创建卷时所做的事情类似。

重新镜像操作完成后,卷将恢复到原始状态,并且此卷的所有先前存在的 volume_glance_metadata 都将被替换为来自新镜像的元数据。

  • 如果重新镜像操作失败,我们将设置用户消息,以提示用户如何从潜在的现在已损坏的启动卷中恢复,并且卷状态将更改为 error

还有一些其他优化机制应该考虑在未来支持,但不会在此规范中实现

  • 重新镜像一个 in-use 卷。如果我们要支持它,我们应该确保此卷可以多重附加,以便我们可以将其附加到主机以支持将镜像复制到卷。并且重新镜像一个 in-use 卷是一个非常危险的操作,我们必须确保在完成重新镜像之前,虚拟机上没有 IO,正在进行或缓存,否则会损坏卷数据。我们不会在此规范中支持此操作。

  • 从镜像缓存重新镜像卷。目前,Cinder 支持从镜像缓存创建卷,这可以提高从镜像创建卷的性能,我们也可以考虑在高级实现中添加此改进。

  • 在重新镜像卷时添加镜像签名验证支持。在从镜像创建卷时也有签名,我们也会在高级实现中支持它。在实现之前,将在 API 参考文档中将其作为限制说明。

备选方案

如果用户想要将卷重新镜像到相同的镜像,用户可以将卷恢复到创建镜像后创建的快照。

但是对于不同的镜像,用户可以先删除卷,然后使用特定的新镜像重新创建卷。Nova 可以编排使用新镜像创建新的根卷,然后在服务器重建操作期间替换它,但正如上面提到的,存在一些问题,例如配额以及 nova 应该如何处理旧卷,您可以在 ML 中找到更多详细信息 [3]

REST API 影响

  • 将创建一个新的微版本来支持卷 ‘os-reimage’ 操作 API

在 v3 中,REST API 如下所示

POST /v3/{project_id}/volumes/{volume_id}/action
{
    "os-reimage": {
        "image_id": "71543ced-a8af-45b6-a5c4-a46282108a90",
        "reimage_reserved": true
    }
}
  • ‘image_id’ 指的是镜像的 ID。由于这是一个必需参数,因此没有默认值。

  • ‘reimage_reserved’ 指的是重新镜像卷并忽略其 ‘reserved’ 状态。可以直接重新镜像 ‘available’ 和 ‘error’ 卷,但只有在参数为 ‘true’ 时才能重新镜像 ‘reserved’ 卷。默认为 ‘false’,这是一个可选参数。

它的响应体如下所示

{
  "volume": {
      "migration_status": null,
      "attachments": [],
      "links": [
          {
              "href": "http://10.79.144.144/volume/v3/ffc60994a7274553905e5e5a8f890ab3/volumes/d90bfc0e-babf-4478-a591-23ca883ba2be",
              "rel": "self"
          },
          {
              "href": "http://10.79.144.144/volume/ffc60994a7274553905e5e5a8f890ab3/volumes/d90bfc0e-babf-4478-a591-23ca883ba2be",
              "rel": "bookmark"
          }
      ],
      "availability_zone": "nova",
      "os-vol-host-attr:host": "ubuntubase@lvmdriver-1#lvmdriver-1",
      "encrypted": false,
      "updated_at": "2018-09-26T01:55:41.084080",
      "replication_status": null,
      "snapshot_id": null,
      "id": "d90bfc0e-babf-4478-a591-23ca883ba2be",
      "size": 2,
      "user_id": "f33299af48b44050b96bc51104f2290a",
      "os-vol-tenant-attr:tenant_id": "ffc60994a7274553905e5e5a8f890ab3",
      "os-vol-mig-status-attr:migstat": null,
      "metadata": { },
      "status": "downloading",
      "volume_image_metadata": {
          "container_format": "bare",
          "min_ram": "0",
          "disk_format": "qcow2",
          "image_name": "cirros-0.3.5-x86_64-disk",
          "image_id": "24d0c0c3-9e03-498c-926f-ac964cbe2e08",
          "checksum": "f8ab98ff5e73ebab884d80c9dc9c7290",
          "min_disk": "0",
          "size": "13267968"
      },
      "description": null,
      "multiattach": false,
      "source_volid": null,
      "consistencygroup_id": null,
      "os-vol-mig-status-attr:name_id": null,
      "name": null,
      "bootable": "true",
      "created_at": "2018-09-26T01:55:38.735749",
      "volume_type": "lvmdriver-1"
    }
}
  • ‘status’ 将为 ‘downloading’。

  • ‘volume_image_metadata’ 指的是卷的镜像元数据。它将在 cinder-volume 中重新镜像操作完成后包含原始镜像,直到重新镜像操作完成。

  • 正常响应代码:202

  • 错误响应代码:400、403、404、409

数据模型影响

安全影响

将引入两个新的策略规则,如 Proposed change 部分所述。

通知影响

将添加重新镜像卷的通知。

其他最终用户影响

将向 python-cinderclient 添加一个新的命令,cinder reimage <volume_id> <image_id> [--ignore-reserved]。此命令镜像底层的 API 函数。

新 API 的调用者需要轮询卷的状态,直到它恢复到原始状态或在操作失败时变为 error。这里的例外是 Nova,它将通过外部事件 API 得到通知,无需轮询重新镜像完成。

由于这是一个数据路径更改,它只会修改卷的内容,并且依赖资源(如快照或备份)不会受到影响。请记住,恢复到较早的备份/快照也会将卷恢复到旧镜像。

性能影响

其他部署者影响

开发人员影响

实现

负责人

主要负责人

Rajat Dhasmana <rajatdhasmana@gmail.com>

工作项

通过支持重新镜像卷,我们需要进行以下更改

  • 向卷操作 API 添加一个新的 ‘os-reimage’ 操作。

  • 添加一个新的 ‘reimage’ cast rpc。

  • 在卷管理器中添加一个新的 ‘reimage’ 方法。

  • 在 python-cinderclient 中采用新的微版本。

  • 在重新镜像失败时设置用户消息。

  • 添加对 nova 外部事件 API 的调用,并带有 ‘volume-reimaged’ 事件

依赖项

测试

将实现单元测试、tempest 和其他相关测试。

文档影响

需要记录卷重新镜像的新行为,以及相关的客户端示例等。

我们还需要在文档中说明,当卷被重新镜像时,卷上的所有当前内容都将被销毁。这一点很重要,因为 cinder 卷被认为是持久的,而此操作并非如此。

参考资料