当前位置: 首页 > Mininet使用入门 > 正文

Mininet官方Walkthrough中文版

官方文档参考:http://mininet.org/walkthrough/”
演示Mininet的大多数命令,以及与Wireshark配合的典型应用。一个小时即可搞定。
本文由http://sdnhub.cn/根据Mininet官方文档翻译整理、并添加了适当的注释,转载请注明出处!

注意:本文没有完全翻译,但是并不影响初学者学习Mininet。如果在学习中有任何的疑问可以给我留言,我会尽量回复!

第1部分 Mininet的基本使用

显示Mininet的启动选项

root@mininet-vm:~# mn -h
Usage: mn [options]
(type mn -h for details)
The mn utility creates Mininet network from the command line. It can create
parametrized topologies, invoke the Mininet CLI, and run tests.

Options:
-h, –help show this help message and exit
–switch=SWITCH ovsk|ovsl|user[,param=value…]
–host=HOST cfs|proc|rt[,param=value…]
–controller=CONTROLLER
none|nox|ovsc|ref|remote[,param=value…]
–link=LINK default|tc[,param=value…]
–topo=TOPO linear|minimal|reversed|single|tree[,param=value…]
-c, –clean clean and exit
–custom=CUSTOM read custom topo and node params from .pyfile
–test=TEST cli|build|pingall|pingpair|iperf|all|iperfudp|none
-x, –xterms spawn xterms for each node
-i IPBASE, –ipbase=IPBASE
base IP address for hosts
–mac automatically set host MACs
–arp set all-pairs ARP entries
-v VERBOSITY, –verbosity=VERBOSITY
info|warning|critical|error|debug|output
–innamespace sw and ctrl in namespace?
–listenport=LISTENPORT
base port for passive switch listening
–nolistenport don’t use passive listening port
–pre=PRE CLI script to run before tests
–post=POST CLI script to run after tests
–prefixlen=PREFIXLEN
prefix length (e.g. /8) for automatic network
configuration
–pin pin hosts to CPU cores (requires –host cfs or –host
rt)
–version
root@mininet-vm:~#

启动Wireshark

# wireshark &

Mininet虚拟机内置的Wireshark可以解析openflow协议的数据包(通过openflow 插件)。在wireshark的过滤文本框中输入“of”并应用,即可只显示openflow的数据包。抓包接口选择“lo”(loopback),并开始抓包。

与主机和交换机交互

直接运行mn命令,则会创建最简单的“minimal”拓扑,它包括一个OpenFlow kernel交换机,交换机上连接了两台主机。下面的两个命令都可以创建“minimal”拓扑。

root@mininet-vm:~# mn
*** Creating network
*** Adding controller
*** Adding hosts:
h1 h2
*** Adding switches:
s1
*** Adding links:
(h1, s1) (h2, s1)
*** Configuring hosts
h1 h2
*** Starting controller
*** Starting 1 switches
s1
*** Starting CLI:
mininet>
root@mininet-vm:~# mn –topo=minimal
*** Creating network
*** Adding controller
*** Adding hosts:
h1 h2
*** Adding switches:
s1
*** Adding links:
(h1, s1) (h2, s1)
*** Configuring hosts
h1 h2
*** Starting controller
*** Starting 1 switches
s1
*** Starting CLI:
mininet>

上面的命令在VM中创建了2个主机进程,1个交换机进程,1个basic控制器。控制器可以在VM的外部。
(通过mn –h帮助的–topo查看可用的拓扑,不指定–topo时默认为minimal:

--topo=TOPO           linear|minimal|reversed|single|tree[,param=value…]        )

如果没有使用“–test”选项时,Mininet命令行将被启动。“–test”选项的值可以看帮助。

--test=TEST           cli|build|pingall|pingpair|iperf|all|iperfudp|none

(cli:进入CLI;none:建完拓扑后什么也不测试自动退出Mininet;其它的则完成测试后退出Mininet)

CLI常用命令示例:

