可互操作的镜像导入

Image Service API 的 2.6 版本引入了实现可互操作镜像导入过程的新 API 调用。这些 API 调用以及使用它们的工作流程在 可互操作的镜像导入Image Service API 参考 的一部分)中描述。该文档解释了最终用户对可互操作镜像导入的视图。在本节中,我们将讨论可供操作员使用的配置选项。

可互操作的镜像导入过程使用 Glance 任务,但不需要将 Tasks API 暴露给最终用户。此外,它需要 taskflow 任务执行器。必须设置以下配置选项

  • [task] 选项组中

    • task_executor 必须设置为 taskflow,或者使用其默认值

  • [taskflow_executor] 选项组中

    • 默认值是可以的。阅读 glance-api.conf 示例文件中的描述是一个好主意,以了解可用的选项。

      注意

      您可以在 Glance 源代码树的 etc/ 子目录中找到一个示例 glance-api.conf 文件。请确保您正在查看与您正在使用的 OpenStack 版本对应的正确分支。

  • 在默认选项组中

    • node_staging_uri 作为 file:///path/to/dir URI(在单存储情况下)或 [os_glance_staging_store]/filesystem_store_datadir 作为路径(在多存储情况下)必须指定 glance 用户可写的目录。有关更多详细信息和建议,请参阅 暂存目录配置

    • enabled_import_methods 必须指定您在安装中公开的导入方法。此设置的默认值为 ['glance-direct','web-download']。有关这些导入方法的描述,请参阅下一节。

此外,您的策略必须允许普通最终用户操作任务。在 Pike 版本之前的版本中,我们建议任务相关的策略仅对管理员开放,以便最终用户无法访问 Tasks API。在 Pike 中,引入了一个新的策略来控制对 Tasks API 的访问。因此,现在可以保持单个任务策略不受限制,同时不向最终用户公开 Tasks API。因此,以下是任务相关策略的推荐配置

"get_task": "",
"get_tasks": "",
"add_task": "",
"modify_task": "",
"tasks_api_access": "role:admin",

镜像导入方法

Glance 提供了四种您可以向用户公开的导入方法:glance-directweb-downloadglance-downloadcopy-image。默认情况下,glance-download 未启用。

  • glance-direct 导入方法允许您的用户直接将镜像数据上传到 Glance。

  • web-download 方法允许最终用户从远程 URL 导入镜像。镜像数据从 URL 检索并存储在 Glance 后端。(换句话说,这是一个从...复制操作。)

    注意

    web-download 导入方法取代了 Image API v1 中可用的 copy-from 功能,但之前在 v2 中不存在。此外,Image API v1 在 Glance 17.0.0 (Rocky) 中已被删除。

  • glance-download 方法允许最终用户从远程 glance 导入镜像。此导入方法用于从由相同的 keystone 联合的另一个 openstack 区域导入镜像。

  • copy-image 方法允许最终用户将现有镜像复制到部署中可用的其他 Glance 后端。只有在您的部署中启用了多个 Glance 后端时,此导入方法才会被使用。

您可以通过 glance-api.conf 文件默认部分中的 enabled_import_methods 配置选项来控制哪些方法可供 API 用户使用。

暂存目录配置

所有导入方法都需要配置暂存目录。这本质上是一个临时抓取位置,镜像可以在此处暂存(由用户通过 glance-direct)、下载(由 web-download)或从现有存储中提取(如在 copy-image 中)后再复制到给定的存储位置。在单存储情况下,此位置由 node_staging_uri 配置选项中的本地文件系统 URI 指定,如下所示

[DEFAULTS]
node_staging_uri = file:///var/lib/glance/staging

在多存储情况下,如 保留存储 中所述,暂存存储应使用以下路径进行配置

[os_glance_staging_store]
filesystem_store_datadir = /var/lib/glance/staging

