使 Manila share 网络跨越多个子网(含 AZ)

https://blueprints.launchpad.net/manila/+spec/share-network-multiple-subnets

Manila 可以使用处理 share 服务器创建和管理的 share 驱动程序进行部署。在这种部署中,用户通过指定 neutron 中的网络和子网 ID 来创建 share 网络。如果 share 驱动程序配置正确,则将使用指定 neutron 子网中的网络信息创建 share 服务器。这些网络信息包括 share 服务器创建的 IP 地址,这些地址反映在由此类驱动程序创建的 share 的导出位置中。

如果 share 驱动程序配置为 standalone 网络或 single 网络配置 [1],则 share 服务器将使用 manila.conf 文件中的网络详细信息创建。在这种情况下,用户指定的 share 网络中的网络信息(目前)将被忽略。未来计划提供网络隧道,从而在配置网络和用户指定的网络之间实现连接。

用户使用 share 网络来创建 share。share 与单个 share 网络关联,并从与 share 网络关联的 share 服务器导出。用户还可以将安全服务(如 LDAP、Active Directory 或 Kerberos)与 share 网络关联,从而影响 share 网络上的所有 share。

问题描述

在 OpenStack Mitaka 版本中设计 share 复制 [2] 时,我们决定使复制在可用区内和可用区之间工作。但是,此功能仅限于具有预配置 share 服务器的驱动程序(DHSS = False 模式)。我们意识到,在不更改 share 网络设计的情况下,我们无法支持使用支持 share 服务器处理的驱动程序创建的 share 的复制。

使用 share 复制时,我们建议在 OpenStack 云中使用可用区作为 **故障域**。当 share 复制用于灾难恢复工作负载时,manila-share 服务将在不同的可用区中运行。用户将在一个可用区中创建主 share,并在不同的可用区中创建副本。因此,创建用于处理和导出这些 share 的 share 服务器需要在各自的可用区内创建。

可用区在其他 OpenStack 服务(如 nova 和 cinder)中用作在 OpenStack 部署中逻辑划分资源的一种方式。这种划分可能是因为这些资源旨在用于特定任务,或者因为它们位于同一位置。但是,最常见的标准是这些资源与共同的故障点相关联,例如连接到公共电源。在 OpenStack Mitaka 版本中,neutron 添加了对可用区的支持 [3][4]。有了这个,用户就可以将网络资源分配给可用区以实现高可用性。

在 Liberty 版本中,当添加 share 实例以支持 share 复制和 share 迁移等功能时,我们承认用户的 share 资源可以同时存在于多个位置。这些位置可能位于不同的网络子网和/或可用区。

目前,没有规定允许用户将他们的 Manila 网络资源隔离到他们创建计算主机聚合或块/共享文件系统存储资源所在的可用区内。

用例

  • 允许 share 网络跨越多个子网,可以更真实地表示内部数据中心网络,当用户希望 share 网络表示资源的不同实例之间的网络连接时。

    目前,当用户在子网上启动计算实例或共享文件系统时,该子网上的所有其他资源都具有与该资源的网络连接。如果存在可以发送和接收这些子网之间流量的路由器,则其他子网上的资源可以“访问”该资源。

    当用户以分布式方式创建共享文件系统时,很有可能他们希望他们的镜像(share 副本)或迁移目标(share 实例)位于不同的子网上。

    同时,部署者也可能选择创建跨越所有可用区的巨大子网。

  • Manila 中的 share 服务器从子网消耗网络分配。对于 share 复制和 share 迁移等高级工作负载,它们可能经常需要相互通信。

    因此,用户创建一个 share 网络并将其分配给子网在语义上是有意义的。这将有效地将管理特定 share 的 share 实例的所有 share 服务器标记为一个网络。但是,每个单独的 share 实例都是从特定的子网导出的。

提议的变更

为了解决允许用户在故障域内管理他们的 share 实例(以及随之而来的 share 服务器)的问题,并为了更好地表示用户 OpenStack 云中的共享文件系统的实例

  • Share 网络将跨越多个子网。这些子网将与每个可用区关联。

  • 可以有一个与 share 网络关联的子网,该子网与所有存储可用区关联。为了本规范的目的,我们将此称为 default 子网。虽然不与任何特定的可用区关联,但此 default 子网旨在服务所有可用区。

  • 每个 share 网络最多只能有一个 default 子网。

  • share 网络不一定需要一个 default 子网。

  • 用户将能够为每个 share 网络分配每个配置存储可用区的一个子网。如果他们的设置允许,他们可以将相同的子网分配给不同的 AZ,但他们不能为每个 share 网络在特定 AZ 中拥有多个服务子网。

