在文章介绍了VXLAN机制,同时在VXLAN OVS实践基于ovs手动构建了一个overlay网络。同时,在Neutron Br-tun流表,分析了Neutron br-tun上的所有流表的作用。基于以上工作,本文,基于Neutron VXLAN的网络模型,手动构建overlay网络并能够承载虚机流量。
NEUTRON的网络模型:
Compute 2:
br-prv: 172.21.12.8 在此环境中为br-mgmt
网桥的添加和连接
添加ovs网桥: br-tun/br-int
#ovs-vsctl add-br br-tun
#ovs-vsctl add-br br-int
#ovs-vsctl set-fail-mode br-tun secure
#ovs-vsctl set-fail-mode br-int standalone
添加patch口,连接br-tun,br-int
#ovs-vsctl add-port br-tun patch-int -- set interface patch-int type=patch -- set interface patch-int options:peer=patch-tun
#ovs-vsctl add-port br-int patch-tun -- set interface patch-tun type=patch -- set interface patch-tun options:peer=patch-int
添加linux bridge:
#brctl addbr qbr123
#ip link set qbr123 up
添加veth口,连接br-int,qbr123
#ip link add name qvo123 type veth peer name qvb123
#ip link set qvo123 up
#ip link set qvb123 up
#ovs-vsctl add-port br-int qvo123
#brctl addif qbr123 qvb123
设置Compute 2上此VPC的local vlan: 22
#ovs-vsctl set port qvo123 tag=22
以上完成网桥的添加和连接。
首先利用namespace进行代替虚拟机进行测试,因此如下添加namespace以及测试的veth口:
添加namespace:
#ip netns add test
添加一个veth口,连接qbr123及namespace
#ip link add name veth1 type veth peer name veth1p
#ip link set dev veth1 netns test
#brctl addif qbr123 veth1p
#ip link set veth1p up
#ip netns exec test ip link set veth1 up
设置VPC IP
#ip netns exec test ip addr add 192.168.10.12/24 dev veth1
添加vxlan tunnel:
in_key及out_key=flow表示采用流表来处理数据流。
#ovs-vsctl add-port br-tun vxlan-01 -- set interface vxlan-01 type=vxlan \
options:remote_ip=172.21.12.163 options:df_default=true options:dst_port=4789 options:in_key=flow options:out_key=flow options:local_ip=172.21.12.8
Compute 1
br-prv: 172.21.12.163 在此环境中为br-mgmt
添加ovs网桥: br-tun/br-int
#ovs-vsctl add-br br-tun
#ovs-vsctl add-br br-int
standalone: 三次探测控制器连接不成功后,此时ovs-vswitchd将会接管转发逻辑,相当于一个正常的二层交换机
secure: 表示在连接不到控制器时,根据现有流表转发。
#ovs-vsctl set-fail-mode br-tun secure
#ovs-vsctl set-fail-mode br-int standalone
添加patch口,连接br-tun,br-int:
#ovs-vsctl add-port br-tun patch-int -- set interface patch-int type=patch -- set interface patch-int options:peer=patch-tun
#ovs-vsctl add-port br-int patch-tun -- set interface patch-tun type=patch -- set interface patch-tun options:peer=patch-int
添加linux bridge:
#brctl addbr qbr123
#ip link set qbr123 up
添加veth口,连接br-int,qbr123:
#ip link add name qvo123 type veth peer name qvb123
#ip link set qvo123 up
#ip link set qvb123 up
#ovs-vsctl add-port br-int qvo123
#brctl addif qbr123 qvb123
设置Compute 2上此VPC的local vlan: 12
#ovs-vsctl set port qvo123 tag=12
以上完成网桥的添加和连接。
首先利用namespace进行代替虚拟机进行测试,因此如下添加namespace以及测试的veth口:
添加namespace:
#ip netns add test
添加一个veth口,连接qbr123及namespace:
#ip link add name veth1 type veth peer name veth1p
#ip link set dev veth1 netns test
#brctl addif qbr123 veth1p
#ip link set veth1p up
#ip netns exec test ip link set veth1 up
设置VPC IP
#ip netns exec test ip addr add 192.168.10.11/24 dev veth1
添加vxlan tunnel:
#ovs-vsctl add-port br-tun vxlan-01 -- set interface vxlan-01 type=vxlan \
options:remote_ip=172.21.12.8 options:df_default=true options:dst_port=4789 options:in_key=flow options:out_key=flow options:local_ip=172.21.12.163
测试:
在利用流表进行数据转发前,我们先测试以上网络是否已通:
设置br-tun的fail_mode模式为standalone,具有二层学习转发能力:
compute1/compute2:
#ovs-vsctl set-fail-mode br-tun standalone
设置qvo123的tag一致:
compute1:
#ovs-vsctl set port qvo123 tag=22
重新设置vxlan tunnel:
compute1/2:
compute1:
#ovs-vsctl del-port vxlan-01
#ovs-vsctl add-port br-tun vxlan-01 -- set interface vxlan-01 type=vxlan options:remote_ip=172.21.12.8 options:key=0x22
compute2:
#ovs-vsctl del-port vxlan-01
#ovs-vsctl add-port br-tun vxlan-01 -- set interface vxlan-01 type=vxlan options:remote_ip=172.21.12.163 options:key=0x22
ping测试:
[root@localhost ~]# ip netns exec test ping 192.168.10.12
PING 192.168.10.12 (192.168.10.12) 56(84) bytes of data.
64 bytes from 192.168.10.12: icmp_seq=1 ttl=64 time=1.61 ms
64 bytes from 192.168.10.12: icmp_seq=2 ttl=64 time=0.549 ms
64 bytes from 192.168.10.12: icmp_seq=3 ttl=64 time=0.480 ms
^C
--- 192.168.10.12 ping statistics ---
3 packets transmitted, 3 received, 0% packet loss, time 2001ms
rtt min/avg/max/mdev = 0.480/0.882/1.619/0.522 ms
如上发现网络已通。
以上完成基础网络的搭建,在NEUTRON OVS网络中,数据流是根据br-tun/br-int流表匹配转发的,因此下一步工作,我们添加流表(br-int仍设置为standalone模式)。
清理测试的配置,恢复br-tun的fail_mode,及vxlan tunnel:
#ovs-vsctl set-fail-mode br-tun secure
vxlan的设置不在重复,删除端口,重配vxlan port。
添加流表
以上完成基础网络的搭建,在NEUTRON OVS网络中,数据流是根据br-tun/br-int流表匹配转发的,因此下一步工作,我们添加流表(br-int仍设置为standalone模式)。
清理测试的配置,恢复br-tun的fail_mode,及vxlan tunnel:
#ovs-vsctl set-fail-mode br-tun secure
vxlan的设置不在重复,删除端口,重配vxlan port。
流表类型:
- 入流表的流量处理
- 出流量的流表处理
- 广播及单播包的处理
- 能够自学习的流表
首先分析br-tun的端口:
- patch-int: 与br-int互连的patch口
- vxlan-*: vxlan与remote vtep 对应的tunnel 口
- br-tun: 本地口,无需关注
首先流表分类:
- table 0: 入流量的初步处理,其中patch-int的入流量交由table 2处理;VLXAN Port入流量交由table 4进一步处理
- table 2: 单播及广播包的处理,单播包交由table 20处理,广播包交由table 22处理
- table 3: 默认Drop流表
- table 4: 处理vxlan数据的规则,解封装,添加对应的local vlan;以及最后默认Drop的流表
- table 6: 默认Drop流表
- table 10: 能够mac学习的流表,避免广播。生成的流表默认添加在table 20。生成流表主要对应的是:目的mac地址 vlan actions: {移除vlan 添加vni} output:port
- table 20: 由table 10生成的流表,以及一条默认流表。默认流表主要将数据交由table 22处理
- table 22: 广播,针对每一个VPC对应一个流表。默认Drop流表
查看compute 2 br-tun port:
[root@youngster ~]# ovs-ofctl show br-tun
OFPT_FEATURES_REPLY (xid=0x2): dpid:0000023d182e2b48
n_tables:254, n_buffers:256
capabilities: FLOW_STATS TABLE_STATS PORT_STATS QUEUE_STATS ARP_MATCH_IP
actions: output enqueue set_vlan_vid set_vlan_pcp strip_vlan mod_dl_src mod_dl_dst mod_nw_src mod_nw_dst mod_nw_tos mod_tp_src mod_tp_dst
1(patch-int): addr:fe:dd:0b:6a:85:91
config: 0
state: 0
speed: 0 Mbps now, 0 Mbps max
7(vxlan-01): addr:8e:83:ab:26:c1:34
config: 0
state: 0
speed: 0 Mbps now, 0 Mbps max
LOCAL(br-tun): addr:02:3d:18:2e:2b:48
config: PORT_DOWN
state: LINK_DOWN
speed: 0 Mbps now, 0 Mbps max
OFPT_GET_CONFIG_REPLY (xid=0x4): frags=normal miss_send_len=0
两个Port:
- port 1: patch-int
- port 7: vxlan-01 #vxlan tunnel: 连接compute1 vtep的port;其中compute1 port 8
VPC 的参数:
VNI: VPC之间的隔离;
Local Vlan: 相同物理机下,不同VPC下的虚拟机之间网络的二层隔离;
- vni: 0x22
- local vlan: compute1:12, compuet2:22
table 0流表
compute1:
处理patch-int包,虚机出流量
#ovs-ofctl add-flow br-tun 'cookie=0x79, table=0, priority=1,in_port=1 actions=resubmit(,2)'
处理vxlan包,从vxlan tunnel进入的数据包
#ovs-ofctl add-flow br-tun 'cookie=0x79, table=0, priority=1,in_port=8 actions=resubmit(,4)'
默认规则
#ovs-ofctl add-flow br-tun 'cookie=0x79, table=0, priority=0 actions=drop'
compute2:
处理patch-int包,虚机出流量
#ovs-ofctl add-flow br-tun 'cookie=0x79, table=0, priority=1,in_port=1 actions=resubmit(,2)'
处理vxlan包,从vxlan tunnel进入的数据包
#ovs-ofctl add-flow br-tun 'cookie=0x79, table=0, priority=1,in_port=7 actions=resubmit(,4)'
默认规则
#ovs-ofctl add-flow br-tun 'cookie=0x79, table=0, priority=0 actions=drop'
table 2流表
compute1/2:
单播包
#ovs-ofctl add-flow br-tun 'cookie=0x79, table=2, priority=0,dl_dst=00:00:00:00:00:00/01:00:00:00:00:00 actions=resubmit(,20)'
广播包
#ovs-ofctl add-flow br-tun 'cookie=0x79, table=2, priority=0,dl_dst=01:00:00:00:00:00/01:00:00:00:00:00 actions=resubmit(,22)'
table 3流表
compute1/2:
#ovs-ofctl add-flow br-tun 'cookie=0x79, table=3, priority=0 actions=drop'
table 4流表
compute1:
#ovs-ofctl add-flow br-tun 'cookie=0x79, table=4, priority=1,tun_id=0x22 actions=mod_vlan_vid:12,resubmit(,10)'
#ovs-ofctl add-flow br-tun 'cookie=0x79, table=4, priority=0 actions=drop'
compute2:
#ovs-ofctl add-flow br-tun 'cookie=0x79, table=4, priority=1,tun_id=0x22 actions=mod_vlan_vid:22,resubmit(,10)'
#ovs-ofctl add-flow br-tun 'cookie=0x79, table=4, priority=0 actions=drop'
table 6流表
compute1/2:
#ovs-ofctl add-flow br-tun 'cookie=0x79, table=6, priority=0 actions=drop'
table 10流表
compute1/2:
#ovs-ofctl add-flow br-tun 'cookie=0x79, table=10, priority=1 actions=learn(table=20,hard_timeout=300,priority=1,cookie=0xa9eb8f9011f7e038,NXM_OF_VLAN_TCI[0..11],NXM_OF_ETH_DST[]=NXM_OF_ETH_SRC[],load:0->NXM_OF_VLAN_TCI[],load:NXM_NX_TUN_ID[]->NXM_NX_TUN_ID[],output:NXM_OF_IN_PORT[]),output:1'
table 20流表
compute1/2:
#ovs-ofctl add-flow br-tun 'cookie=0x79, table=20, priority=0 actions=resubmit(,22)'
table 22流表
compute1
#ovs-ofctl add-flow br-tun 'cookie=0x79, table=22, dl_vlan=12 actions=strip_vlan,set_tunnel:0x22,output:8'
#ovs-ofctl add-flow br-tun 'cookie=0x79, table=22,priority=0 actions=drop'
compute2:
#ovs-ofctl add-flow br-tun 'cookie=0x79, table=22, dl_vlan=22 actions=strip_vlan,set_tunnel:0x22,output:7'
#ovs-ofctl add-flow br-tun 'cookie=0x79, table=22,priority=0 actions=drop'
compute1流表显示如下:
[root@localhost ~]# ovs-ofctl dump-flows br-tun
NXST_FLOW reply (xid=0x4):
cookie=0x79, duration=470.541s, table=0, n_packets=0, n_bytes=0, idle_age=470, priority=1,in_port=1 actions=resubmit(,2)
cookie=0x79, duration=429.619s, table=0, n_packets=0, n_bytes=0, idle_age=429, priority=1,in_port=8 actions=resubmit(,4)
cookie=0x79, duration=421.374s, table=0, n_packets=0, n_bytes=0, idle_age=421, priority=0 actions=drop
cookie=0x79, duration=350.941s, table=2, n_packets=0, n_bytes=0, idle_age=350, priority=0,dl_dst=00:00:00:00:00:00/01:00:00:00:00:00 actions=resubmit(,20)
cookie=0x79, duration=349.111s, table=2, n_packets=0, n_bytes=0, idle_age=349, priority=0,dl_dst=01:00:00:00:00:00/01:00:00:00:00:00 actions=resubmit(,22)
cookie=0x79, duration=277.425s, table=3, n_packets=0, n_bytes=0, idle_age=277, priority=0 actions=drop
cookie=0x79, duration=198.573s, table=4, n_packets=0, n_bytes=0, idle_age=198, priority=1,tun_id=0x22 actions=mod_vlan_vid:12,resubmit(,10)
cookie=0x79, duration=197.620s, table=4, n_packets=0, n_bytes=0, idle_age=197, priority=0 actions=drop
cookie=0x79, duration=160.508s, table=6, n_packets=0, n_bytes=0, idle_age=160, priority=0 actions=drop
cookie=0x79, duration=117.020s, table=10, n_packets=0, n_bytes=0, idle_age=117, priority=1 actions=learn(table=20,hard_timeout=300,priority=1,cookie=0xa9eb8f9011f7e038,NXM_OF_VLAN_TCI[0..11],NXM_OF_ETH_DST[]=NXM_OF_ETH_SRC[],load:0->NXM_OF_VLAN_TCI[],load:NXM_NX_TUN_ID[]->NXM_NX_TUN_ID[],output:NXM_OF_IN_PORT[]),output:1
cookie=0x79, duration=94.170s, table=20, n_packets=0, n_bytes=0, idle_age=94, priority=0 actions=resubmit(,22)
cookie=0x79, duration=47.240s, table=22, n_packets=0, n_bytes=0, idle_age=47, dl_vlan=12 actions=strip_vlan,set_tunnel:0x22,output:8
cookie=0x79, duration=46.207s, table=22, n_packets=0, n_bytes=0, idle_age=46, priority=0 actions=drop
compuet2流表如下:
[root@youngster ~]# ovs-ofctl dump-flows br-tun
NXST_FLOW reply (xid=0x4):
cookie=0x79, duration=503.189s, table=0, n_packets=0, n_bytes=0, idle_age=503, priority=1,in_port=1 actions=resubmit(,2)
cookie=0x79, duration=495.878s, table=0, n_packets=0, n_bytes=0, idle_age=495, priority=1,in_port=7 actions=resubmit(,4)
cookie=0x79, duration=488.948s, table=0, n_packets=0, n_bytes=0, idle_age=488, priority=0 actions=drop
cookie=0x79, duration=453.568s, table=2, n_packets=0, n_bytes=0, idle_age=453, priority=0,dl_dst=00:00:00:00:00:00/01:00:00:00:00:00 actions=resubmit(,20)
cookie=0x79, duration=452.646s, table=2, n_packets=0, n_bytes=0, idle_age=452, priority=0,dl_dst=01:00:00:00:00:00/01:00:00:00:00:00 actions=resubmit(,22)
cookie=0x79, duration=380.931s, table=3, n_packets=0, n_bytes=0, idle_age=380, priority=0 actions=drop
cookie=0x79, duration=283.978s, table=4, n_packets=0, n_bytes=0, idle_age=283, priority=1,tun_id=0x22 actions=mod_vlan_vid:22,resubmit(,10)
cookie=0x79, duration=282.626s, table=4, n_packets=0, n_bytes=0, idle_age=282, priority=0 actions=drop
cookie=0x79, duration=264.334s, table=6, n_packets=0, n_bytes=0, idle_age=264, priority=0 actions=drop
cookie=0x79, duration=220.450s, table=10, n_packets=0, n_bytes=0, idle_age=220, priority=1 actions=learn(table=20,hard_timeout=300,priority=1,cookie=0xa9eb8f9011f7e038,NXM_OF_VLAN_TCI[0..11],NXM_OF_ETH_DST[]=NXM_OF_ETH_SRC[],load:0->NXM_OF_VLAN_TCI[],load:NXM_NX_TUN_ID[]->NXM_NX_TUN_ID[],output:NXM_OF_IN_PORT[]),output:1
cookie=0x79, duration=177.267s, table=20, n_packets=0, n_bytes=0, idle_age=177, priority=0 actions=resubmit(,22)
cookie=0x79, duration=130.243s, table=22, n_packets=0, n_bytes=0, idle_age=130, dl_vlan=22 actions=strip_vlan,set_tunnel:0x22,output:7
cookie=0x79, duration=128.692s, table=22, n_packets=0, n_bytes=0, idle_age=128, priority=0 actions=drop
测试连通性,如下:
网络已能从compute1 ping 通compute2中的地址。同时检查compute2 上的table 20流表,会发现学习生成至compute1 veth1的流表,如下。
compute1 test中的veth1 -> compute2 test中的veth1
[root@localhost ~]# ip netns exec test ping 192.168.10.12
PING 192.168.10.12 (192.168.10.12) 56(84) bytes of data.
64 bytes from 192.168.10.12: icmp_seq=1 ttl=64 time=0.548 ms
64 bytes from 192.168.10.12: icmp_seq=2 ttl=64 time=0.526 ms
64 bytes from 192.168.10.12: icmp_seq=3 ttl=64 time=0.524 ms
64 bytes from 192.168.10.12: icmp_seq=4 ttl=64 time=0.540 ms
64 bytes from 192.168.10.12: icmp_seq=5 ttl=64 time=0.525 ms
64 bytes from 192.168.10.12: icmp_seq=6 ttl=64 time=0.521 ms
检查compute2上的table20流表,多了一个流表项,dl_dst=veth1_mac(compute1),output7,表示下次发往veth1(compute1)通过此流表匹配出去,不需要广播了:
cookie=0xa9eb8f9011f7e038, duration=22.636s, table=20, n_packets=12, n_bytes=1064, hard_timeout=300, idle_age=8, hard_age=7, priority=1,vlan_tci=0x0016/0x0fff,dl_dst=c:eb:1e:c1:ff:8c actions=load:0->NXM_OF_VLAN_TCI[],load:0x22->NXM_NX_TUN_ID[],output:7
上述内容,完成计算节点上VPC网络设计,将在下一篇文章中介绍如添加一个“VPC”网络,流表的变化,同时介绍网络节点的实现