每个 worker 的暂存目录必须为所有导入方法配置,并且可以是本地的(推荐)或共享的。在共享位置的情况下,所有 Glance API worker 都将依赖于共享存储的可用性,将竞争 IO 资源,并可能引入额外的网络流量。如果选择 本地 存储,则必须使用其他 worker 可以直接访问它的 URL 配置每个 worker。这允许一个 worker 在负载均衡器后面暂存一个镜像,而另一个 worker 处理后续的导入请求。例如

[DEFAULTS]
worker_self_reference_url = https://glance01.example.com:8000

假设您有几个名为 glance01glance02 等的 glance-api worker 位于您的负载均衡器后面。

请注意,如果未设置 worker_self_reference_url,则将使用 public_endpoint 作为默认值。由于通常会将此值设置为所有 worker 的相同值,因此结果是所有 worker 都将假定相同的身份,从而恢复到共享暂存行为。如果为一个或一组 worker 设置了不同的 public_endpoint,则它们将被视为隔离的,因此不共享暂存存储。

配置 glance-direct 方法

对于 glance-direct 方法,请确保 glance-direct 包含在您的 enabled_import_methods 设置中指定的列表中,并且暂存目录配置选项已正确设置。

请注意,为了使用 glance-direct,必须如上所述设置 worker_self_reference_url 配置选项,或者所有 Glance API worker 必须将其暂存目录挂载到公共位置(例如 NFS 服务器)。

配置 web-download 方法

要启用 web-download 导入方法,请确保它包含在 enabled_import_methods 选项的列表中,并且暂存目录配置选项已正确设置。

此外,您还可以使用以下配置。

根据您的云的性质和用户的复杂程度,您可能希望限制他们可以用于 web-download 导入方法的 URI。

注意

您应该了解 OSSN-0078,“Image Service API v1 中的 copy_from 允许网络端口扫描”。v1 copy_from 功能不具有此处描述的可配置性。

您可以通过配置 glance-image-import.conf 文件 [import_filtering_opts] 部分中的选项来执行此操作。

注意

glance-image-import.conf 是一个可选文件。(有关如果您不包含此文件的默认设置,请参见下文。)

您可以在 Glance 源代码树的 etc/ 子目录中找到一个名为 glance-image-import.conf.sample 的示例文件。请确保您正在查看与您正在使用的 OpenStack 版本对应的正确分支。

您可以按三个级别进行白名单(“允许这些”)或黑名单(“允许这些”)

  • 方案 (allowed_schemes, disallowed_schemes)

  • 主机 (allowed_hosts, disallowed_hosts)

  • 端口 (allowed_ports, disallowed_ports)

有六个配置选项,但它的工作方式是,如果您在任何级别都指定了两者,则将遵守白名单并忽略黑名单。(那么为什么要同时使用两者?嗯,您可能希望白名单一个方案,但黑名单一个主机,并白名单一个特定的端口。)

URI 的验证过程如下

  1. 检查方案。

    1. 缺少方案:拒绝

    2. 如果存在白名单,并且方案不在其中:拒绝。否则,跳过 c 并继续到 2。

    3. 如果存在黑名单,并且方案在其中:拒绝。

  2. 检查主机名。

    1. 缺少主机名:拒绝

    2. 如果存在白名单,并且主机不在其中:拒绝。否则,跳过 c 并继续到 3。

    3. 如果存在黑名单,并且主机在其中:拒绝。

  3. 如果 URI 中存在端口,则检查端口。

    1. 如果存在白名单,并且端口不在其中:拒绝。否则,跳过 b 并继续到 4。

    2. 如果存在黑名单,并且端口在其中:拒绝。

  4. URI 被接受为有效。

请注意,如果您通过白名单或不黑名单来允许一个方案,则任何使用该方案的 URI(通过不在 URI 中包含端口来使用默认端口)都将被允许。如果它确实包含 URI 中的端口,则将根据上述规则验证 URI。

默认设置

glance-image-import.conf 是一个可选文件。以下是这些选项的默认设置

  • allowed_schemes - ['http', 'https']

  • disallowed_schemes - 空列表

  • allowed_hosts - 空列表

  • disallowed_hosts - 空列表

  • allowed_ports - [80, 443]

  • disallowed_ports - 空列表