注意

我们可以考虑允许每个 share 网络有多个备用或 default 子网; 同样,我们可以允许为给定可用区指定多个子网。

但是,当用户请求在特定 AZ 中创建资源时,Manila 将无法从它将拥有的选项中选择正确的子网。

为了避免任何不确定(因此错误)的行为,我们不允许每个 share 网络有多个 default 子网;或者每个可用区有多个子网。

  • API 更改将涉及扩展通过添加和删除子网(以及与现有 share 和 share 服务器相关的先决条件)来修改 share 网络的能力。

  • 如果用户希望 share 在特定子网上配置,他们需要在创建 share 时选择 share 网络和 AZ。他们只需要在创建 share 副本时选择 AZ。

不会发生的变化

  • share 仍然只与一个 share 网络关联。

  • share 服务器仍然从单个子网的分配池中分配 IP 地址。

  • 安全服务将继续与 share 网络关联。当在新子网上创建 share 服务器时,它们将从 share 网络派生所有安全服务器信息。

受影响的工作流程

创建 share 网络

用户可以继续使用单个子网创建 share 网络,但他们必须提供要将子网分配到的可用区。用户还可能打算创建一个跨越所有可用区的子网。此子网可以充当 defaultfallback 子网,当没有可用的专用子网来服务给定的可用区时。但是,用户每个 share 网络不能拥有多个这些 default 子网。

或者,用户也可以创建“空”share 网络,就像今天一样。

创建 share 服务器

share 服务器仍然由 manila-share 服务使用来自单个子网的网络分配创建。

创建 share

用户可以像以前一样提供 share 网络来创建 share。但是,如果 share 网络与多个子网关联,他们理想情况下还应提供一个可用区,以便在特定子网上创建它(也许是为了与 OpenStack 云上的其他资源进行协同定位)。

如果用户提供 share 网络和可用区来在其中创建 share,则 API 将验证 share 网络是否支持该 AZ(即,它是否已将子网分配给指定的 AZ 或具有 default 子网)。如果未满足此条件,API 将响应 400 BadRequest

创建 share 副本

用户将在创建主 share 期间提供 share 网络和 AZ。他们只需要提供可用区来在其中创建 share 副本。share 网络从父 share 对象继承,并根据提供的 AZ 选择特定的子网。

注意

目前,创建 share 副本的 API 接受 share_network_id 作为可选参数。我们将删除此参数以支持此工作流程。由于没有 share 驱动程序以 DHSS = True 模式工作并支持 share 复制,我们可以删除此未使用的参数。请参阅相关的 launchpad 错误 [5]。

分配安全服务

用户将继续将安全服务分配给 share 网络,不建议对此工作流程进行任何更改。

备选方案

我们可以保留 share 网络的现有设计,但允许相关资源在多个 share 网络中创建。share 网络不会跨越子网,用户将需要为 share 的每个实例使用不同的 share 网络。他们必须将安全服务配置到这些网络中的每一个。

考虑到未来扩展的范围,这种方法存在局限性。理想情况下,我们希望用户能够根据可用区控制他们的资源,而这种方法不利于实现该目标。

当前,配额是在 share 网络数量上执行的。如果用户需要将多个子网作为多个 share 网络处理,则配额限制将是一个问题。作为用户,我可能希望按可用区划分我的网络资源,而无需消耗网络配额,因为它们都被用于管理相同的 share(及其副本或实例),或相同的安全服务。

数据模型影响

manila.db.sqlalchemy.models.ShareNetwork 模型将不再包含特定于子网的信息:neutron_net_idneutron_subnet_idnetwork_typesegmentation_idcidrip_version。这些键将是新的模型 manila.db .sqlalchemy.models.ShareNetworkSubnet 的一部分,该模型具有主键:id(为本文档的目的,我们将其称为 share_network_subnet_id)和外键,availability_zone_idshare_network_id。share 网络子网仅与一个 share 网络和一个可用区关联。

manila.db.sqlalchemy.models.ShareServer 模型将停止具有与 share_network_id 绑定的外键,并改为具有对 share_network_subnet_id 的外键引用。

