SDNLAB技术分享(四):利用ODL下发流表创建VxLAN网络

邓晓涛,当前就职于江苏省未来网络创新研究院,是CDN团队的一名研发人员,主要从事SDN相关的研发相关工作。曾就职于三星电子于先行解决方案研发组任高级工程师、思科系统于云协作应用技术部(CCATG)任工程师。
-----------------------------------------------------------------------------------------------------
【分享正文】
今天想跟大家分享如何通过ODL控制器下发流表来创建VxLAN网络。ODL作为当前流行的控制器,已经有广泛的应用。基于ODL提供了丰富的北向接口,使得应用对网络有了更好的掌控。我们为什么需要研究VxLAN网络,VxLAN网络现在已经成为多数据中心网络的解决方案,提供丰富的网络功能,比如更多的租户数量、虚拟机迁移、IP冲突等问题得到有效解决。

一.实验目的

通过本次分享,你将会了解到以下内容:

  • 构建VxLAN网络的基本步骤。
  • Mininet构建网络拓扑。
  • ODL北向接口Restconf的使用。
  • XML格式的流表创建

二.实验准备

  • Mininet虚拟机:实验中使用mininet-2.2.1-150420-ubuntu-14.04-server-amd64
  • VMware Workstation:加载Mininet虚拟机、运行ODL虚拟机。
  • OpenDaylight: Lithium版本(Oracle JDK8)。
  • Wireshark:抓包分析,建议利用远程方式抓包。
  • Postman:发送REST请求。

三.构建环境

实验中共使用了3台虚拟机,如下图所示,VM1和VM2是Mininet虚拟机,VM3运行ODL。

如上图所示,我们所要构建的网络假定VM1和VM2分别代表两个互通的数据中心。颜色不同的host代表不同的租户。假定当前租户RED和BLUE的网络需求如下表,即租户RED和BLUE拥有两个IP和MAC相同的主机,为了在同一个数据中心网络中保证租户间的网络隔离,并且使得租户网络层实现L2通信。

Table1. 租户信息表

DC Host IP MAC TENANT
VM1 red1 10.0.0.1/8 00:00:00:00:aa:01 RED
  blue1 10.0.0.1/8 00:00:00:00:aa:01 BLUE
VM2 red2 10.0.0.2/8 00:00:00:00:aa:02 RED
  blue2 10.0.0.2/8 00:00:00:00:aa:02 BLUE

四.实验过程

实验过程分为以下几个步骤:

  • 创建网络拓扑:构建如图1所需要的实验场景。
  • 创建隧道:构建VxLAN网络,建立L2通信隧道。
  • 下发流表:控制器下发流表,演示流表的工作原理。
  • 验证网络:验证VxLAN网络。

1.创建网络拓扑

首先启动三台虚拟机,VM1(192.168.1.10)和VM2(192.168.2.20)是Mininet虚拟机,VM3(192.168.3.30)为安装有ODL的控制器服务器。

启动控制器,安装下列组件。下列组件中虽然不是所有的都是该实验必须的,没有经过仔细的排查。如果运行的环境中已经有安装的组件,可以从列表中忽略。另外,有些组件会与当前的组件有端口占用情况,请仔细查看日子。在VM3上运行ODL,通过karaf控制台执行如下命令进行安装:

Shell

1

2

$> feature:install odl-l2switch-all odl-ovsdb-all odl-base-all odl-aaa-authn odl-restconf-all odl-nsf-all odl-adsal-northbound odl-mdsal-apidocs  odl-dlux-all

$> feature:install odl-ovsdb-southbound-api odl-ovsdb-southbound-impl odl-ovsdb-southbound-impl-rest odl-ovsdb-southbound-impl-ui odl-openflowplugin-all-li odl-openflowplugin-adsal-compatibility-all

如图1所示的网络部署图,分别启动Mininet虚拟机,复制Mininet的自定义的拓扑文件,并修改如下部分,一下代码为VM1的执行,请根据具体情况执行VM2创建脚本。

Shell

1

2

3

$> cp ~/mininet/custom/ topo-2sw-2host.py ~/vm1.py

#修改vm1.py

$> vi ~/vm1.py

仅对添加Hosts和Switches以及Links的部分进行修改,修改如下:

Shell

1

2

3

4

5

6

7

# Add hosts and switches

leftHost = self.addHost( ‘red1‘, ip="10.0.0.1/8", mac="00:00:00:00:aa:01")

rightHost = self.addHost(‘blue1‘, ip="10.0.0.1/8", mac="00:00:00:00:aa:01")

leftSwitch = self.addSwitch( ‘s1‘ )

# Add links

self.addLink( leftHost, leftSwitch )

self.addLink( leftSwitch, rightSwitch )

修改完成后创建拓扑:

Shell

1

$> sudo mn --controller remote,ip=192.168.3.30 --custom ~/vm1.py

创建完网络拓扑后,对网络拓扑进行相应的检查,比如创建的端口编号,对应端口的链路,以及当前网桥的流表,知道这些细节对后面流表编程有帮助。

检查创建的端口以及端口

Shell

1

mininet> sh ovs-ofctl show s1

检查当前网络链路

Shell

1

mininet> net

检查当前网络端口号

Shell

1

mininet> sh ovs-vsctl -- --columns=name,ofport list Interface

查看manager和controller的状态是否连接控制器成功

Shell

1

mininet> sh ovs-vsctl show

如果没有连接成功,先删除,再重新设置

Shell

1

2

3

mininet> sh ovs-vsctl del-manager

mininet> sh ovs-vsctl del-controller s1

mininet> sh ovs-vsctl set-manager tcp:192.168.3.30:6640

设置s1网桥控制器,注意端口号,有的控制器默认端口是6653

Shell

1

mininet> sh ovs-vsctl set-controller tcp:192.168.3.30:6633

2.创建隧道

网络拓扑创建完成后,可以登录ODL的dlux界面查看创建的端口以及拓扑情况。如果在mininet上执行ping命令,ODL会下发相关流表到对应的网桥上。开始创建VxLAN隧道,当然我们也可以用命令行进行创建。命令行创建相对来说比较简单,命令行如下:

Shell

1

> sh ovs-vsctl add-port s1 vtep -- set interface vtep type=vxlan option:remote_ip=192.168.2.20 option:key=flow ofport_request=10

如上面命令所示: 在网桥s1上创建端口vtep并在端口下创建同名的接口,接口类型为vxlan,可选参数中指定隧道的remote_ip为192.168.2.20,key=flow表示隧道的VNI是通过流表来指定,ofport_request=10表示创建默认端口号10的端口作为VxLAN通信端口,如果端口被占用,系统自动分配,该端口号在创建流表时会用到。需要注意的是隧道创建是双向的,即是说在一端创建了VTEP,在另一个所指的remote机器上也应创建相应的vxlan端口。 我们接下来不准备用命令行创建,而是用ODL的北向接口创建隧道。在VM3的服务器上利用Postman依次完成以下操作:
1).获得OVS节点
Postman发送Get请求,并在参数列表中添加Basic Auth,默认为 admin/admin

Shell

1

GET: http://192.168.3.30:8282/ovsdb/nb/v3/node

GET结果返回值如下:

Shell

1

2

3

4

[

"OVS|192.168.1.10:63344",

"OVS|192.168.2.20:63647"

]

以上端口分别为OVS实例。分别在VM1和VM2上。
2)创建隧道端口(port)
根据返回的节点,依据上面的创建隧道命名,依次创建端口,接口和隧道,其中node后的参数为Get获得的OVS实例。

Shell

1

POST: http:// 192.168.3.30:8282/ovsdb/nb/v2/node/OVS/192.168.1.10:63344/tables/port/rows

BODY内容如下,parent_uuid是s1的UUID,可以通过相关的REST API获得。

Shell

1

2

3

4

5

6

7

8

{

"parent_uuid":"4d2742b0-e5d8-4228-8c56-4a283f50038e",

"row":{

"Port":{

"name":"vtep"

}

}

}

3)创建隧道接口
依然在VM1上创建

Shell

1

POST: http:// 192.168.3.30:8282/ovsdb/nb/v2/node/OVS/192.168.1.10:63344/tables/interface/rows

BODY如下,请根据实际情况调整uuid.

Shell

1

2

3

4

5

6

7

8