因此,如果您使用默认值,最终用户只能访问使用 http 或 https 方案的 URI。用户只能指定 80 和 443 端口。(用户不必指定端口,但如果指定,则必须是 80 或 443。)

注意

glance-image-import.conf 是一个可选文件。您可以在 Glance 源代码树的 etc/ 子目录中找到一个名为 glance-image-import.conf.sample 的示例文件。请确保您正在查看与您正在使用的 OpenStack 版本对应的正确分支。

配置 glance-download 方法

要启用 glance-download 导入方法,请确保它包含在 enabled_import_methods 选项的列表中,并且暂存目录配置选项已正确设置。

此外,您还可以使用以下配置。

根据您对镜像属性的需求,您可能配置其他属性以从远程镜像复制到本地镜像。

您可以通过配置 glance-image-import.conf 文件 [glance_download_properties] 部分中的选项来执行此操作。

extra_properties选项是一个应该从远程镜像复制的属性列表。列出的属性应被视为“以...开头”的属性,这样可以设置命名空间,而不是显式列出命名空间中的每个属性。

默认值是:['hw_', 'trait:', 'os_distro', 'os_secure_boot', 'os_type']

如果您决定设置此选项,默认值将被完全忽略,除非您显式设置它们。

注意

extra_properties选项将忽略 glance 保留的命名空间,这意味着所有以 os_glance 开头的属性都不会被设置到本地镜像上。

注意

glance-image-import.conf 是一个可选文件。您可以在 Glance 源代码树的 etc/ 子目录中找到一个名为 glance-image-import.conf.sample 的示例文件。请确保您正在查看与您正在使用的 OpenStack 版本相对应的分支。

配置 copy-image 方法

对于 copy-image 方法,请确保 copy-image 包含在您的 enabled_import_methods 设置中指定的列表中,并且您的环境中配置了多个 glance 后端。要允许用户对他们不拥有的镜像执行 copy-image 操作,您可以将 copy_image 策略设置为默认值以外的值,例如

"copy_image": "'public':%(visibility)s"

复制多个存储中的现有镜像

从 Ussuri 版本开始,可以使用可互操作的镜像导入工作流将现有镜像数据复制到多个存储中。

基本上,用户只能复制他们拥有的镜像。除非云运营商通过强制策略检查允许复制非拥有的镜像,否则用户将获得“禁止”(未授权操作)响应。即使通过强制策略允许复制非拥有的镜像,镜像的所有权仍然不变。

操作员或最终用户可以通过在请求体中将 all_stores 设置为 True,或者通过在请求体中传递所需的存储列表来复制现有镜像。如果指定了 all_stores 并且镜像数据已经存在于某些可用存储中,则这些存储将从所有配置的存储列表中静默排除,而如果 all_stores 为 False,则在请求体中显式指定了 stores,并且镜像数据存在于任何指定的存储中,则请求将被拒绝。在 all_stores 在请求体中指定并且云运营商也配置了只读 http 存储的情况下,它将被显式排除。

镜像将被从可用位置之一复制到暂存区域,然后使用下面 Importing in multiple stores 部分中解释的导入工作流继续导入处理。

在多个存储中导入

从 Ussuri 开始,可以使用可互操作的镜像导入工作流将数据导入到多个存储中。

镜像的状态根据 all_stores_must_succeed 参数的值设置为 active

  • 如果设置为 False:只要一个存储的导入成功,镜像就会可用。

  • 如果设置为 True(默认值):只有当所有存储都成功处理后,状态才会被设置为 active

检查进度

由于每个存储都按顺序处理,因此根据镜像的大小和要导入数据的存储数量,工作流完成可能需要相当长的时间。可以通过查看 2 个保留的镜像属性来跟踪任务进度

  • os_glance_importing_to_stores:此属性包含尚未处理的存储列表。在导入流程开始时,它将填充请求中提供的存储。每次完全处理一个存储时,它都会从列表中删除。

  • os_glance_failed_import:每次在存储中导入失败时,它都会添加到此列表中。此属性在导入流程开始时被清空。

