更改 VLAN 提供商网络的段 ID

Launchpad bug: https://bugs.launchpad.net/neutron/+bug/1806052

本文档提出了一种更改 VLAN 类型网络的分割 ID 的方法,即网络的外部 VLAN ID。描述的实现仅限于 OVS 后端和单段提供商网络。

问题描述

目前,Neutron 不允许更改提供商网络的分割 ID 参数,无论网络状态如何(活动或非活动),或者网络上是否存在端口(或不存在)。为了更改分割 ID,管理员需要先取消绑定任何已绑定的端口,然后删除网络,创建一个具有所需分割 ID 的新网络,最后将端口重新绑定到网络。

提议的变更

提出的解决方案是能够使用单个命令(“openstack network set”)以原子方式更改 VLAN 类型网络的分割 ID。

为了实现这一点,需要进行以下几项更改

  • CLI,允许更新现有网络中的分割 ID。

  • Neutron 服务器,允许将这些更改写入数据库。

  • 网络后端。本文档仅涵盖 OVS,实现将仅限于 OVS。

OpenStack Client

目前,OpenStack Client 允许更新现有网络的分割 ID。无需进行任何更改。

Neutron 服务器

目前,当将网络更新消息发送到 Neutron 服务器时,如果此消息中存在任何提供商属性,例如“分割 ID”,则该命令将被拒绝。新的实现将允许更新分割 ID

  • 如果分割 ID 是唯一要更新的提供商参数。不允许其他提供商参数(网络类型、物理网络)。

  • 如果网络只有一个段。在多提供商网络中,服务器不知道应该更新哪个段。

  • 如果提供商段类型为“vlan”。不允许其他类型。

  • 如果绑定到此网络的所有端口都属于兼容的网络驱动程序。兼容的网络驱动程序是已实现此更改的驱动程序。本文档描述了 OVS 代理的实现。例如,对于 OVS,具有 VIF 类型“vhostuser”和“ovs”的端口被接受,“unbound”或“binding_failed”也被允许,因为它们尚未绑定到任何网络驱动程序。

如果满足以上所有条件,Neutron 服务器将执行以下操作(按顺序)

  • 验证新的段,以了解分割 ID 是否落在最小和最大 VLAN 标签范围内。

  • 预留一个新的提供商段。这将确保分割 ID 未在此网络中使用。

  • 在数据库中创建一个新的提供商段。

  • 释放旧的提供商段。

  • 从数据库中删除旧的提供商段。

所有这些操作将在写入上下文中执行,以提供并发性并在发生故障时启用回滚。如果任何这些数据库操作失败,包括后续操作,则上下文将阻止删除旧段,并且不会创建新段。

机制驱动程序

代理机制驱动程序接口将扩展一个新函数。此函数将返回一个提供商网络属性列表,这些属性可以在绑定到此网络后端的端口的网络中进行修改。

默认情况下,此函数将返回一个空列表。

Neutron OVS 代理

在 OVS 代理中,VLAN 提供商网络可以通过物理网桥访问主机外部的提供商网络。每个提供商网络都分配了一个物理网桥。一个物理网桥可以承载多个提供商网络的流量,但每个提供商网络只能通过一个物理网桥发送和接收流量。存在 N:1(网络:物理网桥)关系。

在集成网桥内部,租户网络使用虚拟网络隔离。这些虚拟网络具有自己的 VLAN ID 映射,与提供商网络的 VLAN ID 映射不同。这两个 VLAN 映射通过“LocalVlanManager”相关联,该管理器负责关联这两个映射。当来自租户的数据包退出集成网桥到相应的物理网桥时,流会更改 VLAN 标签,从租户 VLAN ID 更改为提供商分割 ID。相反的过程发生在物理网桥中

br_int:
cookie=0xb46613524bd0de42, duration=23646.484s, table=0, n_packets=0,
  n_bytes=0, priority=3,in_port="int-br-phy",dl_vlan=1074
  actions=mod_vlan_vid:1,resubmit(,60)

br_phy:
cookie=0x43209f9280b7fc88, duration=23666.003s, table=0, n_packets=10,
  n_bytes=788, priority=4,in_port="phy-br-phy",dl_vlan=1
  actions=mod_vlan_vid:1074,NORMAL

当网络分割 ID 更新时,唯一需要的更改是在两个流中更新新的分割 ID。这可以通过删除两个流,然后使用新的分割 ID 重新创建它们来完成。例如

phys_br.reclaim_local_vlan(port=phys_port, lvid=lvid)
phys_br.provision_local_vlan(
    port=phys_port, lvid=lvid,
    segmentation_id=new_segmentation_id,
    distributed=self.enable_distributed_routing)
self.int_br.reclaim_local_vlan(port=int_port,
    segmentation_id=old_segmentation_id)
self.int_br.provision_local_vlan(
    port=int_port, lvid=lvid,
    segmentation_id=new_segmentation_id)

限制

如上所述,此解决方案仅适用于

  • 单段网络。

  • VLAN 类型网络。

  • 仅绑定到此网络的 OVS(内核 OVS 或 DPDK OVS)端口。

数据模型

没有更改。

REST API

需要一个新的 ML2 RPC 调用,从代理端请求。此新的调用将提供有关更新的网络的信息。使用此信息,代理将知道网络是否已更改分割 ID(如上所述,“LocalVlanManager”单例存储此信息)。

CLI 影响

没有更改。

操作影响

更改分割 ID 包含两个操作

  • 更改 Neutron 网络的分割 ID,无需取消绑定附加的端口。完成 Neutron 中的此过程后,这些端口的流量将被标记为新的 VLAN ID,并通过提供商网络传输。

  • 更改提供商网络的分割 ID。此过程在 Neutron(和 OpenStack)之外。

由于这两个过程不能同时进行,管理员应根据站点网络基础设施决定执行顺序。在 Neutron 网络的分割 ID 和外部提供商网络的 VLAN ID 同步之前,将存在网络中断。

参考资料

无。