9

{

"parent_uuid": "2fdc88be-0908-4738-ae8c-9328aeb4fcc5",

"row":{

"Interface":{

"name":"vtep",

"type":"vxlan"

}

}

}

4)更新隧道配置项的值。
通过Postman的put更新VxLAN的interface的值。注意UUID是interface.

Shell

1

PUT: http:// 192.168.3.30:8282/ovsdb/nb/v2/node/OVS/192.168.1.10:63344/tables/interface/rows/${UUIU}

Shell

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

{

"row":{

"Interface":{

"type":"vxlan",

"ofport_request":10,

"options": ["map",

[

["key","flow"],

["local_ip","192.168.1.10"],

["remote_ip","192.168.2.20"]

]

]

}

}

}

注:只有等Interface创建好后,对属性设置才有效。如果在创建过程中指定属性值,属性值可能不会被写入。

上述过程描述的是利用OpenDaylight的REST接口创建隧道,相对于命令而言显得复杂。如命令行创建隧道一样,在一个节点创建隧道,统一需要对另一个节点创建隧道,是一个双向的操作过程,在实践过程中,请注意根据实际情况对REST中相应的参数进行修改。值得注意的是:REST请求的接口有时用v2,有时用v3,是由于Lithium版本的v3接口实现了部分功能,但当前的v2版本是向下兼容的。

3.下发流表

当隧道建立完毕,对应的网桥中的流表为空,也就是当前OVS对任何流不做处理,下面我们就通过控制器下发流表,让OVS完成我们所需要的功能:

  • 根据端口号为租户设置VNI。
  • 根据MAC地址转发相应的包。
  • 根据IP地址转发相应的包。

以下流表是需要下发到VM1上OVS的s1的网桥中,以完成整个VxLAN网络的建立。当然目前只是针对4个host构建的拓扑网络,相对比较简单。如果大家有兴趣,可以参考OpenStack的Neutron网络中是如何规划VxLAN的流表,其中涉及到了Mac地址学习等。所以当前直接把Mac地址写入到流表。大家可以根据以下流表看出转发包的逻辑,以端口1的包转发为例解释如下:

第1条:端口1的流为其设置VNI为100,并转到下一级流表处理;
第4条:VNI为100的包,如果其目的地址为aa:01,则从1号口出,即转发给red1。
第6条:VNI为100的包,如果目的地址为00:a2, 这将包从隧道端口10发送出去。
第8条:VNI为100的ARP包,网络地址为本地IP,从端口1转出。
第10条:VNI为100的ARP包,网络地址为远端IP,从隧道端口10转出。

Shell

1

2

3

4

5

6

7

8

9

10

11

12

13

14

table=0,in_port=1,actions=set_field:100->tun_id,resubmit(,1)

table=0,in_port=2,actions=set_field:200->tun_id,resubmit(,1)

table=0,actions=resubmit(,1)

table=1,tun_id=100,dl_dst=00:00:00:00:aa:01,actions=output:1

table=1,tun_id=200,dl_dst=00:00:00:00:aa:01,actions=output:2

table=1,tun_id=100,dl_dst=00:00:00:00:aa:02,actions=output:10

table=1,tun_id=200,dl_dst=00:00:00:00:aa:02,actions=output:10

table=1,tun_id=100,arp,nw_dst=10.0.0.1,actions=output:1

table=1,tun_id=200,arp,nw_dst=10.0.0.1,actions=output:2

table=1,tun_id=100,arp,nw_dst=10.0.0.2,actions=output:10

table=1,tun_id=200,arp,nw_dst=10.0.0.2,actions=output:10

table=1,priority=100,actions=drop

下面将通过ODL的restconf API来下发流表。根据上面的讲述,对于VM1和VM2,都需要下发12条流,如果用命令行,那么只需要将流表保存于文本中,利用ovs-ofctl add-flows命令可以一次性加入,如果用REST API下发流表,则需要逐条发送。

将文本流表转换成XML格式的流表,请参考ODL官方指南,另外大家可以参考ask.opendaylight.org针对该问题的解决方案。此处列举了流表第1条的例子。更完整的例子可以到SDNLAB官方下载。

Shell

1