不会对 manila.db.sqlalchemy.models.ShareNetworkSecurityServiceAssociationmanila.db.sqlalchemy.models.SecurityServicemanila.db.sqlalchemy .models.ShareInstancemanila.db.sqlalchemy.models.ConsistencyGroup 模型进行任何关键更改。所有这些资源将继续包含指向 manila.db.sqlalchemy.models.ShareNetwork 模型的外部键引用。

数据库升级步骤将为每个现有的共享网络创建一个新的共享网络子网。availability_zone_id 字段将为 null,表示这些是 default 子网,不限于给定的可用区。

数据库降级步骤会将现有的共享网络子网合并到共享网络表中。如果每个共享网络存在多个子网,则此步骤可能会导致信息丢失。因此,不建议在生产云中使用。

REST API 影响

请注意我们在 API 参考 中这些 API 的当前状态。

创建 share 网络:

POST /v2/​{tenant_id}​/share-networks

请求

{
    "share_network": {
        "neutron_net_id": "998b42ee-2cee-4d36-8b95-67b5ca1f2109",
        "neutron_subnet_id": "53482b62-2c84-4a53-b6ab-30d9d9800d06",
        "name": "my_network",
        "description": "This is my share network",
        "availability_zone": "london",
    }
}

子网详细信息 neutron_net_idneutron_subnet_id 是可选的。但是,只要指定了其中一个,就必须同时指定两者,否则 API 将以 400 Bad Request 响应。

availability_zone 是可选的,如果满足以下条件之一:

  • 用户正在创建一个旨在跨越所有可用区的子网。

  • manila-share 服务仅配置了一个可用区,或者,

  • 当未提供子网详细信息时。

如果 manila 不知道 availability_zone,API 将以 400 Bad Request 响应。

如果租户的共享网络配额已超过,API 将以 403 Forbidden 响应。

API 不会与网络提供程序(neutron)验证子网信息。验证将在共享管理器层执行。

响应

Code: 202 Accepted

{
    "share_network": {
        "name": "my_network",
        "created_at": "2016-06-01T21:12:12.617687",
        "id": "77eb3421-4549-4789-ac39-0d5185d68c29",
        "project_id": "e10a683c20da41248cfd5e1ab3d88c62",
        "description": "This is my share network",
        "updated_at": null
    }
}

向共享网络添加子网:

POST /v2/​{tenant_id}​/share-networks/{share_network_id}/subnets

请求

{
    "share-network-subnet" : {
        "neutron_net_id": "998b42ee-2cee-4d36-8b95-67b5ca1f2109",
        "neutron_subnet_id": "12c1490a-e82c-4f5e-bcb1-fb267a58cf10",
        "availability_zone": "paris"
    }
}

这些参数与上述创建 API 具有相同的条件。

如果共享网络 ID 无效,API 将以 404 NotFound 响应。如果已经为指定的可用区定义了子网,API 将以 409 Conflict 响应。

响应

Code: 202 Accepted

{
    "share_network_subnet": {
        "created_at": "2016-06-01T21:12:14.843836",
        "id": "aa7a1269-703b-4832-a3df-17ed954c276c",
        "share_network_id": "77eb3421-4549-4789-ac39-0d5185d68c29",
        "availability_zone": "paris",
        "segmentation_id": null,
        "neutron_subnet_id": "12c1490a-e82c-4f5e-bcb1-fb267a58cf10",
        "updated_at": null,
        "neutron_net_id": "998b42ee-2cee-4d36-8b95-67b5ca1f2109",
        "ip_version": null,
        "cidr": null,
        "network_type": null
    }
}

从共享网络中删除子网:

DELETE /v2/​{tenant_id}​/share-networks/{share_network_id}/subnets/{share-network-subnet-id}

如果共享网络 ID 或共享网络子网 ID 无效,API 将以 404 NotFound 响应。如果在共享网络子网上有共享服务器,则无法将其删除;API 将以 409 Conflict 响应。

响应

202 Accepted

共享网络摘要列表:

GET /v2/​{tenant_id}​/share-networks

响应

Code: 200 OK

{
    "share_networks": [
        {
            "id": "77eb3421-4549-4789-ac39-0d5185d68c29",
            "name": "my_network"
        },
        {
            "id": "00cc3770-2558-4370-a088-de03b055dcff",
            "name": "my_network_2"
        }
    ]
}

此 API 的先前版本没有更改