mininet> help
mininet> nodes
mininet> net
mininet> dump
mininet> h1 ifconfig -a
mininet> s1 ifconfig -a (显示交换机的网口,和虚拟机的网口eth0和lo)
注意:host具有隔离的网络状态,在主机上运行arp,route将只显示host的信息,而不会显示交换机和虚拟机的信息,例如,如下两条命令:
mininet> h1 arp -a
? (10.0.0.2) at 2a:06:4a:e4:56:a5 [ether] on h1-eth0
mininet> s1 arp -a
? (192.168.159.1) at 00:50:56:c0:00:08 [ether] on eth0
? (192.168.159.2) at 00:50:56:eb:5c:45 [ether] on eth0
需要注意,只有网络实现了隔离,其它的诸如显示进程状态之类的还将显示的是虚拟机上的信息。Linux可以使用Linux containers隔离进程空间,但是Mininet暂时并未实现,所有的东西都在root进程名字空间便于调试。
mininet> h1 ping -c 1 h2 (启动wireshark ,仔细体会和观察下面的流程)
You should see OpenFlow control traffic. The first host ARPs for the MAC address of the second, which causes a packet_in message to go to the controller. The controller then sends a packet_out message to flood the broadcast packet to other ports on the switch (in this example, the only other data port). The second host sees the ARP request and sends a broadcast reply. This reply goes to the controller, which sends it to the first host and pushes down a flow entry.
Now the first host knows the IP address of the second, and can send its ping via an ICMP Echo Request. This request, along with its corresponding reply from the second host, both go the controller and result in a flow entry pushed down (along with the actual packets getting sent out).
mininet> pingall
下面测试在h1上启动一个简单的web server:
mininet> h1 python -m SimpleHTTPServer 80 &
mininet> h2 wget -O – h1

mininet> h1 kill %python
mininet> exit
$ sudo mn -c

上面是Mininet的基本使用,下面看一些高级启动选项

第2部分高级启动选项

运行回归测试:Run a Regression Test
$ sudo mn --test pingpair
$ sudo mn --test iperf
改变网络拓扑的大小和类型:Changing Topology Size and Type
默认拓扑只有一个交换机和2个主机,下面1交换机,3个主机
$ sudo mn --test pingall --topo single,3
线性拓扑,4个交换机级联,每个交换机下连1个主机:
$ sudo mn --test pingall --topo linear,4
设置link参数
$ sudo mn --link tc,bw=10,delay=10ms
mininet> iperf

mininet> h1 ping -c10 h2
如上delay为10ms,则ping返回的RTT(Round Trip Time)时间为40ms。since the ICMP request traverses two links (one to the switch, one to the destination) and the ICMP reply traverses two links coming back.
调整冗长输出
默认verbosity level 是info, 只打印启动时和关闭时信息,显示完整的调试信息使用-v选项:
$ sudo mn -v debug

mininet> exit
上面的命令打印很多额外的细节内容,下面试一下output选项,
$ sudo mn -v output
mininet> exit
还有一个warning选项,回归测试时使用,可以隐藏不必要的函数输出。

定制网络拓扑:

范例参考:custom/topo-2sw-2host.py
代码如下:

"""Custom topology example

Two directly connected switches plus a host for each switch:

   host --- switch --- switch --- host

Adding the 'topos' dict with a key/value pair to generate our newly defined
topology enables one to pass in '--topo=mytopo' from the command line.
"""

from mininet.topo import Topo

class MyTopo( Topo ):
    "Simple topology example."

    def __init__( self ):
        "Create custom topo."

        # Initialize topology
        Topo.__init__( self )

        # Add hosts and switches
        leftHost = self.addHost( 'h1' )
        rightHost = self.addHost( 'h2' )
        leftSwitch = self.addSwitch( 's3' )
        rightSwitch = self.addSwitch( 's4' )

        # Add links
        self.addLink( leftHost, leftSwitch )
        self.addLink( leftSwitch, rightSwitch )
        self.addLink( rightSwitch, rightHost )


topos = { 'mytopo': ( lambda: MyTopo() ) }

在命令行调用定制topo的命令:

root@mininet-vm:/home/mininet# mn –custom mininet/custom/topo-2sw-2host.py –topo mytopo
(–topo后的内容必须与topo-2sw-2host.py最后一行的mytopo对应)

ID = MAC