POST: http://192.168.3.30:8181/restconf/config/opendaylight-inventory:nodes/node/openflow:1/table/0/

Body:

Shell

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

<?xml version="1.0" encoding="UTF-8" standalone="no"?>

<flow xmlns="urn:opendaylight:flow:inventory">

<flow-name>S1T0F1</flow-name>

<table_id>0</table_id>

<id>1</id>

<installHw>false</installHw>

<strict>false</strict>

<priority>10</priority>

<instructions>

<instruction>

<order>0</order>

<apply-actions>

<action>

<order>0</order>

<set-field>

<tunnel>

<tunnel-id>100</tunnel-id>

</tunnel>

</set-field>

</action>

</apply-actions>

</instruction>

<instruction>

<order>1</order>

<go-to-table>

<table_id>1</table_id>

</go-to-table>

</instruction>

</instructions>

<match>

<in-port>1</in-port>

</match>

</flow>

注:完整Postman流表脚本下载

注:这个是本次实验的重点和难点。由于在网上找不到关于流表的DTD的定义,很多字段靠自己揣摩和反复实验,才知道是否是正确的。更难的是,因为最终的效果必须等到12条流表全部正确,才能知道结果是否正确。

注:实验过程中,有时候流表是错误的,但是POST的消息没有反馈任何错误提示,也是试验中的坑。

4.验证网络

可以通过ping命令对网络进行验证。为了确定租户网络是否隔离,可以尝试分别断开相同MAC地址的网络连接,再尝试ping,看是否能达到预期效果。测试命令如下:

在VM2上断开blue2的链接

Shell

1

mininet> blue2 ip link set dev blue2-eth0 down

在VM1上租户red1 ping 对端主机

Shell

1

mininet> red1 ping 10.0.0.2

注:验证过程中,特别提醒,租户IP最好不要选用10网段,有可能你的网络本身不通,但是遇到10.0.0.1这样的IP可能误解为网络正常。

五.实验结论

ODL提供了丰富的API对底层的转发设备进行控制,可以基于API对网络进行高效的编排和控制。实验中验证的VxLAN网络也具有实际的应用场景,例如OpenStack的Neutron网络是一个很好的案例。相对于本文介绍的实验,在数据中心间构建VxLAN网络更具挑战性,我们期待有从事这方面研究的朋友一起讨论并分享这方面的经验。

Q&A

Q1:安徽-桥
ODL会下发相关流表到对应的网桥上,网桥要自己设置吗?

会到网桥上。你可以通过ovs-ofctl 查询到 通过POST创建的流表。ovs-vsctl show出来通过Post创建的port和interface.

Q2:心随风飞
我想请问下,在你做的实验里,流表中的参数都需要手动制定,包括流表下发。这些动作能否都自动实现呢?

流表中的参数都是属于业务逻辑。比如你要创建100个租户的,那么你的NID就需要规划了。我们利用ODL创建流表,也就是通过编程的方式实现网络的编排。演示过程只是表示ODL可以这么做。所以自动实现是没有问题的。

Q3:新疆-m0ster
我做过VXLAN使用命令行生成隧道的实验,OVS后面的模拟租户通过隧道成功的互通了,这个过程没有流表的下发,它是怎么实现互通的?

你创建隧道的过程中的一个参数 key=flow这个参数没有指定,对吧。默认所有的流表都属于一个租户。所以是没有租户概念的。本实验中体现除了租户隔离的这个功能,所以用了key=flow这个参数,也就是让流表对隧道VNI进行指定。

Q4:如之何
想问下,如果租户自己本身就有几个vlan, 要怎么通过vxlan互通呢? 

租户的VLAN有VLAN_ID,那么这个可以通过流表的Modify操作来进行Mapping,转换成VNI。只要租户想通信的网络拥有相同的VNI就没有问题。你可以参考OpenStack的相关流表。比如在OpenStack中,你可以在同一个虚拟路由上创建多个子网,每个子网属于一个VLAN,那么一个vRouter出去后,则属于同一个VNI,那么这些子网是可以相互通信的,就算这些计算节点是分布的。

Q5:大连-吉祥
如何用控制器控制网络中链路的带宽,时延,抖动等qos参数

