mininet 入门引导

Mininet 使用攻略

本演练演示了大多数的mininet命令以及与wireshark揭破起一起使用的典型用法。
演练将假设您的基本系统是mininet VM,或安装了所有Open Flow工具和mininet的Ubuntu系统

注意:如果您使用的是UbuntuMininet2.0.0d4软件包,他会使用稍微不同的语法Topo() - 如:
add_switch_ 和addSwitch,等待。如果你检查Mininet源码,你可能希望看2.0.0d4 标签去看代码。

1. 日常mininet用法

关于在命令中的注释语法:

  • $ 代表shell下键入linux命令
  • mininet> 应该是Mininet的CLI中输入Mininet命令
  • 在root shell下键入的Linux命令
    在每种情况下,只需要在右侧键入命令,然后键入Enter。

显示启动项

键入以下命令显示Mininet启动选项帮助信息:

$ sudo mn -h

Start wireshark

使用OpenFlow Wireshark 解剖器查看控制流量,请现在后台打开wireshark:

sudo wireshark &

在Wireshark界面的filter框中,输入这个过滤规则,然后单击apply:

of

单击菜单栏中Capture,单击interfaces选项,然后选择 loopback(lo)接口。
现在,wireshark已经开始抓包,但是没有Openflow数据包展示在主界面。

注意:wireshark 是Mininet VM 镜像自动安装的,如果你使用的系统没有安装Wireshark和OpenFlow扩展,你可以使用Mininet的 install.sh 脚本来按照以下命令安装:

	cd ~ 
	git clone https://github.com/mininet/miniet # if it's not already there
	mininet/util/install.sh -w

