文章目录
- Mininet教程(七)Mininet Walkthrough
- 日常使用指令
- 显示mininet开启选项
- 开启Wireshark
- 主机与路由器之间交互
- 测试主机之间连通性
- 运行一个简单的web服务器和客户端
- 清理缓存
- 高级命令
- 运行回归测试
- 改变拓扑大小和类型
- 链路修改
- 调整输出
- 自定义拓扑
- ID=MAC
- XTerm显示
- 其他交换机类型
- Mininet 基准测试
- 各自都有命名域(仅对用户态)
- Mininet命令行界面的命令
- 显示选项
- Python解释器
- 关闭\打开链路
- XTerm显示
- Python接口示例
-
- 下一步
- 补充说明
-
Mininet教程(七)Mininet Walkthrough
官网mininet walkthrough不完全翻译,原文
本教程展示了大部分mininet命令,以及和Wireshark的交互应用。
日常使用指令
显示mininet开启选项
$ sudo mn -h
开启Wireshark
为了通过Wireshark查看控制流,首先打开Wireshark
$ sudo wireshark
在Wireshark过滤器中,输入openflow"of",点击"Apply"。在Wireshark界面中,点击"Capture",然后"Interfaces",随后选择loopback接口"lo"。当前没有openflow的包显示在界面中。
Wireshark在Mininet虚拟镜像中默认安装的。如果你的系统没有Wireshark以及openflow插件,可以通过Mininet的安装脚本进行安装,命令如下:
$ cd ~
$ git clone https://github.com/mininet/mininet
$ mininet/util/install.sh -w
在运行Wireshark中遇到问题,譬如$DISPLAY not set,可以查看这里。
我个人Wireshark版本2.6.8,界面和上述稍有不同:点击"捕获",借口选择"Loopback:lo",过滤器输入"openflow_v1"。
主机与路由器之间交互
启动最小拓扑并进入命令行界面:
$ sudo mn
此时Wireshark窗口中,已经可以看到捕获的openflow包。
显示MIninet 命令行指令:
mininet> help
显示节点:
mininet> nodes
显示链路:
mininet> net
显示节点所有信息:
mininet> dump
如果命令行的第一个字符串是主机,交换机或者控制器的名字,那么后续的命令就是在该节点中执行。例如:
mininet> h1 ifconfig -a
便能看到主机的"h1-eth0"和"lo"接口。在早期Linux系统中,接口"h1-eth0"在执行ifconfig命令时不能被看到(网络命名空间从linux内核3.8开始支持)。相反的,交换机默认在根网络的命名空间内,因此执行switch的命令和跟平常终端结果一样:
mininet> s1 ifconfig -a
其他例子还有执行"arp"和"route"指令在"s1"和"h1"上。
为每个主机,交换机和控制器都设置一个独立的命名空间也是可以的,但这样没多大好处,除非是在一个复杂的多个控制器网络中。Mininet也支持这样,详情见–innamespace选项。
在Mininet中,只有网络是虚拟的,每个节点其实都有一样的进程和目录。譬如查看主机下的进程目录:
mininet> h1 ps -a
这和交换机下的进程是完全一样的(当然除了ps):
mininet> s1 ps -a
在Linux 容器中设置不同的进程空间也是可以的,但目前Mininet不这么做。将每个进程都置于主进程命名空间会使得调试比较方便,因为你可以看到所有的进程。
测试主机之间连通性
执行命令:
mininet> h1 ping -c 1 h2
在wireshark中抓包可以看到:
h1主机根据地址解析协议(ARP)分析h2的MAC地址,因为当前并不知道谁是h2,因此发送一个packet_in消息给控制器。控制器随后发送packet_out命令将这条指令广播泛洪向交换机的其他接口。当h2看到这条地址解析请求后会发送一个答复给控制器,控制器将它返回给h1并推送一个流表记录(flow entry)。当h1知道了h2的地址之后,就会通过一个报文控制协议(ICMP)的echo request来ping。这个echo request以及它的答复都会经过控制器并导致流表推送。
再次执行:
mininet> h1 ping -c 1 h2
这次用的ping时间更短。因为这次报文控制已经在上一次的ping中被推送到交换机了。所以这次不会有控制流产生,数据包直接经过交换机,速度更快。
一个更简单的方式实在命令行界面执行"pingall",测试所有主机对的通信:
mininet> pingall
运行一个简单的web服务器和客户端
Mininet的主机可以运行任何底层Linux系统/虚拟机以及文件系统支持的命令和应用。也可以运行任意的bash命令,包括任务控制的"&",“jobs”,"kill"等等。
接下来,在h1上启动一个简单的HTTP服务器,并从h2发送一个请求,最后关闭这个服务器。
mininet> h1 python -m SimpleHTTPServer 80 &
mininet> h2 wget -O - h1
mininet> h1 kill %python
退出命令行界面:
mininet> exit
清理缓存
如果Mininet因为某些原因崩溃了,可以清理:
$ sudo mn -c
高级命令
运行回归测试
有的时候不必进入命令行界面,Mininet也可以运行自带的回归测试:
$ sudo mn --test pingpair
该命令创建了一个最小拓扑,开启openflow控制器,对所有的主机对进行ping测试,最后删除拓扑和控制器。
另外一个常用的测试命令是"iperf"(大概需要10秒左右完成):
$ sudo mn --test iperf
这条命令同样创建了一个一样的Mininet环境,在一台主机上运行iperf服务器,另一台主机上运行iperf客户端,进行带宽解析。
改变拓扑大小和类型
默认的拓扑是一个交换机连接俩主机,可以通过"–topo"选项改变拓扑并设置不同参数。例如,生成一个一个交换机带三主机的拓扑并进行"pingall"回归测试:
sudo mn --test pingall --topo single,3
另一个例子线型拓扑,每个主机都有一个对应的交换机,所有交换机连成一条线:
sudo mn --test pingall --topo linear,4
参数化拓扑是Mininet一个非常实用和重要的特征。
链路修改
Mininet2.0允许设置链路参数,可以通过启动命令进行设置:
$ sudo mn --link tc,bw=10,delay=10ms
mininet> iperf
*** Iperf: testing TCP bandwidth between h1 and h2
*** Results: ['9.50 Mbits/sec', '12.0 Mbits/sec']
mininet> h1 ping -c10 h2
PING 10.0.0.2 (10.0.0.2) 56(84) bytes of data.
64 bytes from 10.0.0.2: icmp_seq=1 ttl=64 time=48.1 ms
64 bytes from 10.0.0.2: icmp_seq=2 ttl=64 time=40.8 ms
64 bytes from 10.0.0.2: icmp_seq=3 ttl=64 time=40.4 ms
64 bytes from 10.0.0.2: icmp_seq=4 ttl=64 time=40.2 ms
64 bytes from 10.0.0.2: icmp_seq=5 ttl=64 time=40.2 ms
64 bytes from 10.0.0.2: icmp_seq=6 ttl=64 time=40.1 ms
64 bytes from 10.0.0.2: icmp_seq=7 ttl=64 time=40.4 ms
64 bytes from 10.0.0.2: icmp_seq=8 ttl=64 time=40.3 ms
64 bytes from 10.0.0.2: icmp_seq=9 ttl=64 time=40.1 ms
64 bytes from 10.0.0.2: icmp_seq=10 ttl=64 time=40.3 ms
根据设置,单条链路延时10ms,那么ping测试里RTT大概40ms左右。这是因为ICMP请求要过两条链路(从h1到交换机,从交换机到h2),ICMP的答复也要过这两条链路。
更多的链路设置在这里。
调整输出
默认的信息输出等级是"info",输出Mininet在启动和关闭时的动作。和"debug"设置比较:
$ sudo mn -v debug
mininet> exit
"debug"设置会输出更多的细节信息。"output"设置可以直接输出命令行界面而没有中间的信息。
$ sudo mn -v output
mininet> exit
除此之外还可以设置"warning"等级,在回归测试时可以隐藏不需要的功能输出。
自定义拓扑
自定义拓扑可以使用提供的python借口,已有的一个例子在安装目录下custom/topo-2sw-2host.py中。调用自定义的拓扑并进行回归测试:
$ sudo mn --custom ~/mininet/custom/topo-2sw-2host.py --topo mytopo --test pingall
ID=MAC
默认主机分配的MAC地址都是随机的。每次开启Mininet,MAC地址都会改变,这使得调试以及相应的控制流都比较难进行。这时候"–mac"就非常有用了,它使得主机的MAC和IP地址简单易读且唯一。
设置前:
$ sudo mn
mininet> h1 ifconfig
h1-eth0: flags=4163<UP,BROADCAST,RUNNING,MULTICAST> mtu 1500
inet 10.0.0.1 netmask 255.0.0.0 broadcast 10.255.255.255
inet6 fe80::d4ba:1aff:fee2:fc7a prefixlen 64 scopeid 0x20<link>
ether d6:ba:1a:e2:fc:7a txqueuelen 1000 (Ethernet)
RX packets 11 bytes 942 (942.0 B)
RX errors 0 dropped 0 overruns 0 frame 0
TX packets 7 bytes 586 (586.0 B)
TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0
mininet> h2 ifconfig
h2-eth0: flags=4163<UP,BROADCAST,RUNNING,MULTICAST> mtu 1500
inet 10.0.0.2 netmask 255.0.0.0 broadcast 10.255.255.255
inet6 fe80::945d:f3ff:fe94:74be prefixlen 64 scopeid 0x20<link>
ether 96:5d:f3:94:74:be txqueuelen 1000 (Ethernet)
RX packets 14 bytes 1136 (1.1 KiB)
RX errors 0 dropped 0 overruns 0 frame 0
TX packets 8 bytes 656 (656.0 B)
TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0
设置后:
$ sudo mn --mac
mininet> h1 ifconfig
h1-eth0: flags=4163<UP,BROADCAST,RUNNING,MULTICAST> mtu 1500
inet 10.0.0.1 netmask 255.0.0.0 broadcast 10.255.255.255
inet6 fe80::200:ff:fe00:1 prefixlen 64 scopeid 0x20<link>
ether 00:00:00:00:00:01 txqueuelen 1000 (Ethernet)
RX packets 12 bytes 1052 (1.0 KiB)
RX errors 0 dropped 0 overruns 0 frame 0
TX packets 7 bytes 646 (646.0 B)
TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0
mininet> h2 ifconfig
h2-eth0: flags=4163<UP,BROADCAST,RUNNING,MULTICAST> mtu 1500
inet 10.0.0.2 netmask 255.0.0.0 broadcast 10.255.255.255
inet6 fe80::200:ff:fe00:2 prefixlen 64 scopeid 0x20<link>
ether 00:00:00:00:00:02 txqueuelen 1000 (Ethernet)
RX packets 15 bytes 1246 (1.2 KiB)
RX errors 0 dropped 0 overruns 0 frame 0
TX packets 9 bytes 786 (786.0 B)
TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0
相反的,交换机的MAC地址依然是系统随机分配的。这是因为你可以通过Openflow协议对数据端口分配MAC地址。
XTerm显示
对于更复杂的调试,可以在开启mininet时打开一个或多个XTerm,使用"-x"选项:
$ sudo mn -x
几秒种后,XTerm会弹出来,窗口名字已被自动生成。默认的,只有主机在不同的命名域里面,交换机的XTerm没太有必要(因为这和平常的终端一样),但这样执行调试命令的时候比较方便。
例如,在交换机s1"switch:s1(root)"里面执行:
$ dpctl dump-flows tcp:127.0.0.1:6634
这时并没有输出,数据流没有经过交换机。在主机h1中ping主机2:
$ ping 10.0.0.2
回到交换机s1再次监听端口,就会发现有多条数据流经过。另外一种方法是在Mininet的命令行界面中监听活动端口,这样更方便不用开启XTerm以及不用人工设定IP和端口。还可以在XTerm中通过ifconfig命令检测是否在根命名域中,如果显示所有的接口包括eth0,那么就是位于根命名域。另外,标题栏应该会包含root字样。
当在Mininet命令行中执行exit,XTerm也会自动退出。
6634是交换机默认的监听端口。可以通过ovs-vsctl命令查看监听端口passive listener-ptcp:
$ ovs-vsctl show
...
Bridge "s1"
...
COntroller "ptcp:6654"
...
其他交换机类型
使用用户态交换机:
$ sudo mn --switch user --test iperf
和内核态交换机相比,用户态的带宽要小很多。如果进行ping测试,会发现延时也要比内核态大。这是因为数据包要经过额外的内核到用户空间的转换。
另外一种交换机类型是Open vSwitch(OVS),TCP带宽和内核态相仿甚至略快一些:
$ sudo mn --switch ovsk --test iperf
Mininet 基准测试
记录从代开到关闭拓扑的时间:
$ sudo mn --test none
各自都有命名域(仅对用户态)
默认下,主机各自拥有自己的命名域,交换机和控制器都在根命名域下。可以通过–innamespace选项使得所有设备都在自己的命名域:
$ sudo mn --innamespace --user switch
交换机和控制器通信不用loopback而是一个分开的桥接控制。
Mininet命令行界面的命令
显示选项
$ sudo mn
...
mininet> help
...
Python解释器
如果Mininet命令行界面第一个就是py,那么命令会被python执行。这对于拓展Mininet以及测试内部工作流很有用。每一个主机,交换机和控制器都有一个对应的Node对象。
在Mininet命令行:
mininet> py 'hello '+'world'
打印可用的本地变量:
mininet> py locals()
查看Node对象的方法和属性,使用dir()函数:
mininet> py dir(s1)
可以阅读Node对象方法的在线说明文档,按q退出
mininet> py help(h1)
也可以执行变量的方法:
mininet> py h1.IP()
关闭\打开链路
mininet> link s1 h1 down
mininet> link s1 h1 up
XTerm显示
mininet> xterm h1 h2
Python接口示例
在这里给出了如何使用应用接口的示例。
SSH daemon
其中一个例子是在每个主机上运行SSH daemon,要使用绝对地址:
$ sudo ~/mininet/examples/sshd.py
从另一个终端中可以ssh接入任意主机并运行交互命令:
$ ssh 10.0.0.1
$ ping 10.0.0.2
...
$ exit
下一步
OpenFlow 教程
Mininet介绍和Python接口
补充说明
使用远程控制器
$ sudo mn --controller=remote,ip=[controller IP],port=[controller listening port]
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)