分布式镜像导入支持

https://blueprints.launchpad.net/glance/+spec/distributed-image-import

Glance 正在朝着支持镜像上丰富的操作发展,主要是在创建时通过导入机制实现。这为元数据注入、格式转换和在存储之间复制等功能打开了大门。目前,为了使之工作,对于用户来说最接近 image-upload (即 glance-direct 导入方法) 的功能,API 节点需要访问共享存储,这对部署者来说是一个真正的障碍,也是本规范的主题。

问题描述

当前,当通过导入机制上传镜像时,它们存储在一个名为“staging”的特殊区域。在底层实现中,这被实现为 glance_store,但它必须是主机文件系统上本地可访问的目录。在使用多个 API worker 节点(就像任何实际部署一样)时,所有 worker 节点的 staging 目录必须共享(例如,挂载在通用的 NFS 服务器上),才能支持 glance-direct 导入方法。这显然对 HA、性能以及任何 Glance API worker 位于远程站点的情况来说都是一个问题。

为了使镜像从零到可用,使用 glance-direct 导入,需要多个 API 请求。其中之一是镜像数据的“staging”,然后是“import”操作,它将数据从 staging 区域移动到其最终目的地。在多节点负载均衡场景中,“stage”操作几乎肯定会命中与“import”操作不同的 worker,这将导致后者无法访问其 staging store 中的 staging 镜像数据,从而导致失败。

提议的变更

本规范概述的工作目标是允许 API worker 将其 staging store 目录保持本地且不共享,但仍然能够使导入操作正常工作。为了做到这一点,我们将

  1. 记录其他 worker 可以通过数据库访问 staging worker 的 URL,并且

  2. 如果镜像不是本地的,则通过该 URL 将导入请求代理到托管该镜像的节点。

  3. 在镜像处于 staging 状态时,任何删除请求也需要被代理,以确保临时文件从适当节点上的 staging 目录中被删除。

通过上述更改,我们可以消除 API worker 节点之间共享存储的需要,从而使它们能够从 HA 的角度隔离,并进行地理分布。它需要的实际更改很少,因为非本地接收节点只需将收到的请求代理到托管 staging 镜像的节点并返回结果。 importdelete 操作都很快,并且不需要链式客户端 -> 代理 -> 目的地安排持续很长时间。

备选方案

另一种选择是始终什么也不做。我们可以继续要求在 API 节点之间共享 staging 区域的存储以支持导入功能。我们也可以引导用户在无法使用共享目录的情况下使用镜像上传而不是导入。

另一种选择是做与此处描述的相同的事情,但通过 RabbitMQ 或其他 RPC 机制实现。这具有需要额外的支持基础设施的缺点,而 Glance 目前不需要这些基础设施,以及处理发送和接收这些 RPC 调用并将它们定向到适当的内部操作的新代码。

数据模型影响

为了做到这一点,我们只需要存储一个新信息,并且只在短时间内存储。那就是托管 staging 镜像的 API worker 节点的直接 URL。当镜像最终导入(通常在 staging 之后立即发生)时,该 URL 不再需要(也不相关)。

最初,此实现将使用保留的和不依赖于配额的 os_glance 命名空间将 URL 存储在镜像的 extra_properties 中。

稍后,当完成将 staging 目录用作适当的 Glance 存储的工作时,我们可能能够将 URL 存储在将 staging 镜像数据注册到那里时的位置元数据中。当发生这种情况并且假设有适当的接口来使用该位置元数据时,计划将此实现使用该元数据存储代替。

REST API 影响

无。

安全影响

代理行为将使用负载均衡器选择的 worker 呈现给用户的 token 来完成。不添加额外的授权,并且该 token 用于代表用户向适当的 worker 发出请求。因此,此操作从安全角度来看是完全透明的。

通知影响

无。

其他最终用户影响

在实施此功能后,更多的用户将能够使用镜像导入功能,因为不愿意或无法在其 worker 之间提供共享存储的运营商将不再需要为他们的用户禁用 glance-direct 导入。

性能影响

消除 staging store 的共享 NFS(或类似)存储位置应该可以提高上传和导入的性能,因为 staging 目录可以是本地的。它还大大减少了在执行单个镜像导入的过程中,需要在网络上多次来回移动潜在的非常大的镜像的需要(从镜像数据的四次往返行程减少到两次)。

其他部署者影响

部署者可能希望在升级到支持此功能的版本后启用镜像导入,而之前他们需要禁用该功能(或只是 glance-direct)。他们需要使用一个额外的元素配置每个 API worker,指示可以通过哪个直接 URL 访问它们,并确保 API 节点能够以这种方式相互通信。

当前支持通过共享存储导入的部署者可能希望在将 worker 从共享存储位置拆分为本地目录时使镜像活动静止。

希望保留镜像 staging 的共享存储的部署者可以选择这样做,而无需产生任何影响或采取任何操作。

希望保留导入功能(或只是 glance-direct 方法)禁用的部署者也可以这样做,而无需产生任何影响或采取任何操作。

开发人员影响

当我们将转向上述详细描述的基于位置的元数据方法时,我们需要更改 API,从使用镜像 extra_properties 字典到将该信息传递到存储例程。预计这将少于十行代码。

实现

负责人

主要负责人

danms

工作项

  1. 构建一种机制,通过该机制我们可以使用用户的授权 token 向另一个服务发出外向调用

  2. 添加一个配置元素,允许运营商教导 API worker 他们的外部可见 URL 是什么。

  3. 使 API worker 在镜像 stage 操作期间记录他们自己的 URL。

  4. 当确定适当这样做时,使 importdelete 操作代理到适当的 URL。

依赖项

  • Devstack 需要支持启动额外的 Glance worker,以便正确测试此功能。

  • Tempest 需要支持在服务目录中查找替代镜像服务。

测试

API 行为和导入任务的单元测试就足够了,因为更改很小。

镜像代理的功能测试。

将编写一组 Tempest 测试,这些测试将在不同的 Glance worker 上 staging 和导入/删除具有单独 staging 目录的镜像,以确保以现实意义上涵盖此行为的 CI 覆盖率。

文档影响

由于这只是让一些东西起作用,而之前没有起作用,因此不需要编写大量的文档。如上所述,部署者将在 API 节点上设置一个新配置选项,以及需要解决的网络和防火墙注意事项,以便使其工作,这些将在文档中涵盖。

参考资料

关于此的许多讨论是在另一个规范上进行的

此代码实现也包含与该主题相关的讨论

这在 Wallaby PTG 的 Glance 会议中讨论过,主题是“集群感知”

这在多个 Glance 会议中讨论过