与多个子网共享服务器

https://blueprints.launchpad.net/manila/+spec/multiple-subnet-share-servers

本规范提出对 Manila 的更改,旨在解决共享服务器需要在多个子网上进行网络分配的需求。为此,规范建议允许共享网络在同一可用区 (AZ) 内跨越多个子网。

问题描述

Manila 驱动程序可以以两种模式之一运行,driver_handles_share_servers = True,要求共享服务器在 Neutron 子网上配置,该子网可以是 IPv4 或 IPv6。在该子网上配置的共享服务器,其共享资源可供连接到相同子网的主机访问。当向 Manila 添加 IPv6 支持时,它允许了新的用例,并显现出一些局限性,即共享服务器无法同时提供具有 IPv4 和 IPv6 导出位置的共享。

在基础设施从 IPv4 向 IPv6 过渡的世界中,同时具备两种地址族的连接性已不再罕见。文件服务的根本概念是在多个主机之间共享数据,因此,同时从 IPv4 和 IPv6 地址族访问共享也是合理的,因为存储后端能够实现这一点。

Manila 驱动程序通过接收后端应创建的网络分配列表来实现对共享服务器的支持。驱动程序提供的网络分配数量各不相同,因为每个驱动程序在从 Neutron 获取分配定义之前都会报告其所需数量。

在实现 [1] 之前,共享网络实体保存了来自 Neutron 网络和子网的信息,Manila 在尝试动态分配地址时会参考其数据。自实现 [1] 以来,共享网络实体已被修改为不保存 Neutron 信息,而是被修改为跨越不同可用区中的多个共享网络子网。此后,共享服务器被创建并与单个共享网络子网关联,该子网包含 Neutron 网络和子网信息。

共享网络子网由云用户创建,其 Neutron 网络和子网关联也在创建时定义。无需驱动程序实现来处理多个子网。结果是,如果提供的分配数量超过预期数量,当前所有已实现的驱动程序都将无法处理额外的分配,而这些分配对于满足同时提供 IPv4 和 IPv6 版本共享的要求是必需的。

自实现 [2] 以来,Manila 即使在正在被共享服务器使用的共享网络上,也可以更改共享网络的安全性服务。但是,子网关联仍然无法更改,这可能导致用户最终创建子网仅用于提供共享,而资源驻留在更灵活的网络中,并通过性能降低的流量路由在它们之间进行路由。

用例

通过允许共享服务器在多个子网上配置,可以解决以下用例

  • 能够同时提供具有 IPv4 和 IPv6 导出位置的共享。

  • 能够在多个子网上提供共享。在过载环境中,Neutron 子网可能耗尽 IP(分配给客户端),需要新的子网来访问客户端,而不是

    • 在它们之间路由数据。

    • 为每个子网创建一个共享网络,这将导致生成新的共享服务器,每个服务器都有自己的共享。

  • 通过添加共享网络 Neutron 子网关联来更新现有共享服务器的网络分配。

提议的变更

将引入新的布尔驱动程序功能

  • ``share_server_multiple_subnet_support``:确定驱动程序是否支持在多个子网上配置共享服务器。如果是,则此功能报告为 True。否则,该值为 False

  • ``network_allocation_update_support``:确定驱动程序是否实现了新的接口 update_share_server_network_allocationscheck_update_share_server_network_allocations。如果是,则此功能报告为 True。否则,该值为 False

新的功能 share_server_multiple_subnet_support 的目的是让调度程序在创建已经具有每个 AZ 多个子网的共享网络的共享时,确定合适的后端。

新的驱动程序接口 update_share_server_network_allocations 使驱动程序能够在从共享网络添加 Neutron 子网时更新共享服务器网络分配。此外,该接口必须返回新的共享的导出位置,因为它们将随着共享服务器子网的更改而更改。

在调用更新驱动程序接口之前,Manila 将调用 check_update_share_server_network_allocations 来检查更新是否在所有具有共享网络中服务器的驱动程序中可用。如果其中一个驱动程序拒绝更新,则整个更新操作将失败。在这种情况下,不会有任何资源进入错误状态,只会记录拒绝操作的原因。

将在共享服务器模型中添加一个新的布尔列 network_allocation_update_support,以区分可以支持更新功能的现有共享服务器。它将继承自其驱动程序功能。

受此提案影响的工作流程是

  • 当将共享网络子网添加到现有共享网络时,导致每个 AZ 多个子网(或多个 default 子网),每个 AZ 一个子网的限制仅在存在任何关联的共享服务器且其 network_allocation_update_support 字段设置为 False 时才存在。在这种情况下,API 调用将以 409 Conflict 失败。否则,API 调用将成功,并且将调用共享管理器来更新共享服务器网络分配。

  • 在具有每个 AZ 多个子网的共享网络中创建共享时,调度程序将尝试找到一个有效的后端,该后端具有将 share_server_multiple_subnet_support 设置为 True。如果不是这种情况,则请求将导致 No valid host 调度错误。

