网络段范围管理¶
Launchpad 蓝图: https://blueprints.launchpad.net/neutron/+spec/network-segment-range-management
目前,网络段范围是在 ML2 配置文件中配置的一个条目 [1],它是为租户网络分配而静态定义的,因此必须作为主机部署和管理的一部分进行管理。当普通租户用户创建网络时,Neutron 会从配置的段范围中分配下一个空闲的段 ID(VLAN ID、VNI 等)。只有管理员才能通过提供程序扩展分配特定的段 ID。
此规范引入了一个扩展,该扩展将段范围管理暴露为通过 Neutron API 进行管理的接口。此外,它还引入了管理员控制全局或基于每个租户的段范围的能力。
问题描述¶
自助服务网络,也称为租户网络,主要使普通(非特权)项目能够在不涉及管理员的情况下管理网络。这些网络完全是虚拟的,需要虚拟路由器才能与提供程序和外部网络(如互联网)交互。在大多数情况下,自助服务网络使用 VXLAN 或 GRE 等覆盖协议,因为它们可以支持比使用 VLAN 标记(802.1q)进行分段的第二层更多的网络,后者通常需要额外配置物理网络基础设施。然而,在其他一些情况下,OpenStack Neutron 也支持使用 VLAN 等方式实现自助服务网络隔离。[2]。
当前的 Neutron 实现将条目设置为配置文件中以静态定义用于租户网络分配的网络段范围。它不支持初始化后通过其他动态方式(例如,在 API 级别)。为了使对网络段范围的任何更改生效,必须重新启动 Neutron 服务。然而,云网络基础设施部署可能很复杂且异构。这种僵化给云管理员在处理各种需求时带来了复杂性和困难。
网络段范围管理在 API 级别提供了一个额外的灵活性,它能够使用标准的 REST API 对所有类型的租户网络进行完全的网络编排,而无需直接与主机配置交互。除此之外,对于 VLAN 租户网络,网络段范围管理能够控制云/网络基础设施的管理,用于租户网络。它还促进了按租户分配(包括共享)。这使云管理员能够直接控制 VLAN 租户段映射,并最终控制租户流量的基础 L2/L3 路径,而无需向租户用户公开特定的网络段范围信息。租户网络的段分配将参考管理员分配给该租户的网络段范围。
下面演示了几个示例用例。
用例 I¶
使云管理员能够创建和分配每个租户的网络段范围。这赋予了管理员管理底层网络段范围的权限。当租户创建网络时,它将从分配给租户或共享的段范围中分配一个段 ID(如果没有可用的租户特定范围)。它有助于将该租户创建的 VM 映射到一组现有的网络,以满足隐私或专用的业务连接需求。下面显示了一个示例说明
+------------------+
| Physical Network |
+------------+---------+ Infrastructures +-------------------+
| | +---------+--------+ |
| | | |
| | | |
+----+----+ +----+----+ +----+----+ +----+----+
| Tenant 0| | Tenant 1|.........| Tenant k|.................| Tenant n|
+----+----+ +----+----+ +----+----+ +----+----+
| | | |
| | | |
+ range-0 + range-1 + range-k1 + range-n
range-k2
一个云连接并映射到大量的现有 l2 物理网络基础设施。
n+1 个租户:租户 0,…租户 k…,租户 n 在此云中可用。
每个租户都需要由云管理员分别分配一个(或多个)网络段范围(范围-0,…范围-k1…,…范围-k2…,范围-n),以便其创建的网络可以根据不同的业务需求连接到相应的专用物理网络基础设施。
可能的流程如下
云管理员列出所有现有的网络段范围
openstack network segment range list
如果未为目标租户创建网络段范围,则云管理员可以为其创建一个
openstack network segment range create --name <range_name> --shared <shared> --project <project_id> --network_type <network_type> --physical_network <physical_network_name> --minimum <range_minimum> --maximum <range_maximum>
现在,普通租户用户可以以常规方式创建网络 [3]。创建的网络将自动从分配给租户的段范围(步骤 3)或共享的段范围(如果没有可用的租户特定范围)中分配一个段 ID。
这有助于确定多个租户存在时正确的 VLAN 映射。它还提供了为每个租户动态创建网络段范围的可能性,即使它未预先部署在主机配置中。
用例 II¶
在某些 VLAN 租户网络场景中,现有的物理网络基础设施的段配置发生变化的情况并不少见。因此,云管理员必须同时更新 VLAN 分配范围,以保持与连接或映射的一致性。因此,正如本规范所建议的那样,提供动态管理自助服务网络的段范围的能力对于 VLAN 租户网络至关重要,并且对于其他覆盖租户网络来说也是一个优势。
可能的流程如下
云管理员列出所有现有的网络段范围并识别需要更新的范围
openstack network segment range list
云管理员根据实际需求更新网络段范围
openstack network segment range set --name <range_name> --minimum <range_minimum> --maximum <range_maximum> <network_segment_range-id>
现在,普通租户用户可以以常规方式创建网络 [3]。创建的网络将自动从更新的网络段范围中分配空闲的段 ID。
提议的变更¶
为了解决上述用例,此规范引入了一个名为 network_segment_ranges 的新资源及其实现。
目前,默认情况下,所有预配置的段信息(例如,在 [1] 中定义的 network_vlan_ranges、vni_ranges 等)在 Neutron 服务启动后由 ML2 类型驱动程序加载到“ml2_xxx_allocations”DB 表中。对于所有自助服务网络的段 ID 同步、分配和释放,它们都将基于此信息。
所有这些信息都将被维护。此规范中引入的网络段范围将增强从配置文件加载的初始分配,成为共享范围的一部分。它提出了一种 API 方法,具有管理权限的用户可以创建和管理 ML2 支持的所有网络类型的各种网络段范围。
数据模型影响¶
作为网络网络管理功能的一部分,添加了以下新表
CREATE TABLE network_segment_ranges (
id CHAR(36) NOT NULL PRI KEY,
name VARCHAR(255),
default BOOL NOT NULL,
shared BOOL NOT NULL,
project_id VARCHAR(255) NOT NULL,
network_type ENUM('vlan', 'vxlan', 'gre', 'geneve') NOT NULL,
physical_network VARCHAR(64),
minimum INT,
maximum INT
);
对于不同的网络类型,验证策略和响应应具有以下变体
VLAN:minimum = 1,maximum = 4094。
VXLAN:minimum = 1,maximum = 2 ** 24 - 1。
GRE:minimum = 1,maximum = 2 ** 32 - 1。
Geneve:minimum = 1,maximum = 2 ** 24 - 1。
注意:其他验证规则,如 minimum <= maximum 始终适用,应予以关注。上述大部分已在 neutron_lib.plugins.utils 中得到支持。
应提供添加网络段范围管理扩展的混合类。DB 操作逻辑应由 ML2 类型管理器和类型驱动程序处理。对于现有 ML2 配置选项 [1](例如 ml2_type_vlan、ml2_type_vxlan 等)中存在的值,它们将被加载为 shared 和 default 段范围到 network_segment_ranges DB 中,以便在存在此扩展时提供向后兼容性,以便进行初始部署。
资源扩展¶
正在引入以下新资源,其属性映射如下
NETWORK_TYPE_LIST = [TYPE_VLAN, TYPE_VXLAN, TYPE_GRE, TYPE_GENEVE]
RESOURCE_ATTRIBUTE_MAPS = {
'network_segment_ranges': {
'id': {'allow_post': False, 'allow_put': False,
'validate': {'type:uuid': None},
'is_visible': True,
'is_filter': True,
'is_sort_key': True,
'primary_key': True},
'name': {'allow_post': True, 'allow_put': True,
'validate': {
'type:string': db_const.NAME_FIELD_SIZE},
'default': '', 'is_visible': True, 'is_filter': True,
'is_sort_key': True},
'default': {'allow_post': False, 'allow_put': False,
'convert_to': converters.convert_to_boolean,
'default': False,
'is_visible': True},
'shared': {'allow_post': True, 'allow_put': False,
'convert_to': converters.convert_to_boolean,
'is_visible': True, 'default': True},
'project_id': {'allow_post': True, 'allow_put': False,
'validate': {
'type:string': db_const.PROJECT_ID_FIELD_SIZE},
'required_by_policy': True,
'is_filter': True,
'is_sort_key': True,
'is_visible': True},
'network_type': {'allow_post': True, 'allow_put': False,
'validate': {'type:values': NETWORK_TYPE_LIST},
'default': constants.ATTR_NOT_SPECIFIED,
'is_filter': True,
'is_visible': True},
'physical_network': {'allow_post': True, 'allow_put': False,
'validate': {
'type:string': PHYSICAL_NETWORK_MAX_LEN},
'default': constants.ATTR_NOT_SPECIFIED,
'is_filter': True,
'is_visible': True},
'minimum': {'allow_post': True, 'allow_put': True,
'convert_to': converters.convert_to_int, 'is_visible': True},
'maximum': {'allow_post': True, 'allow_put': True,
'convert_to': converters.convert_to_int, 'is_visible': True},
'used': {'allow_post': False, 'allow_put': False,
'is_visible': True},
'available': {'allow_post': False, 'allow_put': False,
'convert_to': attr.convert_none_to_empty_list,
'is_visible': True},
},
}
REST API 影响¶
想法是添加一个带有以下定义属性的新资源扩展。资源扩展 network_segment_ranges
属性名称 |
类型 |
必需 |
CRUD |
默认值 |
描述 |
|---|---|---|---|---|---|
id |
字符串 |
N/A |
R |
生成 |
网络段范围的标识符 |
name |
字符串 |
否 |
CRU |
‘’ |
网络段范围的名称 |
default |
Bool |
否 |
R |
False |
从主机 ML2 配置文件 [1] 加载的默认网络段范围 |
共享 |
Bool |
是 |
CR |
True |
与其他项目共享 |
project_id |
字符串 |
否 |
CR |
当前 project_id |
范围所有者。当 shared 为 True 时为可选。 |
network_type |
Enum |
是 |
CR |
无 |
VLAN、VxLAN、GRE Geneve |
physical_network |
字符串 |
否 |
CR |
无 |
可选。仅适用于 VLAN。 |
minimum |
INT |
是 |
CRU |
无 |
段范围的下限整数 |
maximum |
INT |
是 |
CRU |
无 |
段范围的上限整数 |
used |
Dict |
否 |
R |
{} |
映射哪个租户使用范围内的哪个分段 ID |
available |
列表 |
否 |
R |
[] |
此段范围中可用的分段 ID 列表 |
要指定具有单个项目的范围,min 等于 max 即可。对于给定网络类型的不连续段范围,它们表示为几个,每个范围都有一个 min 和一个 max。
将根据先前引入的新资源提供以下网络段范围管理 Rest API
列出所有网络段范围。GET /v2.0/network_segment_ranges
GET /v2.0/network_segment_ranges
Accept: application/json
{
"network_segment_ranges": [
{
"id": "d23abc8d-2991-4a55-ba98-2aaea84cc72f",
"name": "network_segment_range_physnet1",
"default": False,
"shared": False,
"project_id": "45977fa2dbd7482098dd68d0d8970117",
"network_type": "vlan",
"physical_network": "physnet1",
"minimum": 100,
"maximum": 105,
"used": {"100": "07ac1127ee9647d48ce2626867104a13",
"101": "d4fa62aa47d340d98d076801aa7e6ec4"},
"available": [102, 103, 104, 105],
}
]
}
列出网络段范围信息。GET /v2.0/network_segment_ranges/<network_segment_range-id>
GET /v2.0/network_segment_ranges/d23abc8d-2991-4a55-ba98-2aaea84cc72f
Accept: application/json
{
"network_segment_range": {
"id": "d23abc8d-2991-4a55-ba98-2aaea84cc72f",
"name": "network_segment_range_physnet1",
"default": False,
"shared": False,
"project_id": "45977fa2dbd7482098dd68d0d8970117",
"network_type": "vlan",
"physical_network": "physnet1",
"minimum": 100,
"maximum": 105,
"used": {"100": "07ac1127ee9647d48ce2626867104a13",
"101": "d4fa62aa47d340d98d076801aa7e6ec4"},
"available": [102, 103, 104, 105],
}
}
为给定的租户创建一个网络段范围。POST /v2.0/network_segment_ranges
POST /v2.0/network_segment_ranges
Accept: application/json
{
"network_segment_range": {
"name": "network_segment_range_physnet1",
"shared": False,
"project_id": "45977fa2dbd7482098dd68d0d8970117",
"network_type": "vlan",
"physical_network": "physnet1",
"minimum": 100,
"maximum": 200,
}
}
按 ID 删除网络段范围。DELETE /v2.0/network_segment_ranges/<network_segment_range-id>
正常响应代码:204
错误响应代码:Unauthorized (401)、Not Found (404)、Conflict (409)。当在网络段范围内部分配了资源时,将返回 Conflict 错误响应。
此操作不需要请求体。
此操作不返回响应体。
DELETE /v2.0/network_segment_ranges/d23abc8d-2991-4a55-ba98-2aaea84cc72f
Accept: application/json
使用给定的数据更新网络段范围。PUT /v2.0/network_segment_ranges/<network_segment_range-id>
PUT /v2.0/network_segment_ranges/d23abc8d-2991-4a55-ba98-2aaea84cc72f
Accept: application/json
{
"network_segment_range": {
"minimum": 200,
"maximum": 300,
}
}
命令行客户端影响¶
Openstack Client 将添加网络段范围管理相关的 CLI。它们应该是仅限管理员的 CLI 命令。例如
openstack network segment range list
[--used | --not-used]
[--available | --not-available]
openstack network segment range show <network_segment_range-id>
openstack network segment range create
--shared <shared>
--network_type <network_type>
--minimum <range_minimum>
--maximum <range_maximum>
[--name <range_name>]
[--project_id <project_id>]
[--physical_network <physical_network>]
Notes: Arguments --name, --project_id are optional, the project_id can be
taken from the context if not given; --physical_network is optional
and only applicable for VLAN. All the other parameters should be
required.
openstack network segment range set
[--name <range_name>]
[--minimum <range_minimum>]
[--maximum <range_maximum>]
<network_segment_range-id>
openstack network segment range delete <network_segment_range-id>
其他影响¶
ML2 插件、插件管理器和类型驱动程序需要进行改进并添加几个新的方法,以支持此功能。
当加载此扩展时,Neutron 服务器将使用 ML2 配置中定义的范围作为 default 和 shared 范围,将建议的 network_segment_ranges DB 表填充到数据库中。这些 default 范围是只读的,管理员可以基于此信息进行每个租户的段范围分配。当 Neutron 服务器启动/重新启动时,default 段范围将被重新加载并对所有服务器可见。来自 REST API 的交互将始终基于数据库中定义的段范围进行操作。
需要对许多情况进行验证工作,包括但不限于
在执行之前述任何网络段范围操作之前,应始终检查管理员权限。
删除网络段范围时,如果其中一个网络段正在使用,则应拒绝该操作。
如果它不会影响范围内的已分配段(例如,扩大该范围),则允许更新网络段范围。否则,我们应该使更新失败。
我们通过“ml2_xxx_allocations”DB 表保持一致性,并依赖它们进行最终验证和底层的段分配。这意味着可以在将代理实际映射到特定的物理网络映射之前配置网络段范围。
理论上,可以为单个租户创建多个网络段范围(而一个网络段范围不能由多个租户拥有)。如果租户配置了多个段范围,它将从其拥有的所有网络段范围中选择下一个空闲的段 ID(VLAN ID、VNI 等)。
向后兼容性来自于将段范围的默认行为指定为租户的 shared 资源。如果向租户公开了 shared 和 specified 段范围资源,则 specified 应该覆盖 shared。
该扩展将是可选的([4] 中的一个选项,默认情况下禁用功能),在这种情况下,现有的 ML2 配置选项将适用。
其他最终用户影响¶
具有管理员权限的用户将能够动态管理支持分段的网络段范围,所有租户和租户网络。如果未为给定的租户创建动态网络段范围,或者由于向后兼容性考虑而禁用该功能,则对最终用户没有影响。
其他部署者影响¶
部署者应该有一个可用的选项来启用或禁用此功能,以便他们可以继续使用配置文件。他们还需要强烈警告更新其操作文档,以确保使用正确的方式管理新的网络段信息。如果禁用该功能,部署级别将不受影响。
性能影响¶
必须进行性能测试,以查看启用此功能的开销,当然,如果禁用该功能,则不应注意到任何性能影响。
实现¶
负责人¶
Kailun Qin <kailun.qin@intel.com>
工作项¶
调整数据库模型并添加新表。
扩展当前 API。
修改类型驱动程序和所有相关引用。
添加相关的测试。
添加 CLI openstackclient。
文档。
依赖项¶
无
测试¶
需要单元测试、功能测试、API 测试和场景测试。
文档影响¶
需要更新 Neutron API 参考文档。