多存储后端支持¶
https://blueprints.launchpad.net/glance/+spec/multi-store
Image 服务支持多种后端来存储虚拟机镜像,包括 Block Storage 服务 (cinder)、文件系统 (本地文件系统上的目录)、HTTP、Ceph RBD、Sheepdog、Object Storage 服务 (swift) 和 VMware ESX。目前,操作员可以为每个 scheme 配置单个后端,但无法为相同或不同的存储配置多个后端。例如,如果云部署了多个 Ceph,Glance 将无法同时使用所有这些后端。
考虑以下用例,以提供多存储后端支持
部署者可能希望为不同存储层级提供不同的成本级别,例如,一个后端用于 SSD,另一个用于机械硬盘。客户可以根据其需求选择其中之一。
旧存储已退役,部署者希望所有新镜像都添加到新存储,而旧存储将在数据迁移完成之前保持运行。
操作员希望区分用户添加的镜像和系统添加的镜像。
来自不同后端的不同 hypervisor(例如,Ceph、Cinder、VMware 等)。
每个站点都有其本地后端,nova 主机直接访问这些后端(Ceph),用户可以选择存储镜像的站点。
问题描述¶
目前 Glance 仅支持每个 scheme 一个存储。因此,例如,如果操作员想要为 2 个后端 Ceph 服务器配置 Ceph 存储 (RBD) 驱动程序(每个存储一个),那么在不进行大量更改的情况下,今天这是不可能的。
即使更改了存储驱动程序代码,操作员今天仍然没有办法使用直接的镜像 URL 来上传或下载目标存储中的镜像位。
因此,操作员今天需要执行许多手动步骤来复制或将镜像位定位到后端 Glance 存储。例如,为了将现有镜像的位复制到与主存储相同类型/scheme 的辅助存储
将镜像位手动复制到辅助存储是一项手动、非同步的任务。
操作员必须手动管理存储位置;没有办法查询可用的存储来备份 Glance 中的镜像位。
操作员必须记住使用 Glance API 注册辅助位置 URL,因为手动构造位置 URL 容易出错,因为某些 URL 既长又复杂。此外,它们需要了解后端存储才能正确构造。
另外,考虑当 Glance API 消费者想要从通过非同步方式添加的辅助后端位置下载镜像位时的情况。今天,消费者必须使用直接位置 URL,这意味着消费者需要必要的逻辑才能将该直接 URL 转换为与后端的连接。
提议的变更¶
本规范提出以下高级功能,以支持相同 scheme/type 的多个存储
在 glance-api.conf 中支持以及支持逻辑,以配置、管理和使用相同或不同类型/scheme 的多个存储。
增强镜像上传 API,以(可选)支持将后端存储定位到镜像位。
增强镜像下载代码,以从任何启用的后端下载镜像。
增强镜像导入 API,以(可选)支持将后端存储定位到下载镜像位的位置。
与后端存储相关的附加元数据属性添加到镜像位置的元数据属性中。
一个新的 REST API,用于列出 Glance 服务已知的所有已配置存储。
** Config/glance-store 更改**
为了支持相同或不同类型/scheme 的多存储,我们建议弃用 ‘stores’、‘default_store’ 配置选项,并在 DEFAULT 部分添加一个新的配置选项 enabled_backends,在 ‘glance_store’ 部分添加 ‘default_backend’ 选项,以及在 glance-api.conf 的所需存储的每个部分下添加 ‘description’ 选项。操作员可以使用 enabled_backends 来指定存储后端及其存储类型的逗号分隔的键值对,然后每个后端将具有一个不同的部分来指定相关的配置选项。如果未显式设置 ‘default_backend’,则将引发适当的异常,这将阻止服务启动。
弃用 ‘default_store’ 配置选项的原因是 Glance 在服务启动时会验证默认存储,如果它不是列出的存储之一(file、http、rbd、swift、cinder、vmware 或 sheepdog),则会引发错误并阻止服务启动。此验证是使用 ConfigOption 对象的 ‘choices’ 属性完成的。在启用多存储支持后,使用 ‘choices’ 属性进行这种验证检查将变得困难,因为 default_store 名称将是存储标识符,而不是实际的存储。
考虑以下 glance-api.conf 片段示例,该示例配置了 3 个存储以供使用
[DEFAULT]
# list of enabled stores identified by their property group name
enabled_backends = fast:rbd, cheap:rbd, reliable:file
# the default store, if not set glance-api service will not start
default_backend = fast
# conf props for file system store instance
[reliable]
filesystem_store_datadir = /var/lib/images/data/
description = Reliable filesystem store
# etc..
# conf props for ceph store instance
[fast]
rbd_store_ceph_conf = /opt/ceph1/ceph.conf
description = Fast access to rbd store
# etc..
# conf props for ceph store instance
[cheap]
rbd_store_ceph_conf = /opt/ceph2/ceph.conf
description = Less expensive rbd store
# etc..
上面的示例是针对 Ceph 的,但它适用于任何存储后端。如上例所示,‘enabled_backends’ 属性是存储标识符的逗号分隔列表,这些标识符已设置为 Glance。每个存储标识符定义了一个属性组名称,该名称本身包含用于配置存储实例的存储特定属性,以及一个存储类型,该类型将用于在新的配置部分中注册与该存储相关的配置选项,这些配置部分是使用存储标识符定义的。在底层,存储标识符(也称为 id)映射到用于实例的存储类。
虽然 ‘stores’ 和 ‘default_store’ 可用,但操作员可以不设置 ‘enabled_backends’ 属性,在这种情况下,多存储支持未“启用”,Glance 将按原样工作。删除这些配置选项后,操作员至少需要在 ‘enabled_backends’ 中设置一个存储,否则 glance-api 服务将无法启动。
为了适应相同 scheme 的多个存储,用于索引存储的 scheme_map 必须按 scheme 索引存储标识符。存储标识符(隐式地)是 glance-api.conf 中给定的 conf 组的名称(例如,上面的示例中的 reliable、fast 和 cheap)。
考虑以下索引方法
scheme_map[scheme][store_id]
其中 ‘scheme’ 是存储实现支持的 scheme,‘store_id’ 是存储的标识符。
为了在它们未被弃用时与旧存储 API 保持向后兼容,我们还建议添加新的存储 API,例如 add、get、delete 等到 glance_store。当 ‘stores’ 和 ‘default_store’ 配置选项的弃用期结束时,将删除旧的存储 API。
API 列出存储
为了适应 Glance 存储的管理和发现,Glance 还应提供一个 REST API,该 API 允许用户列出为 Glance 配置的所有存储。这是 Glance 存储的只读列表,包括存储标识符、每个存储的描述以及一个标志,该标志将指示存储是否为默认存储。
注意:Glance 存储列表基于 glance-api.conf,关于存储配置。操作员将无法使用 API 配置新存储。因此,为了在响应中显示描述,如前所述,我们建议在每个存储中添加一个新的配置选项 ‘description’,并提供一些默认描述,操作员可以根据需要进行设置。
如本文所述,存储标识符可用于寻址适用于图像上传和图像导入等操作的存储实例。
我们建议将新的 REST 资源定位在以下 URI
/v2/info/stores
有关此 API 的更多详细信息,请参阅本规范的 REST API 部分。
图像上传 API 现有的图像上传 API 允许操作员将图像位上传到 Glance 服务。但是,今天此 API 并没有提供一种方法让操作员将特定的存储定位到备份图像位的位置(技术上,v1 API 允许您指定要定位的存储 scheme)。本规范建议增强 API,以允许操作员指定将备份图像位的存储。
我们建议使用标头字段作为传输备份图像位的存储标识符的一种方式。同样,底层标识符是各自 Glance 存储驱动程序的属性组名称。当使用图像上传 API 上传图像位时,Glance 逻辑将确定是否指定了目标存储,如果是,则将图像位添加到目标存储。
如果在上传请求中未指定存储,则使用 ‘default_backend’ 来备份图像位。
使用此方案,操作员将能够在上传操作期间指定他们希望将图像位备份到哪个存储。我们建议使用 ‘X-Image-Meta-Store’ 标头作为传输目标存储标识符的一种方式。
有关此 API 的更多详细信息,请参阅本规范的 REST API 部分。
图像下载 如果云升级为使用多存储支持从单存储,那么 Glance 需要处理来自旧存储到新存储的位置。例如,如果操作员正在使用 rbd(ceph)后端,现在他升级了环境并引入了两个额外的 rbd 存储作为 ceph1 和 ceph2,默认存储为 ‘ceph1’,那么 Glance 必须能够从旧存储(ceph)下载图像。
有了多个后端可用,Glance 需要一些增强功能,以便它可以满足当前的图像下载 API 合同。下载请求将遍历所有配置的后端以查找图像。正如我们在位置元数据中添加存储信息一样,首先它将在位置元数据中设置的存储中查找图像。如果位置元数据未设置,那么根据配置部分中的示例,如果位置是 rbd://<something>,那么它将在所有可用的 ceph 存储中搜索图像,即,在本例中为 ‘fast’ 和 ‘cheap’。这样,即使云升级为使用多个存储,用户也能够从旧存储下载其图像。
图像导入 API 现有的图像导入 API 允许最终用户将图像从暂存区域导入到 Glance 后端。但是,今天此 API 并没有提供一种方法让最终用户将特定的存储定位到导入图像的位置。本规范建议增强 API,以允许最终用户指定将备份导入图像的存储。
我们建议使用标头字段作为传输导入图像的存储标识符的一种方式。同样,底层标识符是各自 Glance 存储驱动程序的属性组名称。当使用图像导入 API 导入图像时,Glance 逻辑将确定是否指定了目标存储标头,如果是,则将图像导入到目标存储。
如果在导入请求中未指定存储,则使用 ‘default_backend’ 导入图像。
使用此方案,最终用户将能够在导入操作期间指定他们希望将图像导入到哪个存储。我们建议使用 ‘X-Image-Meta-Store’ 标头作为传输目标存储标识符的一种方式。
有关此 API 的更多详细信息,请参阅本规范的 REST API 部分。
存储位置元数据属性 在当前的 Glance API 中,Glance API 的消费者无法通过检查图像的位置 URL 来关联图像位置与其各自的存储。虽然这对于许多用例来说可能有效,但在多存储环境中需要更友好的关系;用户需要图像位置与其各自存储之间的显式关系(例如,此位置由哪个存储备份)。
本规范建议,当使用图像上传 API 添加图像位时,核心 Glance 逻辑负责将元数据属性添加到图像位置 URL,以反映备份存储的标识符。例如,如果用户将图像上传到我们上面的示例中的 ‘ceph1’ 存储,则在上传图像位后,将添加图像位置 URL,并且在 URL 的元数据中,将存储标识符添加到位置元数据对象。
有了图像位置 URL 元数据中的存储标识符,我们可以将其与图像响应中的新属性 ‘store’ 一起暴露给最终用户,以便在后续操作或 API 消费者逻辑中使用。
带有存储属性的新图像响应如下所示
"size": 1234,
"store": ["reliable"],
"checksum": 1234567890,
"name": "Import image",
"status": active
备选方案¶
在 Glance 中采用多存储方法有两个主要替代方案;每个存储使用一个服务以及每个驱动程序支持多存储。
每个存储服务 在每个存储服务方法中,每个配置的存储实例都将作为单独的进程/服务运行。因此,每个服务都有自己的 AMQP/RPC 接口、自己的 PID 等。为了将请求路由到存储服务,我们将使用调度器,它本身是另一个进程/服务。这是 Cinder 多后端支持中使用的方法。
虽然每个存储服务方法可能是 Glance 的长期目标,但今天我们还没有从我们的消费者群体中看到足够的理由来证明需要进行重大重构/更改才能将 Glance 迁移到这种模型。
因此,本规范建议本规范中概述的多存储方法 - 首先让初始近似的多存储工作,并根据社区的消费者反馈来确定我们的下一步行动。
每个驱动程序支持 另一种潜在的方法是将多存储逻辑推送到每个 Glance 存储驱动程序的实现中。例如,存储驱动程序本身可以包含与多个后端复用的逻辑。
虽然这种方法有效,但它需要更改每个存储驱动程序的实现,并且会导致代码重用的次优结果。
本规范建议采用一种多存储方法,该方法对每个存储驱动程序的影响很小或没有影响;它们可以在多存储实现中按原样使用。通过将支持相同 scheme 的多个存储的逻辑推送到 Glance 的核心,我们可以获得最大的重用,并且存储驱动程序实现无需关注此类逻辑。
数据模型影响¶
本规范没有提出对数据模型进行任何更改。相反,本文档中的方法可以在内存或 Glance 使用的现有模式中维护所有新的有状态数据。但是,存储标识符将作为位置对象中的元数据存储。
REST API 影响¶
此规范提出了以下 API 更改
新的 API
列出 Glance 服务已知的所有存储。
修改后的 API
导入镜像。
上传图像文件。
获取图像详细信息。
常见响应代码
创建 成功:201 Created
修改成功:200 OK
删除 成功:204 No Content
失败:400 Bad Request,包含详细信息。
禁止:403 Forbidden
API 版本
所有 URL 都在 v2 Glance API 下。如果未明确指定,则假定 /v2/<url>
[新 API] 列出存储
列出 Glance 服务已知的所有存储
GET /v2/info/stores
此 API 不接受任何查询参数,授权后会返回 Glance 服务已知的所有存储的列表。Glance 知道的存储是在 glance-api.conf 中配置并在 Glance 启动期间加载的存储。响应主体有效负载是 JSON,包含每个存储的 JSON 对象。每个存储 JSON 对象包含存储标识符 (id)、描述以及如果特定存储是默认存储,则它将具有一个指示存储是否为默认存储的标志。例如
{
"stores":[
{
"id":"reliable",
"description": "Reliable filesystem store"
},
{
"id":"fast",
"description": "Fast access to rbd store",
"default": true
},
{
"id":"cheap",
"description": "Less expensive rbd store"
}
]
}
响应代码
200 – 授权并成功请求后。响应主体包含包含已知存储的 JSON 有效负载。
[修改后的 API] 创建图像 我们建议向 image-create 响应添加一个 ‘OpenStack-image-store-ids’ 标头,该标头将包含可用的存储。使用此信息,用户可以决定上传/导入图像的存储,而无需进行单独的 get-stores 调用。
新的响应头¶
OpenStack-image-store-ids
此头的值将是一个逗号分隔的可用存储列表。例如,
OpenStack-image-store-ids: fast, cheap, reliable
[修改的 API] 上传镜像二进制数据
获取镜像二进制数据
PUT /v2/images/{image_id}/file
此修改现有的 REST API 以支持一个新的可选头字段,如果存在,则指定将镜像数据上传到的存储 ID。为了向后兼容,如果未指定该头,则将镜像上传到指定为默认存储(例如 default_store)的存储。
新的头字段
X-Image-Meta-Store – 如果存在,则包含将镜像二进制数据上传到的存储 ID。
新的/更改的响应代码
400 – 如果存在 X-Image-Meta-Store 头,但指定了一个不存在于该 ID 的存储。
示例 curl 用法
curl -i -X PUT -H "X-Auth-Token: $token" -H "X-Image-Meta-Store:
ceph1" -H "Content-Type: application/octet-stream"
-d @/home/glance/ubuntu-12.10.qcow2
$image_url/v2/images/{image_id}/file
[修改的 API] 获取镜像详情
获取指定镜像的详情
GET /v2/images/{image_id}
虽然此规范对 glance API 层不施加任何更改,但此调用现在将显示位置的存储 ID。如果存在多个位置,则所有位置将显示为逗号分隔的列表。带有存储属性的新镜像响应如下所示:
"size": 1234,
"store": ["reliable"],
"checksum": 1234567890,
"name": "Import image",
"status": active
[修改的 API] 将镜像导入到后端
将镜像导入到后端
POST /v2/images/{image_id}/import
此修改现有的 REST API 以支持一个新的可选头字段,如果存在,则指定将镜像数据导入到的存储 ID。为了向后兼容,如果未指定该头,则将镜像导入到指定为默认存储(例如 default_store)的存储。
新的头字段
X-Image-Meta-Store – 如果存在,则包含将镜像二进制数据上传到的存储 ID。
新的/更改的响应代码
400 – 如果存在 X-Image-Meta-Store 头,但指定了一个不存在于该 ID 的存储。
示例 curl 用法
curl -i -X PUT -H "X-Auth-Token: $token" -H "X-Image-Meta-Store:
ceph1" -H "Content-Type: application/json"
-d '{"method":{"name":"glance-direct"}}'
$image_url/v2/images/{image_id}/import
安全影响¶
无
通知影响¶
需要在通知响应中添加“stores”字段,因为此提案的一个用例是提供不同的存储价格等级,这将帮助消耗通知的系统执行计费。
其他最终用户影响¶
此提案引入了一些其他值得注意的用户影响。
Glance 客户端 理想情况下,glance 客户端(CLI + REST 客户端)应根据此规范进行更新。特别是
CLI / API 支持列出 glance 存储。
CLI / API 支持在上传/导入时指定存储 ID。
配置 部署者需要了解 glance 多存储的配置方面。从配置角度来看,为 glance 配置多存储将非常类似于为 cinder 配置多后端。需要记录配置文件中的具体内容。
性能影响¶
从旧存储下载镜像的性能会略有下降。例如,如果现有用户正在使用单个 rbd(例如 ceph)后端,现在他升级了环境并引入了两个额外的 rbd 存储作为 ceph1 和 ceph2,默认存储为“ceph1”,那么需要从旧存储(ceph)下载的镜像将需要一些时间,因为它需要在所有启用的后端中查找。
其他部署者影响¶
合并后,除非部署者在 glance-api.conf 中配置 enabled_backends 属性,否则 glance 多存储未启用,因此开箱即用具有向后兼容性。当多存储被禁用时,v2 API 用户可以使用 list stores API 并将检索到配置的当前存储列表(当然,每个方案只有一个存储)。
开发人员影响¶
无
实现¶
负责人¶
- 主要负责人
abhishek-kekane
- 其他贡献者
无
工作项¶
实施任务可能包括
多存储的配置支持。
多存储加载和索引。
List stores API。
上传时的 Location URL 元数据存储 ID。
在镜像响应中添加新的“store”属性。
针对存储的目标的镜像上传。
针对存储的目标的镜像导入。
多存储删除和其他存储访问代码路径。
添加 python-glanceclient 支持
依赖项¶
无
测试¶
需要添加新的 tempest 测试来验证多存储支持
文档影响¶
如“工作项”部分所述,我们需要确保 glance 文档更新为
新的 list stores REST API。
用于镜像上传的新头字段。
用于镜像导入的新头字段。
镜像响应中的新存储 ID。
关于该功能的整体 glance 多存储文档,以教育部署者如何使用它。