mininet拓扑搭建

基于python脚本的拓扑搭建
Mininet这个网络仿真软件支持使用python脚本建立拓扑,我们只需要预先写好存储拓扑信息的文件和拓扑建立逻辑(这是两个文件)就可以一键运行,在拓扑规模大、链路数量多的情况下(实验用的拓扑就挺大)能极大提高仿真效率,且不容易出现错误搭建拓扑的情况(比如少拉了一根线,拉错了一根线之类的)。
拓扑搭建逻辑
mininet自带有一个拓扑搭建脚本,我们先来看一下拓扑搭建逻辑。
你可以在上图红色框线所示的文件路径找到系统里的拓扑搭建脚本,里面的代码就只有一页这么多(才34行,简单得不能再简单了)。
- 绿色框线里的内容是这个 python 脚本成功运行需要的一些库,一般不需要改动(当然了,如果你想给这个脚本增加一些新功能,相应的库也要加进来,比如让他能读取json文件,就需要添加读取json文件需要的库,具体是什么,可以自行搜索~)。
- 橙色框线的第一行代码读取拓扑信息,注意,此处读取的路径使用了相对路径(./表示当前脚本文件所在的路径),使用绝对路径也是可以的,第15行代码读取拓扑信息文件的第一行,即下图的第一行。下图的第一行数据分别表示这个拓扑里的主机数量(3)和交换机数量(7)
- 有了这两个信息,上图的紫色框线开始向 mininet 网络中添加主机(line18)和交换机(line21),然后上图的程序继续读取拓扑文件的其他行,用于添加设备之间的链路(上图蓝色框线部分)。
- 最后,上图白色框线的部分相当于为这个脚本创建的网络起了一个名字,你可以做定制化的改动,比如改成你自己的名字,但是一定要记住自己改成了什么,后面实际运行时需要用到。
接下来,我们看看拓扑信息文件到底存了什么。你可以在上图中红色框线所示的路径下(其实就是拓扑搭建脚本所在的路径)找到存储拓扑信息的文件(topoinfo.txt)。打开以后其实也就14行,第一行的意思刚刚已经解释过了,仔细观察,你会发现,之后的每一行都对应了要搭建的拓扑里面的一条边。这并不是实验要用的那个拓扑的信息,而是下图所示的拓扑。到这里,我们可以回到第一幅图的蓝色框线部分了,是不是能理解这部分代码在干什么了。
json文件描述拓扑
这一部分,还有一点补充,第二幅图的文件用最简单的文件格式(实际就是txt)去描述了一个网络的拓扑信息,但并不一定最好用,例如当网络拓扑比较大,且需要给链路附加诸如时延和带宽等属性的时候,文件解析(解析就是指从文件中去找想要的某些信息)起来不太方便,比如DFS、Dijkstra需要获取拓扑中链路的时延属性,最大流需要获取链路的带宽,有时候需要全部链路的这些信息,有时候又只需要某条链路的信息,那从这种txt中去找相关信息就比较麻烦。万幸的是,不论是拓扑搭建脚本、还是ryu控制器的控制逻辑,都是用python写的,python是可以通过调库将json文件读取成字典的(如果你还不知道python字典是什么,自觉去面壁10分钟),到这,你悟了吗?
运行拓扑
现在我们正式开始运行用户自定义的脚本(革命快要成功了,再坚持一下),上图中橙色框线里橙色横线处的代码表示要自定义脚本,其后紧跟的就是我们拓扑建立逻辑的脚本文件(严格讲应该是脚本文件所在的路径再加文件名,只是这里执行该命令的位置就是文件所在的目录),绿色框线里的内容就相当于这个建立的拓扑叫什么名字了,还记得最开始的图里里白色框线里的东西吗,就是那个玩意儿,蓝色框线的命令告诉mininet这个软件,我这个建起来的拓扑需要连接到一个远程的控制器,这个控制器的ip是127.0.0.1,端口号是6653(openflow协议的默认端口号),最后紫色框线的配置告诉mininet:你给我按照添加主机的顺序,从00:00:00:00:00:01开始依次分配物理地址(注意物理地址用的是十六进制,00:00:00:00:00:10不是10而是16,切记,切记),如果你不加这条命令,每个添加的主机的mac地址就是随机分配的,没有规律(在之前给的b站上的视频里面,作者也提到过这个)。输入密码后,Mininet就开始建立拓扑了,黄色框线内显示了mininet建立拓扑的过程,先添加了三个主机、然后是7个交换机、最后是13条边(注意是双向边)。
Mininet的命令状态下输入exit(图5红色框线)会退出,节点和链路都依次停止,蓝色框线里显示mininet停止了多少条链路。
这里还要注意一个问题,对mininet来说,一共增加了13条双向边,其中有三条是主机和交换机之间的链路,剩余10条才是交换机和交换机之间的边,对控制器来说,他只能观测到交换机和交换机之间的边(也就是他能获取到20条边,因为这里的10条边是双向边,所以ryu控制器按两个方向各存一条),而看不到主机和交换机之间的边,原因在于控制器发现拓扑用的是LLDP协议,且控制器控制的是交换机,只有交换机会向控制器请求指示,而在LLDP链路发现过程中发送到主机的测试包会被主机直接丢掉,不存在主机也将这个数据包向上发给控制器的可能,所以LLDP检测不到主机和交换机之间的链路。)
还有一个问题需要解释,你可能都没发现这个问题:图3中交换机的端口号是怎么确定的?Mininet在给设备端口分配编号的时候也是从1开始(不同设备之间的端口编号是独立的),按照设备接口上连接链路的顺序,依次编号。举个栗子:按照图2的拓扑文件,与交换机1有关的链路的添加顺序是h1-s1、s1-s2、s1-s4,所以s1相对应的端口也就被分别编号1、2、3。也就是说,这个端口编号在你给定了拓扑信息和搭建拓扑的脚本逻辑的时候,命运已定。
至此,拓扑搭建的所有内容已经介绍完了,回过头来再看,建立一个拓扑的信息文本其实要比搭建拓扑的逻辑脚本麻烦的多,毕竟后者就几个for的事,前者那可真是实打实地要一条条加呀,就拿之前给的那个24个节点地拓扑来说,交换机到交换机的边有43条(ryu控制器的get_link()拉取的信息中包含的链路数量翻倍),主机到交换机的边有24条,合起来67条(你可以用我上面介绍的办法看看他是不是真的是67条),这你要是拿miniedit拉可得拉多久,想想就头秃。
实验拓扑
为了防止你头秃,这里破例提供两个已建好的拓扑信息的json文件(注意,前面讲解的拓扑搭建代码不能直接处理json文件,你还需要做出相应的调整),如果你愿意,可以直接用我提供的json文件去实现后续的逻辑。
1 | { |
上面代码中一共7个交换机,拓扑图如下,每个交换机下挂一个主机,图中只画出一个主机(h3),但你需要知道还有6个主机并没有画出来,主机和交换机之间的链路属性都按图6中的蓝色数值进行了设置,交换机之间的链路属性也按图中标注进行了设置。
所有链路的排列顺序(正常来说就是后面搭建拓扑的脚本添加链路的顺序,也就是说)如下:首先是主机和交换机之间的链路,按主机编号增序添加;然后是交换机和交换机之间的链路,按交换机编号增序依次添加交换机的所有邻居链路,对邻居的要求是其编号比自己的大,在满足这个条件的邻居里,先添加邻居编号小的链路(这里用文字描述有点绕,没看明白的话多看几次)。按这个规则形成的拓扑中,交换机的各个接口编号以较小的红色数字标注在了对应位置。
类似的,下面给定实验拓扑,只是相比上图,下图追加了按这个文件建立的拓扑的交换机接口编号信息。代码中链路的顺序规则同上。
1 | { |