你的问题我也遇到过,可以参考https://wiki.opendaylight.org/view/OpenDaylight_OpenFlow_Plugin:End_to_End_Flows由于没有官方的XML的流表DTD说明文档,有时候只能靠摸索,然后通过查流表中的参数来验证配置是否正确。但是很遗憾的是,ODL在容错处理上不友好,比如有时候流表的XML参数配置错误,但你POST状态显示成功。

Q6:成都-东风
这个比上次的清楚些老,上次完全坐飞机。初学者感到很费解的,普通交换机二层转发自动通过ARP应答,三层通过IP和网关,现在SDN了难道每一个2层通讯动作都要这么复杂,一个过程就要写那么多条流表?还要事先知道Mac地址?

你的问题很好!你可以参考OpenStack的Neutron网络,它在实现长采用了Mac自学习的方式来配置流表。有兴趣的同学可以去了解如何通过学习Mac地址来简化流表,很好的问题。关于ARP应答,这个就比较复杂,在这里不深入展开,有兴趣可以参考OpenStack的虚拟路由的实现。

Q7:新疆-m0ster
使用命令行创建VXLAN隧道的时候也没有指定VNI信息,当时我就觉得很费解,理论VXLAN支持1600万,这个量体现在哪?

那个1600万就体现在VNI上

Q8:Beyond myself
分享过程中涉及到创建vxlan网络,构建l2 tunnel隧道,odl代码实现过程存在add br-int 和br-tun网桥这些网桥吗

ODL通过Rest API创建 Brige, Port和Interface是机上是操作OVSDB的表。在实例中,VXLAN的port同样是用Post创建的,所以应该没有问题。只是本例中将部分过程省略。

Q9:成都-东风
从刚才的Vxlan配置看也很不复杂,但最初的包转发就一大堆流表需要写?这才2台VM,如果大型数据中心咋办?

你说得对。当然只有增加节点是会下发相关流表。另一方面,前面回答过,也有学习Mac地址的实现方式,请参考OpenStack的Neutron网络中如何实现学习流表的。

Q10:小柠檬
vxlan是解决数据中心vlan-id不够分的问题吗

VxLAN解决 VLAN很多的问题,不只是ID不够分,vxlan 一个是扩展vlan 数 另外是建立l2over l3问题 还设计 unicast muticast mapping 问题 到了multicast 这个模型类似 mvpn了

Q11:Beyond myself
还有就是为每个端口配置规则下发流表的时候,ovsdb api里面有支持检测arp欺骗流表吗,如果想配置这样的流表,我们该如何着手,或者自己写这样的代码

关于ARP欺骗这些,也有很多做攻防的利用SDN方式解决,应该也是通过流表来实现。这方面我没有了解过。

-----------------------------------------------------------------------------------------------------
OpenDayLight SDNLAB研究群(群号:194240432)定位为面向SDN/ODL相关技术的初学者进行交流、学习、分享,吸引了来自高校、云服务提供商、互联网厂商、设备厂商、运营商等单位的从业人员近千人,每周会组织定向的技术及业界动态分享,如果你有需要分享的请加Q:117511567联系。

时间: 2024-10-13 00:06:43

SDNLAB技术分享(四):利用ODL下发流表创建VxLAN网络的相关文章

Floodlight下发流表过程分析

转载请注明出处:http://blog.csdn.net/vonzhoufz/article/details/32166445 当一个packet到达openflow交换机,会进行流表的匹配,如果没有找到相应的流表项,就会发送一个packet_in消息 到达SDN controller端,控制器根据一定的路由算法决策后,会向该路径上的所有交换机下发流表(也就是发送FLOW_MOD消息,里面有对应的action).这里要知道的是在SDN的环境下,控制器具有全局拓扑信息,每当有链路状态改变时就会跟新

sdn下发流表

1.首先我创建了简单的拓扑,深度为2,扇面为2. 1 1 mn --controller remote --topo tree,fanout=3,depth=2 2.使用 1 net 来查看网络的连接情况.如下所示: 3. 1 dpctl dump-flows 1 该命令可以用来查看所有节点的信息. 但是还有一种看个别交换机的流表信息. 1 sh ovs-ofctl dump-flows s1 4. 1 xterm s1 可以打开一个黑色框框,一个小终端吧. 5.刚打开的拓扑,actions字段

