vlan tenant network on ovn based dvr (by quqi99)

Posted quqi99

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了vlan tenant network on ovn based dvr (by quqi99)相关的知识,希望对你有一定的参考价值。

作者:张华 发表于:2021-08-25
版权声明:可以任意转载,转载时请务必以超链接形式标明文章原始出处和作者信息及本版权声明
(http://blog.csdn.net/quqi99 )

目前ovn based dvr环境下的vlan tenant network是有问题的。见https://docs.openstack.org/neutron/latest/admin/ovn/sriov.html 中的:

Routing on VLAN tenant network will not work with SR-IOV. This is because the external ports are not being co-located with the logical router’s gateway ports, for more information take a look at bug #1875852.

何为neutron vlan tenant network

neutron中有provider network, tenant network, external network之分

  • provider network, 使用了provider-physical-network属性的就是provider network, 是由管理员创建的。
juju config neutron-api vlan-ranges="physnet1:1000:2000"
vni_ranges = 1001:2000(or the range that you configure)
flat_networks = bridge,extern
bridge_mappings = bridge:br-vlan,extern:br-ext
tenant_network_types = vxlan,vlan,flat,local
type_drivers = vxlan,vlan,flat,local

local:openstack network create NAME --provider:network_type local
flat:openstack network create NAME --provider:network_type flat --provider:physical_network PHYS_NET_NAME
vlan:openstack network create NAME --provider:network_type vlan --provider:physical_network PHYS_NET_NAME --provider:segmentation_id VID
gre:openstack network create NAME --provider:network_type gre --provider:segmentation_id TUNNEL_ID
vxlan:openstack network create NAME --provider:network_type vxlan --provider:segmentation_id TUNNEL_ID
  • tenant network, 没使用provider属性的就是tenant network, 是由用户自己创建的。Tenant network 也有 local,flat,vlan,gre 和 vxlan 等类型。但是,tenant 普通用户创建的 Flat 和 VLAN tenant network 实际上还是 Provider network,所以真正有意义的是 GRE 和 VXLAN 类型,这种网络和物理网络没有绑定关系。一般而言,SDN采用vxlan,政务云里面由于物理规划基本采用VLAN,并且都是管理员做好相关网络(provider-physical-network),由租户使用,因为VLAN和IP的关系一般都是规划好的。
openstack network create --provider-network-type gre --provider:segmentation_id 1012 gre_net
  • external network, 无论是provider network还是tenant network加了–external的就是external network
openstack network create --external --provider-network-type vlan --provider-physical-network bridge vlan_net

可以创建vlan的tenant network吗?

openstack network create --provider-network-type vlan --provider:segmentation_id 1012 vlan_tenant_net

上面的分类不是机械的,这里有一个非常好的博客(http://dani.foroselectronica.es/ovn-external-ports-604/)解释了这些分类。例:

有两个private (non-external) networks:

  • network1: 192.168.0.0/24 of type VLAN and ID 190 network2:
  • 192.168.1.0/24 of type VLAN and ID 170
    也有两个provider network:
  • external: 172.24.14.0/24 used for Floating IP traffic
  • tenant: used by network1 and network2 VLAN networks

ovn external port原理

继续上面测试环境的图,环境的三个分布式网关和测试虚机信息如下:

One Logical router that connects both private networks and the Floating IP network
router1-net1: "40:44:00:00:00:03" "192.168.0.1/24"
router1-net2: "40:44:33:00:00:05" "192.168.1.1/24"
router1-public: "40:44:00:00:00:04" "172.24.14.1/24"
4 Virtual Machines (simulated with network namespaces), 2 on each network
vm1: addresses: ["40:44:00:00:00:01 192.168.0.11"]
vm2: addresses: ["40:44:00:00:00:02 192.168.0.12"]
vm3: addresses: ["40:44:33:00:00:03 192.168.1.13"]
pext: addresses: ["40:44:44:00:00:10 192.168.1.111"]

1, 先看有FIP的情况 (南北向L3)
注意:在ovn实现上图的拓扑中,192.168.0.1(cr-lrp)与192.168.1.1(cr-lrp)(在gw1上)和external port (pext)可以分布在不同的机器上的, 这些网关之间流量走Geneve overlay tunnel.

注意:此处cr-lrp与pext port不在同一个机器上会造成无法响应vm1对192.168.0.1的arp请求,因为这里有pext所以默认情况下对于有external port的VM(vm1)的arp请求只有gw2没有drop (而现在192.168.0.1在gw1只有gw1能回答arp), 所以如果此时支持dvr (worker1上配置external_ids:ovn-chassis-mac-mappings让cr-lrp调度在worker1上,这样worker1自己负责自己上的vm的arp)。所以这种问题只有vlan作为tenant network才有问题(这时它才有cr-lrp, 如果直接这个vlan network不需要NAT的话就没这个问题了). 毕竟,南北向流量相较东西向流量最大的区别在于南北向流量有一个gateway chassis (cr-lrp)来提供NAT

More context history,chasis和gateway chassis之间(worker1和gw1)之后默认采用overlay encapsulation来redirect流量,这个实验(https://bugs.launchpad.net/neutron/+bug/1875852/comments/2)在说使用redirect=overlay + external_ids:ovn-chassis-mac-mappings works, 但是redirect=bridge + external_ids:ovn-chassis-mac-mappings不work, 可能是这个patch 有问题 - https://github.com/openstack/networking-ovn/commit/d22cc2a0dc8de7b792dc4be471277167fc2a94d3
为了让chassis(worker1)和gatewa chassis(gw1)之间的流量直接走vlan而不是tunnel, ovn为vlan gateway port添加reside-on-redirect-chassis参数让它中心化(https://github.com/openvswitch/ovs/commit/85706c34d53d4810f54bec1de662392a3c06a996),这样又整出了上面的pext(gw2)与cr-lrp(gw1)不在同一个chassis带来的arp问题(最好在worker1上面那就是ovn dvr)

所以,下图显然是non-dvr环境,如果是dvr,那cr-lrp应该在worker1而不是gw1上

上面,vm1(192.168.0.11)有FIP:

  • vm1在worker1上
  • gateway port 192.168.0.1在gw1上
  • 处理dhcp和medata的external port (pext) 在gw2上
  • 运行ping命令的机器在host1上, 它配置了一个namespace连向ovs bridge, 有一个vlan 170 (network2)的vlan device

当在host1上ping vm1’s FIP时流程如下:

  • host1属于vlan 170(192.168.1.0.24), 它ping虚机的FIP, FIP这个external port在gw2上,dst mac是network 2 router port)
  • external port导流到中心化网关上(gw1), 这是通过Geneve overlay tunnel走的。
  • 中心化网关(gw1上)发送流量到vm1的FIP上(经flat network 172.24.14.0/24, src IP is 172.24.14.1)
  • 这样request就到了worker1, local ovn-controller un-NATs the packet to the vm1

此时,vm1如何返回reply呢?

  • vm1 (192.168.0.11)发送reply到tap inerface, 然后发到它的中心化网关(gw1上,这中间还得NATed to the FIP 172.14.14.100)。
  • gw1路由流量到network2
  • 然后就是从network2 router所在chassis(gw1)因为在同一个子网network2就直接通过dvr 到host1 chassis了(使用该机制:ovs-vsctl get open . external_ids:ovn-chassis-mac-mappings,每个chassis上有一个不同的IP).

2, 没有FIP时的南北流量 (东西向L3)

此时虚机vm1没有FIP:

  • 由于运行ping的host1机器的网卡的mac与pext同,所以从host1发出的ping实际上就是从pext发出的。
  • 既然是从pext发出的ping,当然先从gw2开始(eth1.170)
  • 这里没有FIP, 到vm1所有的vlan 170实际上属于东西向流量,通过dvr机器就过去worker1了,不需要经过gw1
  • reply回程也是,直接worker1就回host1了

3, 东西向L2流量

就是纯粹的dvr机制了。每个chassis上有唯一的mac, 从一个chassis到另一个chassis之后,该chassis上的ovn-controller也知道每个虚机的mac/ip,当然就知道怎么转发了。

OpenStack在处理external port时的南北向流量问题

如上,使用了ovn based sriov port就涉及到external port, 又有FIP就涉及到了中心化的网关port。然后以上为例,这就存在:

  • vm1在worker1上
  • gateway port 192.168.0.1在gw1上
  • 处理dhcp和medata的external port (pext) 在gw2上
  • 运行ping命令的机器在host1上, 它配置了一个namespace连向ovs bridge, 有一个vlan 170 (network2)的vlan device

上面的流程都没问题,为什么openstack有问题呢?因为openstack还不支持external_ids:ovn-chassis-mac-mappings模式的dvr机制。这样当虚机(在worker1上)需要它的网关192.168.0.1的mac地址时,worker1上的ovn-controller根本就不知道。

  • worker1自己由于如上原因不支持external_ids:ovn-chassis-mac-mappings缺乏dvr特性支持所以自己不会回答192.168.0.1的mac
  • 那应只能是192.168.0.1所在的gw1回答这个mac (对于vlan router port使用了reside-on-redirect-chassis见:https://github.com/openstack/networking-ovn/commit/d22cc2a0dc8de7b792dc4be471277167fc2a94d3)
  • 但是对于这种有external port的VM发出的arp所以的chassis默认都是drop的,只有host external port的gw2除外,这样理想情况下应该是gw2来回答

这样就有两种解决方案:

  • 让gw1与gw2合并,cr-lrp port与pext port合在一块就没这问题了
  • 支持dvr模式(external_ids:ovn-chassis-mac-mappings),让cr-lrp port在worker1上,这样worker1自己负责自己的arp
    见:https://bugs.launchpad.net/neutron/+bug/1875852
      https://bugzilla.redhat.com/show_bug.cgi?id=1766930

回顾neutron ovs based dvr

openstack ovs based dvr ( https://blog.csdn.net/quqi99/article/details/20711303 ) 由于每个计算节点上都有gateway, 所以每个gateway都要有唯一的mac,这样在进出gateway时需要将router port mac转成这个gateway unique mac.

回顾neutron ovn based dvr

dvr改成ovn based之后, 原理一样,也得每个gateway-chassis上都配置不同的mac ( ovn-chassis-mac-mappings = physnet:aa:bb:cc:dd:ee:ff ), 在vlan流量从chaasis到physical network时ovn-controller都要编程flow用chassis mac代替router port mac

For example: chassis_mac = “aa:bb:cc:dd:ee:ff”, router_port_mac = “00:00:01:01:02:04”
cookie=0x0, duration=30.226s, table=65, n_packets=0, n_bytes=0, idle_age=30, priority=150,reg15=0x5,metadata=0x2,
dl_src=00:00:01:01:02:04 actions=mod_dl_src:aa:bb:cc:dd:ee:ff,output:30,mod_vlan_vid:118

  • ovn-controller直接产生arp reply到router port, 这样TOR就能学习VM的mac了。gateway-chassis能够独立解决router
  • port的ARP之后就可以进行南北流量了(一个chaasis变成gateway-chaasis之后会发GARP来广播router port的mac)
  • NAT, 转发package到gateway-chassis时用router port mac做为dest mac,

reference

[1] https://www.openvswitch.org/support/ovscon2018/6/1440-sharma.pdf

以上是关于vlan tenant network on ovn based dvr (by quqi99)的主要内容,如果未能解决你的问题,请参考以下文章

Tstack基础云修改网络模式Vxlan_OVs到Vlan_OVS

多主机Docker容器的VLAN划分

分析 OVS 如何实现 vlan 隔离 - 每天5分钟玩转 OpenStack(140)

虚拟机 vlan trunk 特性

ovs 实现vlan隔离

创建 OVS vlan101 并部署 instance - 每天5分钟玩转 OpenStack(139)