这两个属性也包含在工作流期间发送的通知中

注意

示例

操作员使用以下参数调用 import image api

curl -i -X POST -H "X-Auth-Token: $token"
     -H "Content-Type: application/json"
     -d '{"method": {"name":"glance-direct"},
          "stores": ["ceph1", "ceph2"],
          "all_stores_must_succeed": false}'
    $image_url/v2/images/{image_id}/import

对 ‘ceph2’ 的上传失败,但在 ‘ceph1’ 上成功。由于参数 all_stores_must_succeed 已设置为 ‘false’,因此任务成功完成,镜像现在处于活动状态。

glance 发送的通知如下所示(有效负载已截断以提高清晰度)

{
    "priority": "INFO",
    "event_type": "image.prepare",
    "timestamp": "2019-08-27 16:10:30.066867",
    "payload": {"status": "importing",
                "name": "example",
                "backend": "ceph1",
                "os_glance_importing_to_stores": ["ceph1", "ceph2"],
                "os_glance_failed_import": [],
                ...},
    "message_id": "1c8993ad-e47c-4af7-9f75-fa49596eeb10",
    ...
}

{
    "priority": "INFO",
    "event_type": "image.upload",
    "timestamp": "2019-08-27 16:10:32.058812",
    "payload": {"status": "active",
                "name": "example",
                "backend": "ceph1",
                "os_glance_importing_to_stores": ["ceph2"],
                "os_glance_failed_import": [],
                ...},
    "message_id": "8b8993ad-e47c-4af7-9f75-fa49596eeb11",
    ...
}

{
    "priority": "INFO",
    "event_type": "image.prepare",
    "timestamp": "2019-08-27 16:10:33.066867",
    "payload": {"status": "active",
                "name": "example",
                "backend": "ceph2",
                "os_glance_importing_to_stores": ["ceph2"],
                "os_glance_failed_import": [],
                ...},
    "message_id": "1c8993ad-e47c-4af7-9f75-fa49596eeb18",
    ...
}

{
    "priority": "ERROR",
    "event_type": "image.upload",
    "timestamp": "2019-08-27 16:10:34.058812",
    "payload": "Error Message",
    "message_id": "8b8993ad-e47c-4af7-9f75-fa49596eeb11",
    ...
}

自定义镜像导入过程

当用户发出 image-import 调用时,Glance 会检索分阶段的镜像数据,对其进行处理,并将结果保存在后端存储中。您可以通过使用插件来自定义此处理的性质。一些插件由 Glance 项目团队提供,您可以使用第三方插件,或者您可以编写自己的插件。

技术信息

可互操作镜像导入的导入步骤由 Taskflow “flow” 对象执行。Glance 提供的此对象将调用您在 glance-image-import.conf 文件中指定的任何插件。插件由 Stevedore 加载,并且必须在 glance.image_import.plugins 命名空间中的入口点注册表中列出。(如果您只使用 Glance 项目团队提供的插件,这些插件已经为您注册。)

插件必须以 Python 编写为 Taskflow “Task” 对象。包含此对象的 文件必须位于 glance/async_/flows/plugins 目录中。插件文件必须包含一个 get_flow 函数,该函数返回一个包装在线性流程中的 Taskflow Task 对象。请参阅位于 glance/async_/flows/plugins/no_op.pyno_op 插件,了解如何执行此操作的示例。

指定要使用的插件

首先,插件代码必须存在于 glance/async_/flows/plugins 目录中。插件的名称是包含插件代码的文件的文件名(不带扩展名)。例如,名为 fred_mertz.py 的文件将包含插件 fred_mertz