驱动程序可以独立支持这些功能。如果驱动程序报告 share_server_multiple_subnet_support=Truenetwork_allocation_update_support=False,则在配置第一个共享服务器后,共享网络将变为不可变。因此,如果云管理员想要这两个功能,他们必须通过共享类型附加规范显式请求每个功能。

不实现任一接口的现有共享服务器将继续工作,无需更改。API 将永远不允许在添加 Neutron 子网导致每个 AZ 多个子网的情况下,更改其关联的共享网络。

如果驱动程序决定在 network_allocation_update_support 字段已经设置为 TrueFalse 之后,在后续版本中实现 update_share_server_network_allocations,则需要使用 manila-manage 工具重置共享服务器的 network_allocation_update_support 字段。

共享网络更新可以是一对多操作,这可能会为不同共享服务中的不同后端触发多个共享服务器更新。为了添加与共享网络关联的子网,共享 API 需要验证所有受影响的资源是否正常,然后才能继续请求。之后,共享网络和共享服务器状态将更新为 network_change

如果使用多个子网配置共享服务器在为给定子网之一配置服务器失败,则整个设置将失败。同样,如果 update_share_server_network_allocations 失败,共享服务器状态将被设置为 error,以及所有受影响的共享访问规则。网络状态不会受到后端驱动程序引发的错误的影响,共享网络将处于活动状态,其资源将被更新(添加子网)。

Manila Manage

通过向共享服务器模型添加新功能,重要的是要考虑现有共享服务器需要在未来根据驱动程序的支持更新此字段,以启用此功能。这将通过为 manila-manage 工具提供一个新的管理命令来实现,该命令将允许管理员相应地更新其共享服务器。

备选方案

由于没有办法在不重用相同的驱动程序接口的情况下引入更改来改进 Manila,唯一的替代方案是不实现提议的更改并继续使用限制。

数据模型影响

将在 manila.db.sqlalchemy.models.ShareServer 中添加一个新的 network_allocation_update_support 功能列,指示驱动程序和驻留此共享服务器的后端是否支持更新每个 AZ 多个子网的操作。在数据库迁移升级中,新列将以默认值 False 添加,这意味着即使驱动程序支持,已部署的所有共享服务器也无法更新每个 AZ 的子网配置。在数据库迁移降级中,该列将被删除。

鉴于 ShareServer 可以有多个 ShareNetworkSubnet,并且 ShareNetworkSubnet 也可以有多个 ShareServer,将添加一个新的表 ShareServerShareNetworkSubnetMappingShareServer 中的 share_network_subnet_id 字段将被删除。数据库迁移升级将基于当前的 ShareServer 表构建此新表并删除该字段。不建议降级,因为映射可能每个 ShareServer 有多个条目。

将向 manila.db.sqlalchemy.models.ShareNetwork 添加一个新的 network_allocation_update_support 属性,以指示共享网络是否支持更新每个 AZ 多个子网的操作。此属性将从所有当前关联的共享服务器继承其值。如果所有关联的共享服务器都支持 network_allocation_update_support,则共享网络属性将设置为 True,否则将设置为 False

由于当前 Manila 数据模型设计具有实体 manila.db.sqlalchemy.models.ShareNetworkSubnet 包含外键 availability_zone_id,而不是反向关系,因此数据模型中没有阻止在同一 AZ 中拥有多个子网的因素。

REST API 影响

没有引入新的 API,但现有的 API 将进行微版本控制。具体来说

  • 显示共享服务器:在微版本更新之后,共享服务器视图将包含字段 network_allocation_update_support。此外,share_network_subnet_id 将是一个 ID 列表。

  • 将 Neutron 子网添加到共享网络:在微版本更新之后,此 API 不再总是会在操作结果超过每个 AZ 一个子网时返回错误。相反,它将检查现有的关联共享服务器是否将 network_allocation_update_support 字段设置为 True。如果不是这种情况,它将返回 409 Conflict

安全影响

无。

通知影响

没有引入新的通知。现有的通知已经适应了提议的更改。

其他最终用户影响

除了添加或删除共享网络时限制更改之外,没有其他限制。

性能影响

无。

其他部署者影响

  • 预计不会添加新的配置。

  • 后端功能将帮助部署者识别支持多个子网共享服务器支持的池。

  • 所有现有的共享服务器都将将其 network_allocation_update_support 设置为 False,即使驱动程序支持该功能。新的共享服务器将根据驱动程序报告的后端能力设置相应的能力。管理员需要使用 manila manage 命令手动更新共享服务器的能力。

开发人员影响

无。

驱动程序影响

希望支持更新功能的驱动程序必须实现新的检查和更新驱动程序接口

