OVN实战二之Overlay实现

时间:2022-05-06
本文章向大家介绍OVN实战二之Overlay实现,主要内容包括前言、一、实验环境、1.2 准备虚拟机、1.3创建SW1搭建拓扑、二、验证结果、创建SW2、创建R1、参考资料、基本概念、基础应用、原理机制和需要注意的事项等,并结合实例形式分析了其使用技巧,希望通过本文能帮助到大家理解应用这部分内容。

前言

上一章介绍了GNS3的使用以及OVN系统的架构,搭建了实验环境,阐述了OVN各个进程的用途、彼此之间的关系,以及产生的日志(OVN实战一之GNS3操作指南及OVN入门,http://www.sdnlab.com/19765.html)。本章主要介绍我们实验的拓扑结构,然后实现拓扑中的相应功能。

一、实验环境

1.1 拓扑结构

上面拓扑中有四个“虚拟机(VM)”,分别属于两个广播域(二层交换机,SW),SW1和SW2通过R1连接起来。本章先实现SW1和SW2两个网络。

为了验证实验网络的Overlay功能(VXLAN封包、解包),这里故意把VM1和VM2分配到不同的物理机上,物理上的分布如下:

VM1、VM3运行在ovn-node2上;VM2、VM4运行在ovn-node3上。

1.2 准备虚拟机

笔者的实验资源有限,所以就不通过Hypervisor来创建虚拟机而是通过Linux network namespace模拟虚拟机。

Linux network namespace是Linux从2.6.24开始提供的一种“隔离技术”,它允许一个Linux内核可以拥有多个隔离的网络空间(独立的ARP表、路由表、IP地址、接口)。通过下面命令分别在ovn-node2、ovn-node3上创建VM1和VM2:

在ovn-node2上执行创建虚拟机VM1:

12345

sudo ip netns add vm1sudo ip link add vm1-eth0 type veth peer name veth-vm1sudo ip link set veth-vm1 upsudo ip link set vm1-eth0 netns vm1

为了便于测试此处使用固定MAC地址

1234567891011

sudo ip netns exec vm1 ip link set vm1-eth0 addres 00:00:00:00:00:01sudo ip netns exec vm1 ip link set vm1-eth0 upsudo ovs-vsctl add-port br-int veth-vm1 sudo ip netns add vm3sudo ip link add vm3-eth0 type veth peer name veth-vm3sudo ip link set veth-vm3 upsudo ip link set vm3-eth0 netns vm3sudo ip netns exec vm3 ip link set vm3-eth0 address 00:00:00:00:00:03sudo ip netns exec vm3 ip link set vm3-eth0 upsudo ovs-vsctl add-port br-int veth-vm3

在ovn-node3上执行创建虚拟机VM2:

123456789101112131415

sudo ip netns add vm2sudo ip link add vm2-eth0 type veth peer name veth-vm2sudo ip link set veth-vm2 upsudo ip link set vm2-eth0 netns vm2sudo ip netns exec vm2 ifconfig vm2-eth0 hw ether 00:00:00:00:00:02sudo ip netns exec vm2 ip link set vm2-eth0 upsudo ovs-vsctl add-port br-int veth-vm2 sudo ip netns add vm4sudo ip link add vm4-eth0 type veth peer name veth-vm4sudo ip link set veth-vm4 upsudo ip link set vm4-eth0 netns vm4sudo ip netns exec vm4 ip link set vm4-eth0 address 00:00:00:00:00:04sudo ip netns exec vm4 ip link set vm4-eth0 upsudo ovs-vsctl add-port br-int veth-vm4

我们用VETH来模拟模拟虚拟机的网卡,这是Linux提供的一种虚拟网络设备,它通常成对出现,送到一端请求发送的数据总是从另一端以请求接受的形式出现。我们一般把VETH的一端用于连接网桥,一段放入到net namespace中作为网卡。用同样的命令上创建VM3、VM4。

1.3创建SW1搭建拓扑

OVN的所有操作都在ovn-central节点完成,当需要操作网络拓扑中的“虚拟机”的时候我们才会用到ovn-host节点。OVN提供了两个命令行工具叫ovn-sbctl、ovn-nbctl,根据名字不难想到,ovn-sbctl是用来操作SB的;ovn-nbctl是用来操作NB的。逻辑交换机、逻辑路由器是放在NB中的所以和我们经常打交道的是ovn-nbctl。

在ovn-node1上执行:

12345

sudo ovn-nbctl ls-add sw1sudo ovn-nbctl lsp-add sw1 sw1-vm1sudo ovn-nbctl lsp-set-addresses sw1-vm1 "00:00:00:00:00:01 192.168.100.10"sudo ovn-nbctl lsp-add sw1 sw1-vm2sudo ovn-nbctl lsp-set-addresses sw1-vm2 "00:00:00:00:00:02 192.168.100.20"

ls-add命令用于添加逻辑交换机,lsp-add命令用于为逻辑交换机添加端口,在OVN中每个逻辑交换机都有一个唯一的命名。lsp-set-addresses为逻辑交换机端口配置MAC地址和IP地址,这一步骤是不可省略的,OVN会根据这两个信息生成流表 上述命令通过ovn-nbctl工具在NB中添加了一个逻辑交换机、两个逻辑交换机端口;ovn-northd进程会“发现”这个改变,然后读取NB中的数据把它转换成流表写入到SB数据库中(可以通过ovn-sbctl list Logical_Flow查看相关流表)。但是此时流表并没有下发到ovn-host中,需要通过下面命令建立逻辑交换机端口和OVS端口(ovn-host上的OVS)的关联。

在ovn-node2上执行

1

sudo ovs-vsctl set Interface veth-vm1 external_ids:iface-id=sw1-vm1

设置IP地址,必须和lsp-set-addresses 中的一致

1

sudo ip netns exec vm1 ip addr add 192.168.100.10/24 dev vm1-eth0

在ovn-node3上执行

12

sudo ovs-vsctl set Interface veth-vm2 external_ids:iface-id=sw1-vm2sudo ip netns exec vm2 ip addr add 192.168.100.20/24 dev vm2-eth0

二、验证结果

在node2上执行ping命令发送ICMP数据包;在GNS3中右击ovn-node2到SW1之间的链路选择“start capture”,GNS3会自动启动Wireshark抓取这段链路上的数据包。 ping命令正常执行,说明vm1和vm2之间可以互相通讯

Wireshark抓取的数据包显示,网络中传送的数据包是VxLAN封装后的Overlay数据包(VNI是1)

注意,Wireshark并没有抓到vm1和vm2之间的ARP数据包,这是OVN的一个特性叫“ARP Responder”,它的实现原理在调试部分说明。

2.1 调试

OVS提供了一个叫ofproto/trace的流表分析工具,用于分析数据包在流表中如何被“处理”。

在ovn-node2上执行

1

sudo ovs-appctl ofproto/trace br-int in_port=3,icmp,nw_src=192.168.100.10,nw_dst=192.168.100.20,dl_dst=00:00:00:00:00:02,dl_src=00:00:00:00:00:01

in_port指定数据包从哪个端口进来的,可以通过sudo ovs-ofctl dump-ports-desc br-int查看veth-vm1对应的port编号,在我的环境中它是3。 icmp指定了数据包类型 nw_src源IP地址 nw_dst是目标IP地址 dl_src是源MAC地址 dl_dst是目标MAC地址。

完整的输出太长,这里截取最后一部分,数据包最终被设置上tun_id=1从port2中发送出去。 通过sudo ovs-dpctl show可以查看DataPath和Port的对应关系,port 2对应的是vxlan_sys_xxxx,它是一种特殊的ovs port用于VXLAN的封包。

下面看一下ARP数据包是如何处理的

ovn-node2上执行

1

sudo ovs-appctl ofproto/trace br-int in_port=3,arp,arp_tpa=192.168.100.20,arp_op=1,dl_src=00:00:00:00:00:01

arp_tpa是目标IP地址 arp_op是ARP数据包类型,1表示request数据包,2表示reply数据包

ARP数据并没有被发送到到ovn-node3而直接在ovn-node2就终结了,流表自动构造了一个ARP Reply数据包回送到来源端口,这个特性就叫ARP Responder。

创建SW2

SW2的创建过程和SW1很像,此处直接罗列命令:

在ovn-node1上执行

12345

sudo ovn-nbctl ls-add sw2sudo ovn-nbctl lsp-add sw2 sw2-vm3sudo ovn-nbctl lsp-set-addresses sw2-vm3 "00:00:00:00:00:03 192.168.200.30"sudo ovn-nbctl lsp-add sw2 sw2-vm4sudo ovn-nbctl lsp-set-addresses sw2-vm4 "00:00:00:00:00:04 192.168.200.40"

在ovn-node2上执行

12

sudo ovs-vsctl set Interface veth-vm3 external_ids:iface-id=sw2-vm3sudo ip netns exec vm3 ip addr add 192.168.200.30/24 dev vm3-eth0

在ovn-node3上执行

12

sudo ovs-vsctl set Interface veth-vm4 external_ids:iface-id=sw2-vm4sudo ip netns exec vm4 ip addr add 192.168.200.40/24 dev vm4-eth0

验证WWW服务

这组环境用于验证TCP服务是否能正常工作,笔者在vm4上启动一个WWW服务,在vm3上通过curl访问。

在ovn-node3上执行

1

sudo ip netns exec vm4 python -m SimpleHTTPServer 8080

在ovn-node2上执行

1

sudo ip netns exec vm3 curl http://192.168.200.40:8080

执行结果如下图所示,说明WWW服务正常工作

创建R1

在ovn-node1上执行

1

sudo ovn-nbctl lr-add r1

此处的IP地址相当于路由表,输入格式是CIRD

1234567891011

sudo ovn-nbctl lrp-add r1 r1-sw1 00:00:00:00:10:00 192.168.100.1/24sudo ovn-nbctl lsp-add sw1 sw1-r1sudo ovn-nbctl lsp-set-type sw1-r1 routersudo ovn-nbctl lsp-set-addresses sw1-r1 00:00:00:00:10:00sudo ovn-nbctl lsp-set-options sw1-r1 router-port=r1-sw1 sudo ovn-nbctl lrp-add r1 r1-sw2 00:00:00:00:20:00 192.168.200.1/24sudo ovn-nbctl lsp-add sw2 sw2-r1sudo ovn-nbctl lsp-set-type sw2-r1 routersudo ovn-nbctl lsp-set-addresses sw2-r1 00:00:00:00:20:00sudo ovn-nbctl lsp-set-options sw2-r1 router-port=r1-sw2

由于Linux namespace没有默认网关,所以需要为vm1、vm2、vm3、vm4配置默认网关

ovn-node2

12

sudo ip netns exec vm1 ip route add default via 192.168.100.1sudo ip netns exec vm3 ip route add default via 192.168.200.1

ovn-node3

12

sudo ip netns exec vm2 ip route add default via 192.168.100.1sudo ip netns exec vm4 ip route add default via 192.168.200.1

通过vm1访问vm4的WWW服务,说明R1已经生效。

参考资料

OVS每个字段的说明,流表的语法规则 http://openvswitch.org/support/dist-docs/ovs-ofctl.8.html NB数据库结构 http://openvswitch.org/support/dist-docs/ovn-nb.5.html SB数据库结构 http://openvswitch.org/support/dist-docs/ovn-sb.5.html