其次,插件必须在 glance.image_import.plugins 命名空间的入口点列表中列出。(如果您只使用 Glance 提供的插件,这将已经为您完成,但检查一下永远不会有坏处。)入口点列表位于 setup.cfg 中。找到标题为 [entry_points] 的部分,并查找以 glance.image_import.plugins = 开头的行。它将后跟一系列如下形式的行

<plugin-name> = <module-package-name>:get_flow

例如

no_op = glance.async_.flows.plugins.no_op:get_flow

确保包含您想要使用的任何插件。

第三,插件必须在 glance-image-import.conf 文件中列出,作为 image_import_plugins 选项的值的列表中的一个插件名称。插件的执行顺序是它们在此列表中指定的顺序。

镜像属性注入插件

release 引入

Queens (Glance 16.0.0)

配置文件

glance-image-import.conf

配置文件部分

[inject_metadata_properties]

此插件实现了 Glance 规范 自动将元数据属性注入到非管理员镜像。此插件的一个用例是,运营商希望将特定元数据放在最终用户导入的镜像上,以便从这些镜像启动的虚拟机将位于特定的计算节点上。由于最终用户(镜像所有者)不太可能知道适当的属性或值,因此运营商可以使用此插件在镜像导入时自动注入属性。

注意

此插件只能作为可互操作镜像导入工作流(POST v2/images/{image_id}/import)的一部分使用。它对镜像数据上传调用PUT v2/images/{image_id}/file没有影响

您可以通过适当限制 Glance policy.yaml 文件中的 upload_image 策略来保证您的最终用户必须使用可互操作镜像导入。默认情况下,此策略不受限制(即,任何授权用户都可以发出镜像上传调用)。

例如,要仅允许管理员或服务用户发出镜像上传调用,可以将策略限制如下

"upload_image": "role:admin or (service_user_id:<uuid of nova user>) or
   (service_roles:<service user role>)"

其中“service_role”是为服务用户创建并分配给受信任服务的角色。

要使用镜像属性注入插件,需要进行以下配置。

  1. 您需要配置 ‘glance-image-import.conf’ 文件,如下所示

    [image_import_opts]
    image_import_plugins = [inject_image_metadata]
    
    [inject_metadata_properties]
    ignore_user_roles = admin,...
    inject = property1:value1,property2:value2,...
    

    第一部分,image_import_opts,用于通过将插件名称指定为 image_import_plugins 参数的值的列表中的一个元素来启用插件。插件名称只是 glance/async_/flows/plugins/ 下的模块名称

    第二部分,inject_metadata_properties,是您设置插件参数的位置。(请注意,如果您已在 image_import_plugins 列表中启用插件,则此处指定的这些值才有效。)

    • ignore_user_roles 是一个以逗号分隔的 Keystone 角色列表,插件将忽略这些角色。换句话说,如果发出镜像导入调用的用户具有任何这些角色,插件将不会将任何属性注入到镜像中。

    • inject 是一个以逗号分隔的属性和值列表,这些属性和值将被注入到导入镜像的镜像记录中。每个属性和值应由冒号(‘:’)分隔,如上面的示例所示。

  2. 如果您的用例是您不想允许最终用户创建、修改或删除您在可互操作镜像导入过程中注入的元数据属性,则需要使用 Glance 属性保护功能(自 Havana 版本以来可用)来保护这些属性。

    例如,假设有一个名为 ‘property1’ 的属性,您希望在导入期间注入它,但您只想允许管理员或服务用户创建此属性,并且您只想允许管理员修改或删除它。您可以通过将以下内容添加到属性保护配置文件中来实现这一点

    [property1]
    create = admin,service_role
    read = admin,service_role,member,_member_
    update = admin
    delete = admin
    

    有关更多信息,请参阅本指南的 属性保护 部分。

镜像转换

release 引入

Rocky (Glance 17.0.0)

配置文件

glance-image-import.conf

配置文件部分

[image_conversion]

此插件为可互操作镜像导入实现自动化镜像转换。此插件的一个用例是在 Ceph 作为镜像后端,并且操作员希望通过确保所有镜像都采用原始格式来优化后端能力的环境中,同时不给最终用户带来转换镜像的负担。