在命令行中使用 --mac选项即可,使主机的mac地址最后的数字为主机的编号。方便调试。

$ sudo mn --mac

打开Xterm终端:

$ sudo mn -x
(启动Mininet构建拓扑后,自动打开所有主机、交换机、控制的的xterm终端)

mininet> xterm h1 c0
(在CLI中打开指定的主机、交换机、控制器的xterm终端)

交换机和控制器的xterm终端其实没什么区别,没有使用单独的名字空间,跟普通的终端是一样的,但是可以方便调试,例如,显示流表:

# dpctl dump-flows tcp:127.0.0.1:6634
(dpctl: OpenFlow switch management utility)

使用其它交换机类型:

mn默认使用的交换机类型是ovsk(OVS,即Open vSwitch,是Mininet预装的交换机),mn帮助中的内容:

--switch=SWITCH       ivs|ovsk|ovsl|user[,param=value…]

  • ivs交换机:Indigo Virtual Switch (projectfloodlight.org),默认未安装,不能使用。
  • ovsk交换机:OVS,即Open vSwitch  openvswitch.org,默认安装,可以使用
  • ovsl交换机:Open VSwitch legacy kernel-space switch using ovs-openflowd,Currently only works in the root namespace.即,老的Open vSwitch交换机。没有安装,不能使用。也没必要。。。
  • user交换机:工作在用户空间交换机,默认安装可以使用。

工作在kernel空间的交换机性能比user空间的高。可以使用iperf进行测试进行对比:

$ sudo mn --switch ovsk --test iperf
$ sudo mn --switch user --test iperf

进入mn的CLI后使用dump命令查看交换机的类型。

基准测试(Benchmark):

--test=TEST       cli|build|pingall|pingpair|iperf|all|iperfudp|none

命令示例:

$ sudo mn --switch ovsk --test iperf
$ sudo mn --switch user --test iperf
$ sudo mn --switch user --test none          (不做测试操作,只记录Mininet运行的用时,然后退出)

使交换机工作在自己的名字空间中 (仅user switch适用,ovsk不能用)

默认情况下交换机工作在root名字空间中,使用下面的命令可以使交换机网络工作在自己的名字空间中:

$ sudo mn --innamespace --switch user
(在交换机中执行ifconfig将看不到eth0接口)

虽然没多大用处,但是示例了如何隔离多个不同的交换机。此时,交换机将使用一个单独的桥接与控制器通信。

第3部分 Mininet命令行接口(CLI)命令显示选项