共享网络的详细列表:

GET /v2/​{tenant_id}​/share-networks/detail

响应

Code: 200 OK

{
    "share_networks": [
        {
            "name": "my_network",
            "id": "77eb3421-4549-4789-ac39-0d5185d68c29",
            "project_id": "e10a683c20da41248cfd5e1ab3d88c62",
            "description": "This is my share network",
            "updated_at": null,
            "share_network_subnets": [
                {
                    "created_at": "2016-06-01T21:12:14.843836",
                    "id": "aa7a1269-703b-4832-a3df-17ed954c276c",
                    "availability_zone": "paris",
                    "segmentation_id": null,
                    "neutron_subnet_id": "12c1490a-e82c-4f5e-bcb1-fb267a58cf10",
                    "updated_at": null,
                    "neutron_net_id": "998b42ee-2cee-4d36-8b95-67b5ca1f2109",
                    "ip_version": null,
                    "cidr": null,
                    "network_type": null
                },
                {
                    "created_at": "2016-06-01T21:12:14.843836",
                    "id": "9c5dbe11-cdf6-48a4-b6ca-9582ef5af193",
                    "availability_zone": "london",
                    "segmentation_id": null,
                    "neutron_subnet_id": "53482b62-2c84-4a53-b6ab-30d9d9800d06",
                    "updated_at": null,
                    "neutron_net_id": "998b42ee-2cee-4d36-8b95-67b5ca1f2109",
                    "ip_version": null,
                    "cidr": null,
                    "network_type": null
                }
            ]
        },
        {
            "name": "my_network_2",
            "id": "00cc3770-2558-4370-a088-de03b055dcff",
            "project_id": "e10a683c20da41248cfd5e1ab3d88c62",
            "description": "This is also my share network",
            "updated_at": null,
            "share_network_subnets": [
                {
                    "created_at": "2016-06-01T21:12:14.843836",
                    "id": "1feffbd9-9747-413d-b162-83b97981f0ba",
                    "availability_zone": "paris",
                    "segmentation_id": null,
                    "neutron_subnet_id": "647cf190-e439-4159-98f9-17cb266d6d00",
                    "updated_at": null,
                    "neutron_net_id": "3b49335d-273e-4829-9b08-b7b1df157e69",
                    "ip_version": null,
                    "cidr": null,
                    "network_type": null
                }
            ]
        }
    ]
}

显示单个共享网络的详细信息:

GET /v2/​{tenant_id}​/share-networks/{share_network_id}/detail

如果共享网络 ID 无效,API 将以 404 NotFound 响应。

响应

Code: 200 OK

{
    "name": "my_network",
    "id": "77eb3421-4549-4789-ac39-0d5185d68c29",
    "project_id": "e10a683c20da41248cfd5e1ab3d88c62",
    "description": "This is my share network",
    "updated_at": null,
    "share_network_subnets": [
        {
            "created_at": "2016-06-01T21:12:14.843836",
            "id": "aa7a1269-703b-4832-a3df-17ed954c276c",
            "availability_zone": "paris",
            "segmentation_id": null,
            "neutron_subnet_id": "12c1490a-e82c-4f5e-bcb1-fb267a58cf10",
            "updated_at": null,
            "neutron_net_id": "998b42ee-2cee-4d36-8b95-67b5ca1f2109",
            "ip_version": null,
            "cidr": null,
            "network_type": null
        },
        {
            "created_at": "2016-06-01T21:12:14.843836",
            "id": "9c5dbe11-cdf6-48a4-b6ca-9582ef5af193",
            "availability_zone": "london",
            "segmentation_id": null,
            "neutron_subnet_id": "53482b62-2c84-4a53-b6ab-30d9d9800d06",
            "updated_at": null,
            "neutron_net_id": "998b42ee-2cee-4d36-8b95-67b5ca1f2109",
            "ip_version": null,
            "cidr": null,
            "network_type": null
        }
    ]
}

显示子网的详细信息:

GET /v2/​{tenant_id}​/share-networks/{share_network_id}/subnets/{share_network_subnet_id}

如果共享网络 ID 或共享网络子网 ID 无效,API 将以 404 NotFound 响应。

响应

Code: 200 OK