注意

此插件只能作为可互操作镜像导入工作流(POST v2/images/{image_id}/import)的一部分使用。它对镜像数据上传调用PUT v2/images/{image_id}/file没有影响

您可以通过适当限制 Glance policy.yaml 文件中的 upload_image 策略来保证您的最终用户必须使用可互操作镜像导入。默认情况下,此策略不受限制(即,任何授权用户都可以发出镜像上传调用)。

例如,要仅允许管理员或服务用户发出镜像上传调用,可以将策略限制如下

"upload_image": "role:admin or (service_user_id:<uuid of nova user>) or
   (service_roles:<service user role>)"

其中“service_role”是为服务用户创建并分配给受信任服务的角色。

要使用镜像转换插件,需要以下配置。

您需要配置 ‘glance-image-import.conf’ 文件,如下所示

[image_import_opts]
image_import_plugins = ['image_conversion']

[image_conversion]
output_format = raw

注意

默认输出格式为 raw,在这种情况下,无需在配置文件中定义 ‘image_conversion’ 部分及其 ‘output_format’。

输入格式需要是 qemu-img 支持的格式之一,此功能才能正常工作。如果 qemu-img 调用在源镜像上失败,并且启用了 ‘image_conversion’ 插件,则导入过程将失败。

注意

image_import_plugins 配置选项是一个列表,可以为导入流程启用多个插件。插件不会并行运行。可以通过在 glance-image-import.conf 中配置它们来启用多个插件,例如如下所示

[image_import_opts]
image_import_plugins = ['inject_image_metadata', 'image_conversion']

[inject_metadata_properties]
ignore_user_roles = admin,...
inject = "property1":"value1","property2":"value2",...

[image_conversion]
output_format = raw

镜像解压缩

release 引入

Ussuri (Glance 20.0.0)

配置文件

glance-image-import.conf

此插件为可互操作镜像导入实现自动化镜像解压缩。此插件的一个用例是在用户或操作员希望使用 ‘web-download’ 方法,并且镜像提供者仅提供压缩镜像的环境中。

注意

此插件只能作为可互操作镜像导入工作流(POST v2/images/{image_id}/import)的一部分使用。它对镜像数据上传调用PUT v2/images/{image_id}/file没有影响

您可以通过适当限制 Glance policy.yaml 文件中的 upload_image 策略来保证您的最终用户必须使用可互操作镜像导入。默认情况下,此策略不受限制(即,任何授权用户都可以发出镜像上传调用)。

例如,要仅允许管理员或服务用户发出镜像上传调用,可以将策略限制如下

"upload_image": "role:admin or (service_user_id:<uuid of nova user>) or
(service_roles:<service user role>)"

其中“service_role”是为服务用户创建并分配给受信任服务的角色。

注意

如果镜像的 container_format 设置为 compressed,则插件将不会解压缩镜像。这是为了保持镜像创建者的原始意图。

要使用镜像解压缩插件,需要以下配置。

您需要在 ‘glance-image-import.conf’ 文件中添加 “image_decompression”,如下所示

[image_import_opts]
image_import_plugins = ['image_decompression']

注意

镜像解压缩支持的归档类型包括 zip、lha/lzh 和 gzip。目前插件不支持多层归档(如 tar.gz)。只有在安装了 python3 lhafile 依赖库的情况下才支持 Lha/lzh,缺少此依赖项将导致提供 lha 文件时导入作业失败。(在这种情况下,我们知道它将无法启动,因为镜像已压缩,并且我们没有解压缩它的手段。)

注意

image_import_plugins 配置选项是一个列表,可以为导入流程启用多个插件。插件不会并行运行。可以通过在 glance-image-import.conf 中配置它们来启用多个插件,例如如下所示

[image_import_opts]
image_import_plugins = ['image_decompression', 'image_conversion']

[image_conversion]
output_format = raw

如果同时使用镜像转换,必须先进行解压缩,插件的顺序可以确保这一点。