def check_update_share_server_network_allocations(
    self, network_info, server_details, shares, snapshots):
"""Updates a share server's network allocations.

:param network_info: Dictionary containing network parameters for share
    server update, with the map of network allocations and security
    services among them.
:param server_details: Back end details for share server being updated.
:param shares: All shares in the share server.
:param snapshots: All snapshots in the share server.
:return Boolean indicating whether the update is possible or not. It is
    the driver responsibility to log the reason why not accepting the
    update.

def update_share_server_network_allocations(
    self, network_info, server_details, shares, snapshots):
"""Updates a share server's network allocations.

:param network_info: Dictionary containing network parameters for share
    server update, with the map of network allocations and security
    services among them.
:param server_details: Back end details for share server being updated.
:param shares: All shares in the share server.
:param snapshots: All snapshots in the share server.
:return If the update changes the shares export locations or snapshots
        export locations, this method should return a dictionary containing
        a list of share instances and snapshot instances indexed by their
        id's, where each instance should provide a dict with the relevant
        information that need to be updated. Also, the returned dict
        contains the updated back end details to be saved in the database.

        Example::

            {
                'share_updates':
                {
                    '4363eb92-23ca-4888-9e24-502387816e2a':
                    {
                    'export_locations':
                    [
                        {
                        'path': '1.2.3.4:/foo',
                        'metadata': {},
                        'is_admin_only': False
                        },
                        {
                        'path': '5.6.7.8:/foo',
                        'metadata': {},
                        'is_admin_only': True
                        },
                    ],
                    'pool_name': 'poolA',
                    },
                },
                'snapshot_updates':
                {
                    'bc4e3b28-0832-4168-b688-67fdc3e9d408':
                    {
                    'provider_location': '/snapshots/foo/bar_1',
                    'export_locations':
                    [
                        {
                        'path': '1.2.3.4:/snapshots/foo/bar_1',
                        'is_admin_only': False,
                        },
                        {
                        'path': '5.6.7.8:/snapshots/foo/bar_1',
                        'is_admin_only': True,
                        },
                    ],
                    },
                    '2e62b7ea-4e30-445f-bc05-fd523ca62941':
                    {
                    'provider_location': '/snapshots/foo/bar_2',
                    'export_locations':
                    [
                        {
                        'path': '1.2.3.4:/snapshots/foo/bar_2',
                        'is_admin_only': False,
                        },
                        {
                        'path': '5.6.7.8:/snapshots/foo/bar_2',
                        'is_admin_only': True,
                        },
                    ],
                    },
                }
                'backend_details':
                {
                    'new_share_server_info_key':
                        'new_share_server_info_value',
                },
            }
    Example::

        {'server_name': 'my_share_server'}

    """
    raise NotImplementedError()

驱动程序应期望接收多个网络分配。总数将是与同一可用区 (AZ) 关联的子网数量乘以驱动程序报告的分配数量。

现有的驱动程序接口 _setup_server 将被修改。网络分配字典条目 network_info 现在将是一个字典列表,代表每个子网中的分配。为了保持兼容性,驱动程序将被更改为消耗列表的第一个元素,并且将在 OpenStack 邮件列表中发送一封通知此接口更改的邮件。

实现

负责人

主要负责人
felipe_rodrigues

工作项

  • 实现核心更改,必须包括

    • 添加共享网络和共享服务器模型属性;

    • 添加数据库迁移。

    • 根据新的共享服务器模型字段更新添加共享网络 Neutron 子网 API 验证。

    • 添加新的驱动程序接口。

    • 添加新的能力。

    • 添加调度器能力检查。

  • 第一方驱动程序中的实现

  • 在 manila-tempest-plugin 中添加新的功能测试

  • 为共享服务器能力更新添加新的 manila-manage 命令

  • 更新 Manila 文档

此规范可能需要多个发布版本才能交付所有用例。因此,它可以分为两个主要交付成果,分别是

  1. 添加在同一共享网络 AZ 中定义多个子网的能力

  2. 添加“更新”共享网络 AZ 中子网的能力

这种交付方法将把测试和验证工作分散到各个发布版本中。

依赖项

无。

测试

将根据社区标准添加/维护单元测试覆盖率。将添加新的 tempest 测试来涵盖每个 AZ 多个子网的场景。容器或虚拟驱动程序将得到改进,以正确配置安全服务,并用于验证提议的更改。

文档影响

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

  • OpenStack 用户指南:将记录共享网络 API 的更改。

  • OpenStack 管理员指南:将记录共享服务器的更改。

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

  • Manila 开发者参考:将记录低级别实现注意事项、功能设计以及驱动程序实现指南。

参考资料

[1]: https://specs.openstack.org/openstack/manila-specs/specs/train/share-network-multiple-subnets.html

[2]: https://specs.openstack.org/openstack/manila-specs/specs/wallaby/security-service-updates-in-use-share-network.html