{
    "share_network_subnet": {
        "created_at": "2016-06-01T21:12:14.843836",
        "id": "aa7a1269-703b-4832-a3df-17ed954c276c",
        "share_network_id": "77eb3421-4549-4789-ac39-0d5185d68c29",
        "availability_zone": "paris",
        "segmentation_id": null,
        "neutron_subnet_id": "12c1490a-e82c-4f5e-bcb1-fb267a58cf10",
        "updated_at": null,
        "neutron_net_id": "998b42ee-2cee-4d36-8b95-67b5ca1f2109",
        "ip_version": null,
        "cidr": null,
        "network_type": null
    }
}

删除共享网络:

DELETE /v2/​{tenant_id}​/share-networks/​{share_network_id}​

具有多个子网的共享网络无法原子删除。API 将以 409 Conflict 响应。用户必须迭代删除子网,直到共享网络中只剩一个或更少的子网,然后才能尝试删除共享网络。

响应

Code: 202 Accepted

安全影响

安全服务仍然与共享网络关联,但共享网络的覆盖范围正在增加,以跨越多个子网。因此,对于外部用户而言,唯一可见的更改是共享网络现在可能比以前“更大”。因此,在向现有共享网络添加子网时必须格外小心。用户可以将与部署中的可用区一样多的子网分配给特定的共享网络。他们还可以定义一个可以跨越所有可用区的子网。

通知影响

我们将异步验证共享创建期间的网络信息,如果与配置的网络插件中指定的信息不匹配,我们将引发用户错误消息。

其他最终用户影响

  • 最终用户必须在创建共享网络时指定可用区参数,除非他们希望创建跨越所有可用区的子网的共享网络。

  • 最终用户必须迭代地向现有网络添加新的子网,以跨可用区扩展共享网络。

性能影响

验证用户是否提供了正确的存储可用区将在 API 层执行。但是,可用区与配置的网络验证将在网络插件层完成,就像今天完成的现有网络检查一样。这预计不会造成性能影响,但会将我们现有的共享网络验证与 API 分离,从而允许进行进一步的增强,而不是在 API 层阻止更改。

换句话说,为了最大限度地减少性能影响,设计中不建议在 API 上进行进一步的网络信息验证。

其他部署者影响

  • 预计不会添加新的配置选项。但是,neutron 在用户使用 availability_zone_hints 创建网络时执行 AZ 验证。部署者必须确保 neutron 服务正在所需的可用区中运行,以允许网络创建成功。

  • 数据库升级到此版本的数据库更改后,所有现有的共享网络都将将其子网(如果存在)指定为 default

开发人员影响

驱动程序影响

无。驱动程序必须忽略所有这些更改,因为它们将在 manila API 服务和共享管理器服务中处理。

实现

负责人

主要负责人
lseki

工作项

  • 在数据库中引入共享网络子网并将其映射到可用区。

  • 共享网络 API 的更改 - 创建、列表、修改

  • CLI 实现

  • manila-ui 支持

依赖项

共享复制的演进以覆盖 DHSS = True 用例取决于此更改。一旦完成这项工作,支持 DHSS = True 模式的共享驱动程序就可以支持共享复制。作为先决条件更正,Share 副本 API 不应再支持指定 share_network_id。[5]

测试

将添加/维护符合社区标准的单元测试覆盖率。Tempest 测试将被修改/添加以覆盖新的共享网络 API 更改。AZ 感知将被编码到测试中,并带有像共享复制 tempest 测试这样的回退。

在 gate 上设置多个 AZ 不在此工作范围内。但是,可以使用多 AZ 配置手动运行这些测试。

文档影响

以下 OpenStack 文档将更新以反映此更改

  • OpenStack 用户指南:将记录共享网络的创建和修改中的更改。

  • OpenStack 管理员指南:将记录列出/删除共享网络实例的 API。

  • OpenStack API 参考:将记录所有 API 更改

  • Manila 开发人员参考:将记录此功能的低级别实现考虑因素和设计。

  • OpenStack 安全指南:将让读者了解将 AZ 感知添加到共享网络的总体情况。

参考资料

[1]: https://docs.openstack.org/admin-guide/shared_file_systems_share_networks.html

[2]: https://wiki.openstack.org/wiki/Manila/design/manila-mitaka-data-replication

[3]: https://specs.openstack.org/openstack/neutron-specs/specs/liberty/availability-zone.html

[4]: https://docs.openstack.org/mitaka/networking-guide/adv-config-availability-zone.html

[5]: https://bugs.launchpad.net/manila/+bug/1588144