#mn -h
#mn
mininet>help
可以在Mininet的CLI中使用py来执行python表达式。
mininet> py ‘hi’ + ‘,nihao’
hi,nihao
mininet> py locals()
{‘h2′: , ‘h1′: , ‘s4′: , ‘s3′: , ‘net': <mininet.net.Mininet object at 0x1079dd0>, ‘c0′: }
mininet> py dir(h1)
[‘IP’, ‘MAC’, ‘class‘, ‘delattr‘, ‘dict‘, ‘doc‘, ‘format‘, ‘getattribute‘, ‘hash‘, ‘init‘, ‘module‘, ‘new‘, ‘reduce‘, ‘reduce_ex‘, ‘repr‘, ‘setattr‘, ‘sizeof‘, ‘str‘, ‘subclasshook‘, ‘weakref‘, ‘addIntf’, ‘checkSetup’, ‘cleanup’, ‘cmd’, ‘cmdPrint’, ‘config’, ‘configDefault’, ‘connectionsTo’, ‘defaultIntf’, ‘deleteIntfs’, ‘execed’, ‘fdToNode’, ‘inNamespace’, ‘inToNode’, ‘intf’, ‘intfIsUp’, ‘intfList’, ‘intfNames’, ‘intfs’, ‘isSetup’, ‘lastCmd’, ‘lastPid’, ‘linkTo’, ‘monitor’, ‘name’, ‘nameToIntf’, ‘newPort’, ‘outToNode’, ‘params’, ‘pexec’, ‘pid’, ‘pollOut’, ‘popen’, ‘portBase’, ‘ports’, ‘read’, ‘readbuf’, ‘readline’, ‘sendCmd’, ‘sendInt’, ‘setARP’, ‘setDefaultRoute’, ‘setHostRoute’, ‘setIP’, ‘setMAC’, ‘setParam’, ‘setup’, ‘shell’, ‘startShell’, ‘stdin’, ‘stdout’, ‘stop’, ‘terminate’, ‘waitOutput’, ‘waitReadable’, ‘waiting’, ‘write’]
mininet> py h1.IP()
10.0.0.1
mininet> py h1.MAC()
7e:6d:a6:fc:3a:c8
mininet>

连接的打开与关闭

mininet> link s1 h1 down
mininet> link s1 h1 up

连接的打开和断开都会触发,端口状态改变通知,可以在Wireshark中看到对应的包:

Xterm显示

mininet> xterm h1 h2

第4部分 Python API示例

目录/home/mininet/mininet/example下的示例文件,如何使用Mininet的Python API。

例如:/home/mininet/mininet/example/sshd.py,创建的topo可以使每个主机都运行一个ssh服务器,可以在VM的终端中ping通每一个主机,并且可以ssh进每个主机。

第5部分 Workthrough完成

Next :OpenFlow Tutorial
关于Mininet的Python API可以参考 Introduction to Mininet:
https://github.com/mininet/mininet/wiki/Introduction-to-Mininet

附录补充信息

  • 使用远程Controller

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

运行POX控制器:

$ cd ~/pox
$ ./pox.py forwarding.l2_learning
$ sudo mn --controller=remote,ip=127.0.0.1,port=6633

Mininet默认使用的是NOX控制器,在/home/mininet/mininet/util目录,Mininet使用的安装选项是util/install.sh -a,可以查看这个目录下的install.sh文件了解详情。

  • 在主机上使用iperf测试网络性能

可以在Mininet的CLI中直接使用iperf测试性能。也可以在h1和h2上手工单独运行iperf。

mininet> h1 iperf -s & #运行iperf服务器
mininet> h2 iperf -c h1 #运行iperf客户端

  • 使用netcat在主机间发送消息

在h1上运行”server”:

mininet> h1 nc -l 80

h2主机作为 “client”,:

mininet> h2 nc h1 80

  • 使用dpctl手工管理交换机流表

dpctl:通过查看流状态和流计数器可以辅助调试。大多数的OpenFlow交换机可以被动监听一个端口启动(如:6634)。这样既可以不在交换机中添加任何代码而查看交换机的状态。

The ‘show’ command connects to the switch and dumps out its port state and capabilities:
#dpctl show tcp:127.0.0.1:6634
The ‘dump-flows’ command outputs the current set of rules:
#dpctl dump-flows tcp:127.0.0.1:6634
To manually install a rule, run something like:
#dpctl add-flow tcp:127.0.0.1:6634 in_port=1,actions=output:2
Rule Timeouts
When you do a “dpctl dump-flows” you can see an “idle_timeout” option for each entry, which defaults to 60s. This means that the flow will expire after 60secs if there is no incoming traffic. Run again respecting this limit, or install a flow-entry with longer timeout.
#dpctl add-flow tcp:127.0.0.1:6634 in_port=1,idle_timeout=120,actions=output:2
Rule Counters
Each rule tracks the number of packets and bytes
Events
Switch join/leave
Packet i
Why doesn’t dpctl work? How can I dump a switch’s flow table?
dpctl should work fine with the Stanford OpenFlow reference implementation or the CPqD version of same.
But you probably don’t want to use dpctl – use ovs-ofctl instead! Especially if you’re running Open vSwitch – ovs-ofctl it’s particularly easy to use with OVS and, importantly, will actually dump the complete flow table (unlike ovs-dpctl !)
If you’re running Open vSwitch, or need to open up a listening port on either OVS or the reference switch so that you can connect to a port, read on…
1.If you are using Open vSwitch, the correct command to use from the shell prompt is
$ sudo ovs-ofctl dump-flows s1
(If you try to use ovs-dpctl with Open vSwitch, you will only see the cached flows in the kernel, rather than the switch’s full flow table.)
2.The correct command to use from the Mininet prompt is
mininet> dpctl dump-flows
which dumps all the flows on all switches, and works for both OVS and the reference switch.
If you’re running OVS, you can pass the switch name to ovs-ofctl and it will connect to it via the file system:
mininet> sh ovs-ofctl dump-flows s1
or, from the shell prompt:
$ ovs-ofctl dump-flows s1
3.If you want to open up a listening port on the switch, you need to specify the base listening port, e.g.
net = Mininet( topo=topo, listenPort=6634 )
Ports will be allocated sequentially starting with the value you specify.
Note if you want to dump the flows from the reference switch, you will need to have a listening port opened up; then you can use dpctl :
$ dpctl dump-flows tcp:localhost:6634
Note that ovs-ofctl doesn’t like localhost , so you should use 127.0.0.1:
$ ovs-ofctl dump-flows tcp:127.0.0.1:6634

关于使用在Mininet的CLI中使用dpctl、在shell中使用dpctl、ovs-dpctl、ovs-ofctl的区别:
首先,在Mininet的CLI中使用dpctl时:dpctl命令与使用的交换机相关,它并非真正的命令,它根据交换机的不同选择真正的命令,如下表。shell命令行中使用ovs-dpctl、ovs-ofctl的区别上面英文有介绍。

root@mininet-vm:~# mn --switch user
*** Creating network
*** Adding controller
*** Adding hosts:
h1 h2
*** Adding switches:
s1
*** Adding links:
(h1, s1) (h2, s1)
*** Configuring hosts
h1 h2
*** Starting controller
*** Starting 1 switches
s1
*** Starting CLI:
mininet> dump
< OVSController c0: 127.0.0.1:6633 pid=1669 >
< UserSwitch s1: lo:127.0.0.1,s1-eth1:None,s1-eth2:None pid=1679 >
< Host h1: h1-eth0:10.0.0.1 pid=1677 >
< Host h2: h2-eth0:10.0.0.2 pid=1678 >
mininet> dpctl -V
*** s1 ————————————————————————
dpctl 1.0.0 compiled Nov 30 2012 22:31:36
mininet> quit
*** Stopping 2 hosts
h1 h2
*** Stopping 1 switches
s1 …
*** Stopping 1 controllers
c0
*** Done
completed in 191.695 seconds
root@mininet-vm:~# mn --switch ovsk
*** Creating network
*** Adding controller
*** Adding hosts:
h1 h2
*** Adding switches:
s1
*** Adding links:
(h1, s1) (h2, s1)
*** Configuring hosts
h1 h2
*** Starting controller
*** Starting 1 switches
s1
*** Starting CLI:
mininet> dump
< OVSController c0: 127.0.0.1:6633 pid=1804 >
< OVSSwitch s1: lo:127.0.0.1,s1-eth1:None,s1-eth2:None pid=1816 >
< Host h1: h1-eth0:10.0.0.1 pid=1812 >
< Host h2: h2-eth0:10.0.0.2 pid=1813 >
mininet> dpctl -V
*** s1 ————————————————————————
ovs-dpctl (Open vSwitch) 1.4.3
Compiled Oct 25 2012 09:12:47
mininet>

本文没有完全翻译,但是并不影响初学者学习Mininet。如果在学习中有任何的疑问可以给我留言,我会尽量回复!

本文固定链接: http://sdnhub.cn/index.php/mininet-walkthrough-chinese/ | 软件定义网络SDN

该日志由 sdnhub 于2014年06月09日发表在 Mininet使用入门 分类下, 你可以发表评论,并在保留原文地址及作者的情况下引用到你的网站或博客。
原创文章转载请注明: Mininet官方Walkthrough中文版 | 软件定义网络SDN
关键字:

Mininet官方Walkthrough中文版:目前有1 条留言

  1. 沙发
    minineter:

    你好,请问一下Mininet可以连接到其他虚拟机吗?
    即,我在VM1中运行Mininet,在同一个平台下,我有其他虚拟机VM2,VM3等。
    请问VM2 VM3这些虚拟机可以作为Mininet构建的网络拓扑中的主机吗?
    如果可以,请问大致实现方案是怎样的? 谢谢

    2014-12-30 16:29 [回复]

发表评论

*

快捷键:Ctrl+Enter