SDNLAB技术分享(二):从Toaster示例初探ODL MD-SAL架构

本文系OpenDayLight SDNLAB研究群(群号:194240432)分享整理而成,分享者魏静波通过对ODL wiki上的toaster例子进行深入浅出的细致讲解形象的描述了ODL MD-SAL的开发架构原理. 文章内容过多,详情点击查看原网页:http://www.sdnlab.com/13972.html

ryu的RESTAPI简介——我主要用于下发和查看流表

一.Rest API简介 REST即表述性状态传递(RepreSentational State Transfer),是一种针对网络应用的设计和开发方式,可以降低开发的复杂性,提高系统的可伸缩性. 表述性状态转移是一组构架约束条件和原则,满足这些约束和原则的应用程序或设计就是RESTful,REST是设计风格而不是标准,它通常基于使用HTTP,URI,XML以及HTML这些现有的广泛流行的协议和标准. REST定义了一组体系构架原则,可以根据这些原则设计以系统资源为中心的Web服务,包括使用不同

Openflow流表应用测试--逻辑隔离

1.搭建拓扑 搭建了三层的二叉树结构网络,开启SimpleSwitch3.py无法完成pingall联通测试,于是将拓扑结构更改为简单的line,四个交换机(OF13)连成一线,每个交换机下挂两个主机,依次h1--h8 s1 = net.addSwitch('s1', cls=OVSKernelSwitch, protocols='OpenFlow13', mac='00:00:00:00:00:11')    s2 = net.addSwitch('s2', cls=OVSKernelSwit

Open vSwitch流表应用实战

写在前面 本随笔参考 学会了如何下发流表及删除流表的操作. 第一个不用脚本的实验. 实验原理 在SDN环境下,当交换机收到一个数据包并且交换机中没有与该数据包匹配的流表项时,交换机将此数据包发送给控制器,由控制器决策数据包如何处理. 控制器下发决策后,交换机根据控制器下发的信息来进行数据包的处理,即转发或者丢弃该数据包.我们可以通过对流表操作来控制交换机的转发行为. 实验任务 Mininet创建一个默认树形拓扑. 选择Mininet的控制器指定为ODL,进行基本的添加.删除流表操作,使网络实现网

openflow流表项中有关ip掩码的匹配的问题(控制器为ryu)

一.写在前面 唉,被分配到sdn安全方向,顶不住,顶不住,感觉搞不出来什么有搞头的东西.可若是让我水水的应付,我想我也是做不到的,世上无难事只怕有心人.好了,进入正题,本次要讨论的时一个比较细节的东西,在流表项中的有关ip掩码的问题.对了,本文适合于,有一定基础的openflow使用者,一点点就行. 二.问题描述 若不是机缘巧合,我甚至完全不会注意到这个问题,为什么,咱来看一个平时实验环境中最为常见的流表项长啥样,如图1                                      

OpenvSwitch 流表转换

推荐看一下这篇文章,讲述了各个流表,我们这里着重讲流程和代码,对流表不再细说. 我们主要的关注点还是OVS-DPDK的流表转换,其实和OVS的转换差不多,只不过OVS的Datapath流表位于kernel,报文在Datapath找不到流表即通过netlink上传到Userspace,而OVS-DPDK则是Datapath流表依然位于Userspace,可以看做是一个缓存.查找不到的话直接继续调用其他接口查找Userspace的流表. controller会根据网络情况给ovs下发流表,或者命令o

【技术分享会】谈谈公司内部的技术分享

这段时间,为了促进程序同事间技术氛围,在公司内部组织开展技术分享会.形式很简单,每周进行一次技术分享:分享人由组员顺序安排:题材不限,可以是自己熟悉的技术,比如说服务端的开发者,分享后端定时器,消息队列等等,前端的开发者分享加载的模式,MVC模式等等,可以是一些通用的技术,比如数据结构,算法,代码风格,Effective 系列,调试技巧等,甚至可以是经典书的读后感等等,抑或是最近大家在研究一个开源的项目,也可以跟大家讲一下这个开源项目的框架:或许有些人利用业余时间做了一个小软件,也可以拿出来分享