如果Wireshark已经安装了,但是你仍然不能运行它(例如 发生了异常,如 ’$DISPLAY not set’,请咨询FAQ:https://github.com/mininet/mininet/wiki/FAQ#wiki-x11-forwarding)
设置X11 立刻启用将会允许你运行其他GUI程序和我们之后会用到的xterm终端仿真器。

主机和交换机交互

$ sudo mn

默认的拓扑图是最小的拓扑图,包含一个OpenFlow 核心交换机简洁之两个主机,扩展OpenFlow 控制器。使用--topo==minimal命令可以在命令行查看这个拓扑的具体说明。其他拓扑也可以从盒子中获得;详细信息请通过mn -h 查看 --topo 的详细内容。

这四个实体(两个主机进程,一个交换机进程,一个基础控制器)已经运行在虚拟机中,这个控制器可以在虚拟机外部,并且知道底部设备。
如果没有制定的测试被作为参数发送,Mininet CLI 将会出现。
在wireshark 窗口,你应该看到颗心交换机连接到了依赖的控制器。
展示Mininet CLI命令:

mininet> help

展示节点

mininet> nodes

展示连接

mininet> net

转储所有节点信息

mininet> dump

你将会看到交换机和两个主机被列举出来。
如果在Mininet CLI中输出的第一个字符串是主机、交换机或者控制器的名字,命令在这个节点被执行。运行一个命令在主机进程:

mininet> h1 ifconfig -a

你应该看到主机的 h1-eth0 和loopback(lo)接口。注意h1-eth-接口不能够被看到在出事的linux系统当ifconfig被运行时,因为它决定于主机进程的网络命名空间。
相反,默认情况下,交换机在跟 root 网络命名空间中运行,因此运行一个命令在“交换机”中,类似于运行它同常规终端:

mininet> s1 ifconfig -a

这将会展示交换机接口,扩展虚拟机的连接(eth0)。
其他的强调网络主机已经隔离网络状态的示例,需要同时运行arp和route在s1和h1上。

这将可能安置每一个主机、交换机和控制器在它自己的网络隔离命名空间,但是这是没有真实网络条件去这样做,除非你希望复制一个复杂的多控制器网络。mininet支持这样做,查看 ‘--innamespace’选项。

注意:这仅仅是网络虚拟化,每个主机进程有相同的进程集合和目录。例如,从一个主机进程打印进程列表:

mininet> h1 ps -a

者应该和root network 命名空间完全相同:

mininet> s1 ps -a

这可能在linux容器中使用独立的进程空间,但是当前的Mininet 不会这样做。将所有事都运行在root进程命名空间是方便于测试,因为这允许你从命令行中通过ps、kill等命令查看所有的进程。

测试两台主机之间的连通性。

现在将要证实你能够从host0 ping通 host1:

mininet> h1 ping -c 1 h2

如果一个带有节点名的字符串之后在命令行中出现,节点名将会被替换为其ip地址;这发生在h2上。

你应该看到OpenFlow 控制流量,第一个主机ARP用于寻找第二个主机的mac地址,造成了一个packet_in信息进入了控制器,控制器之后发送了packet_out信息泛洪(洪水广播包)到交换机的其他接口(在这个例子中,只有其他的数据端口)。第二台主机看到了ARP请求并且大宋了一个响应。这个响应进入了控制器,然后发送到了第一个主机并且执行下一个流表(flow entry)。
现在,第一个主机知道了第二个主机的mac地址,可以发送他的ping 通过ICMP相应请求。这个请求,伴随着来自第二台主机的相应地响应,都进入了控制器,并且最终进入了下一个流表(result in a flow entry pushed down)(伴随着实际的包发送出去)。
重复请求ping:

mininet> h1 ping -c 1 h2

你会看到,第二次ping的时间是远小于第一次(<100us)。一个预装在交换机中的流表覆盖了ICMP ping流量,所以没有控制流量生成,数据包迅速通过交换机。

一个更简单的方法去运行测试是使用mininet CLI 内置的pingall 命令,这个命令会执行所有成对机器的ping:

mininet> pingall

运行一个简单的web服务和客户端

记住,ping并不是唯一一个你可以运行在主机上的命令!mininet主机可与运行任何底层linux系统(或者虚拟机)和他的文件系统支持的命令或者应用程序。你亦可以加入任何的 bash 命令,包括任务控制(&,jobs,kill,等)

接下来,尝试在h1上启动一个简单的HTTP 服务,在h2上发出请求,之后关闭web服务:

	mininet> h1 python -m SimpleHTTPServer 80 &
	mininet> h2 wget -O - h1
	...
	h1 kill %python

退出CLI

mininet> exit

清理

如果Mininet由于某些原因出了问题,清理它:

$sudo mn -c

高级启动选项

Run a Regression Test

你不需要进入CLI;mininet也可以被用于运行独立回归测试。
运行回归测试:

sudo mn --test pingpair

这个命令创建了一个最小的拓扑,启动了OpenFlow饮用控制,运行了一个全对ping的测试,并且卸下拓扑和控制器(关闭拓扑和控制器)。

另一个有用的测试是iperf(大概10秒完成)

sudo mn --test iperf

这个命令创建了一个相同的mininet,在新创建的主机上运行一个iperf 客户端,并且测试了网络。

改变拓扑大小和类型

默认的拓扑时简单的交换机连接着两个主机,你可以使用 --topo、通过这些技术的创建参数将其转变成不同的拓扑。例如,使用一个交换机和三个主机,证实all-pairs ping 连通:
运行一个回归测试:

$ sudo mn --test pingall --topo single,3

再例如,使用线性拓扑(每个交换机有一个主机,所有的交换机连接在一个线上):

$ sudo mn --test pingall --topo linear,4

参数化拓扑时mininet最有用和强大的特征。

mininet 2.0允许你设置连接参数。使用一下命令,参数甚至可以被自动设置

	$ sudo mn --link tc,bw=10,delay=10ms
	mininet > iperf
	...
	mininet > h1 ping -c10 h2

如果每个连接推迟10ms,一个回路时间(RTT, round trip time)应该推迟40ms,从ICMP请求经过两条路(一个到交换机,一个到目的主机),并且ICMP回复经过两条路在回来。

你可以通过Mininet’s python API 自定义每个连接,但是现在你需要继续这个教程。

可调节的输出长度

输出部分详细情况,显示了mininet在启动和关闭过程中干了什么。共有6个等级(info,warning,critical,error,debug,output)。我们可以使用 -v 变量 的形式进行修改 。默认的冗余等级是 info

  • 尝试使用 debug 查看其缺失的详细信息。
	$ sudo mn -v debug
  • 尝试使用output设置显示CLI输出:
	$sudo mn -v output
	mininet> exit

在CLI外,其他打印等级也可以被使用,例如 warning 就是使用回归测试隐藏不需要的函数输出。

自定义拓扑

自定义拓扑可以很轻松的使用简单的python API完成。custom/topo-2sw-2host.py 就是一个例子。这个例子完成了两个交换机直接连接、每个交换机连接有一台主机。

	"""
	注意⚠️,由于兼容问题,尽量不要打中文。
	topo-2sw-2host.py
	python
	两个直接连接的交换机,每个交换机上连接一个主机
	host --- switch --- switch ---host
	以键值对的方式加入到'topos'字典,生成我们全新定义的拓扑,允许从命令行通过’--topo=mytopo‘进入
	"""
	from minnet.topo import Topo
	class MyTopo(Topo):
	"Simple topology example."
	def __init__(self):
			"构造函数,创建自定义拓扑"
			#initialize topology
			Topo.__init__(self)
			
			#增加主机和交换机
			leftHost = self.addHost('h1')
			rightHost = self.addHost('h2')
			leftSwitch = self.addSwitch('s3')
			rightSwitch = self.addSwitch('s4')
			
			# 增加连接
			self.addLink(leftHost, leftSwitch)
			self.addLink(leftSwitch, rightSwitch)
			self.addLink(rightSwitch, rightHost)	
	
	topos = {'mytopo':(lamabda:MyTopo())}

当提供自定的mininet文件,它可以增加一个新的拓扑、交换机类型和命令行测试。如:

	$ sudo mn --custom ~/mininet/custom/topo-2sw-2host.py --topo mytopo --test pingall

ID = MAC

主机每次开机都有随机分配的MAC地址。这可能导致调试困难,因为每次mininet被创建,Mac地址就该拜年。所以将流量控制和和特定的主机相关联是比较困难的。
--mac选项是极其有效的,设置主机MAC和ip地址设施的小巧、更容易读的ID。
使用--mac之前:

	mininet> h1 ifconfig
	h1-eth0   Link encap:Ethernet  HWaddr 36:53:96:85:7a:7f  
	          inet addr:10.0.0.1  Bcast:10.255.255.255  Mask:255.0.0.0
	          UP BROADCAST RUNNING MULTICAST  MTU:1500  Metric:1
	          RX packets:0 errors:0 dropped:0 overruns:0 frame:0
	          TX packets:0 errors:0 dropped:0 overruns:0 carrier:0
	          collisions:0 txqueuelen:1000 
	          RX bytes:0 (0.0 B)  TX bytes:0 (0.0 B)

使用后:

	mininet> h1 ifconfig
	h1-eth0   Link encap:Ethernet  HWaddr 00:00:00:00:00:01  
	          inet addr:10.0.0.1  Bcast:10.255.255.255  Mask:255.0.0.0
	          UP BROADCAST RUNNING MULTICAST  MTU:1500  Metric:1
	          RX packets:0 errors:0 dropped:0 overruns:0 frame:0
	          TX packets:0 errors:0 dropped:0 overruns:0 carrier:0
	          collisions:0 txqueuelen:1000 
	          RX bytes:0 (0.0 B)  TX bytes:0 (0.0 B)

相比之下,交换机数据端口的mac地址变化是linux随机赋值的。你可以使用OpenFlow分配一个mac地址给数据端口。这里有些你现在可以忽略不计的微妙的点。

XTerm Display

更多复杂的测试,你可以启动mininet并且拥有多个一个或者多个窗口。
通过-x为每个主机和交换机启动xterm:

	$ sudo mn -x

稍等一下,xterms就会弹出,并且自动设置窗口名称。
或者你也可以调取xterm如下所示:
默认情况下,只有主机被放入单独的命名空间,每个交换机的窗口是不必要的(也就是说,相当于常规终端),但是可以是一个方便的地方去运行,剩下交换机调试命令,就像流量计数转储。
Xterms 也用于运行你可能会取消的、仅仅只想看输出的交互命令。
以下事例在自己做实验时不可运行。narkive 上的资料 显示,dpctl属于OpenFlow老旧的命令。但是网上也有资料显示可以执行,如dpctl 命令实践-heimafeitian官方对于dpctl无法执行问题解答。
例如:
在标签为“switch:s1(root)” xterm窗口中运行:

	dpctl dump-flows tcp:127.0.0.1:6634

什么都不会显示;交换机没有流量流入。要和其他交换机一起用使用dpctl,启动冗余模式的mininet,当交换机被创建时查看他们的监听端口。
现在,在标签为host:h1的xterm窗口中运行:

	ping 10.0.0.2

返回到s1并且转储流: # dpctl dump-flows tcp:127.0.0.1:6634 
你会看到多个流量流入。或者(一般情况下更方便),你可以看到dpctl冰凌构建进入了mininet CLI 而不需要任何xterm窗口或者特殊方法的交换机的Ip和端口。
你可以通过检查ifconfig判断xterm是否在root命名空间下;如果所有的接口都显示(包括eth0),这是在root命名空间的。另外,其标题应该包含“(root)”。
从mininetCLI中关闭设置:

	mininet> exit

这些xterm窗口应该自动关闭
如果以上实验可能无法完成。使用 ovs-ofctl show s1 也能达到类似效果
tip: ovs-ofctl、ovs-dpctl和dpctl的区别

  • ovs-ofctl :在所有的OpenFlow交换机上(不仅仅是OpenFlow vSwitch,而是任意OpenFlow switch)
  • ovs-dpctl:工作于linux 内核 数据通路上。
  • dpctl 是一个从OpenFlow参考实现的古董,它包含了部分ovs-ofctl 和 ova-dpctl it includes aspects of ovs-ofctl and ovs-dpctl.

官方对于dpctl无法使用的解决方案:

dpctl应该可以在斯坦福 OpenFlow参考时限或CPqD相同版本中正常使用。
但是你可能不想用dpctl,而是全部替换为ovs-ofctl。ovs-ofctl在安装和在OVS中使用时非常方便的,重要的是,会真的转出完整的流表(不像ovs-dpctl)
如果你想运行Open v S为 i 推出,或者需要开放在OVS或者参考交换机上打开监听端口以便于你可以连接进入该端口,请继续阅读:
1.如果你想要使用Open vSwitch,shell提示符中正确的命令是:

	$ sudo ovs-ofctl dump-flows s1

(如果你尝试在Open vSwitch上使用ovs-dpctl,你只能看到在内核中的缓存流,而不是交换机中所有的流表)
2. 在mininet提示符中正确的命令是:

	mininet> dpctl dump-flows

转储所有交换机的数据流,支持OVS 和部分涉及的交换机。
如果你运行的是OVS,你可以使用ovs-ofctl命令,传入交换机名字,通过文件系统进行连接到它:

	mininet> sh ovs-ofctl dump-flows s1

或者,从shell提示符:

	$ ovs-ofctl dump-flows s1
  1. 如果要在交换机上打开侦听端口,你需要指定基本的监听端口
	net = Mininet(topo=topo, listenPort=6634 )

端口将会从你指定的值开始分配。
注意,如果你想要去转储流,则需要打开一个侦听端口;然后你就可以使用dpctl:

	$ dpctl dump-flows tcp:localhost:6634

注意ova-ofctl不能使用localhost,而应该使用127.0.0.1:

	$ ovs-ofctl dump-flows tcp:127.0.0.1:6634

其他的交换类型

可以使用其他交换类型。例如,运行user-space交换机

	$ sudo mn --switch user --test iperf

注意,相对之前使用内科的交换机,TCP iperf-reported 宽带会低得多。
如果你之前做了ping测试显示,你应该注意到高延迟,从现在数据包包必须经历额外的内核到用户空间的转换。ping时间将会更加可变,表示主机的用户空间进程可以由系统调度进出。
另一方面,用户空间交换机可能是实现新功能一个很好的起点。尤其是软件性能要求不高时。

另一个交换机类型的例子是Open vSwitch(OVS),这个交换机是预装在Mininet虚拟机上的。Iperf-reported TCP 带宽类似于OpenFlow核心模块,也可能更快:

	$ sudo mn --switch ovsk --test iperf

mininet 基准

使用--test none记录启动和关闭拓扑的时间:

	$ sudo mn --test none

所有信息都在自己的命名空间(仅限用户交换机)

默认的,主机放在他们自己的命名空间,而交换机和控制器是在root命名空间。为了将交换机放入自己的命名空间,我们需要使用--innamespace 选项:

	$ sudo mn --innamespace --switch user

替代使用loopback,交换机将通过单独的控制桥连接与控制器对话。就其本身而言,这个选项不是十分有用,但是它提供了一个隔离不同交换机的方法。
注意,截止至2012年11月19日,此选项仍不可在Open vSwitch上使用。

part3 :mininet 命令行接口(CLI,Command-Line interface) 命令

为了查看CLI选项列表,请先启动一个最小的拓扑并使他运行。建立mininet:

	$ sudo mn

显示选项:

	mininet> help

python解释器:

如果第一个mininet 命令行中,第一个短语是py,之后这个命令是用Python执行的。这对扩展mininet和谈妥起内部工作方式是很有用的。每个主机、交换机和控制器都有关联节点对象。
在Mininet CLI中运行:

	mininet> py 'hello ' + 'world'

打印可访问的本地变量:

	mininet> py locals()

然后,查看变量拥有的方法和属性,使用dir()函数:

	mininet> py dir(s1)

你可以通过使用help()方法阅读在线文档,获取每个节点可以调用的方法:

	mininet> py help(h1)(press "q" to quit reading the documentation)

你也可以查询变量的方法:

	mininet> py h1.IP()

link UP/Down(接通/断开)

为了容错测试,建立/断开连接可能是有帮助的。
断开虚拟网络的两半:

mininet\> link s1 h1 down

你应该看到一个OpenFlow 端口状态更改通知被生成。再将其调整为连接状态:

	mininet> link s1 h1 up

XTerm 展示

展示h1和h2的XTerm窗口:

	mininet> xterm h1 h2

第四部分:Python API 示例

源码中包含的示例目录包含了如何使用Mininet‘s python API的例子,以及暂时没有合并到住代码的潜在有用的代码。
注意:如开头所述,本演练假定您使用的是Mininet VM,其中包含您所需要的所有内容,或者是用饱含所有相关工具的本地安装。包括OpenFlow 参考实现的一部分—引用控制器controller。如果您还没有安装,可以使用install.sh -f 安装。
每个主机的SSH守护程序:
一个可能特别有用的例子,在每台主机上运行一个SSH守护程序

	$ sudo ~/mininet/examples/sshd.py

从另一个终端,你可以ssh到任何主机并且运行交互式命令:

	$ ssh 10.0.0.1
	$ ping 10.0.0.2

推出SSH示例mininet:

	$ exit

在你阅读完了mininet 介绍 关于Python API的介绍后,你可能希望重访这个例子。

第五部分:引导完成

恭喜,你已经完成mininet引导。请自由尝试新的拓扑和控制器,或者查看源码吧。

下一步掌握mininet

如果你还没有完成,你应该继续阅读 OpenFlow 教程
虽然使用Mininet CLI 是很明智的,但是当你掌握了Python API后,mininet 会更有用。mininet介绍 提供了Mininet和Python API的介绍。
如果你想知道如何使用远程控制控制器(比如一个运行在外部的),我们将会在接下来的部分解释。

附录:补充资料

这些不是必要的知识,但是你会发现者很有用。

使用远程控制器

注意,这一步不是默认的引导之一;主要用于在虚拟机外运行着一个控制器,例如在VM主机,或者一个单独的PC。OPenFlow tutorial 使用 controller --remote 启动一个您使用一个控制器框架,如POX,NOX,Beacon 或者Floodlight 创建的简单学习交换机,。
当你启动mininet网络,每个交互那集可以连接到一个远程控制器-可以在虚拟机、不在虚拟机而是你的主机、或者是世界上任意的地方。
这个安装可能是方便的,如果你已经有一个自定义版本的控制器框架和开发工具安装在你本地机器上,或者你想要测试一个控制器运行在不同的物理机器上(甚至可以运行在云上)。
如果你想要试试,填写主机IP 和/或 监听端口:

	$sudo mn controller=remote,ip=[controller IP],port=[controller listening port]

例如,运行一个POX框架的简单学习交换机,你可以这样做:

	$ cd ~/pox
	$ ./pox.py forwarding.12_learning

在这个窗口,同时在另一个窗口启动mininet并且连接远程交换机(实际上是本地运行,但是实在mininet控制之外)

	$ sudo mn --controller=remote,ip=127.0.0.1,port=6633

注意,者实际上是默认Ip地址和端口信息
如果你生成了一些流量(如:h1 ping h2)你应该能够观察到一些在POX窗口观察到一些输出,交换机已经连接并且流表像已经被安装。
很多OpenFlow 控制器框架都是现成,只要启动他们,指定远程控制器选项、填入正确的控制器运行机器Ip地址和舰艇端口,就可以轻松的和mininet一起工作。

NOX classic

mininet默认安装(使用util/install.sh -a)不会安装NOX Classic。如果你想要安装他,运行sudo ~/mininet/util/install.sh -x
注意,NOX Classic 已经被弃用,将来可能不受支持。
用Nox运行Nox app pyswitch运行回归测试,NOX_CORE_DIR环境变量必须被设置包含Nox可执行命令的目录。
首先,运行Nox:

	cd $NOX_CORE_DIR
	$ ./nox_core -v -i ptcp:

ctrl-C 结束Nox进程,然后运行一个带有Nox pyswitch 的测试:

	$ cd 
	$ sudo -E mn --controller=nox,pyswitch --test pingpair

注意,—controller选项有一个方便的语法为了指定控制器类型选项(在本例中,nox运行pyswitch)。

当Nox读取和交换机连接时,需要等待几秒,但是之后他应该可以完成ping操作。
注意,这是,我们通过sudo -E 调用mn,为了保证NOX_CORE_DIR 环境变量。如果你是运行nox 远程交换机,使用--controller remote,之后的-E选项不再是必要的。相应的,你可以通过sudo visudo改变/etc/sudoers文件第一行,将env_reset变为:

	Defaults ~env_reset

这样,运行sudo 的环境变量设知识就不会改变。

文中引用:
mininet walkthrough
mininet introduction GitHub
dpctl报错问题: Error encountered on issuing dpctl to dump-flows
dpctl 命令实践

posted @ 2019-04-06 10:56  wgh0807  阅读(4433)  评论(0编辑  收藏  举报