http://mininet.org/download/
http://sdnhub.cn/index.php/mininet-walkthrough-chinese/
-----------------------------------源碼安裝-------------------------------------------------------------------
1.從GITHUB上獲取mininet源碼 git clone git://github.com/mininet/mininet
2.安裝 mininet/util/install.sh [options]
參數包括
-a: 全部安裝
-nfv:僅安裝MINIENT OPENFLOW引用多SWITCH 和OPEN VSWITCH
-s mydir: 指定目錄
例如
To install everything (using your home directory): install.sh -a 全部安裝
To install everything (using another directory): install.sh -s mydir -a 安裝在mydir目錄下
To install Mininet + user switch + OVS (using your home dir): install.sh -nfv 只安裝MININET User Switch OVS
To install Mininet + user switch + OVS (using another dir:) install.sh -s mydir -nfv 在mydir目錄下只安裝MININET USER Switch 和 OVS
install.sh -h 查看更多參數 使用全部安裝 mininet/util/install.sh -a
3.測試 sudo mn --test pingall 節點之間會互相進行ping操作
-------------------------------------------------------------------------------------------------------------------------------
第1部分:Everyday Mininet Usage
首先是是命令語法
$
這個符號代表現在處於 Linux 的shell 交互下,需要使用的是 Linux 命令mininet>
這個符號表示現在處於 Mininet 交互下,需要使用的是 Mininet 的命令#
這個符號表示的是現在處於 Linux 的 root 權限下。
以上相應的狀態下下屬於對應的命令,就能夠得到正常的輸出。需要注意的是mininet>
的情況比較特殊,需要使用 minient 的命令來進行交互。
Display Startup Options
我們首先來啟動 Mininet。
鍵入以下命令來顯示Mininet的幫助信息:
$ sudo 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 ivs|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 --pin pin hosts to CPU cores (requires --host cfs or --host rt) --version
如上所示,輸出了 mn 的幫助信息。
Start Wireshark
為了使用 Wireshark 來查看 OpenFlow 的控制信息,我們先打開 Wireshark 並讓他在后台運行。$ sudo wireshark &
在 Wireshark 的過濾選項中,輸入of
,然后選擇 Apply。
In Wireshark, click Capture, then Interfaces, then select Start on the loopback interface (lo
).
現在窗口上暫時應該沒有任何 OpenFlow 的數據包。
注:在Mininet VM鏡像中Wireshark是默認已經安裝的。如果你的系統中沒有Wireshark的和OpenFlow,您可以使用Mininet的install.sh腳本,按以下步驟安裝:
$ cd ~
$ git clone https://github.com/mininet/mininet#如果它尚不存在
$ mininet/util/install.sh -w
如果已經安裝了 Wireshark,但是運行不了(e.g. 你得到一個類似$DISPLAY not set
之類的錯誤信息,可以參考 FAQ,:https://github.com/mininet/mininet/wiki/FAQ#wiki-X11-forwarding)
設置好 X11就可以正常運行 GUI 程序,並且使用 xterm 之類的終端仿真器了,后面的演示中可以用到。
Interact with Hosts and Switches
Start a minimal topology and enter the CLI:
$ sudo mn
默認的最小拓撲結構包含有兩台主機(h1,h2),還有一個 OpenFlow 的交換機,一個 OpenFlow 的控制器四台設備。這種拓撲接口也可以使用--topo=minimal
來指定。當然我們也可以使用其他的拓撲結構,具體信息可以看 --topo
的信息。
現在四個實體(h1,h2,c0,s1)都在運行着。c0作為控制器,是可以放在虛擬機外部的。
如果沒有具體的測試作為參數傳遞時,我們可以使用 Mininet 交互。
在Wireshark的窗口中,你會看到內核交換機連接到控制器。
顯示Mininet CLI命令:
mininet> help
Documented commands (type help <topic>):
========================================
EOF exit intfs link noecho pingpair py source xterm
dpctl gterm iperf net pingall pingpairfull quit time
dump help iperfudp nodes pingallfull px sh x
You may also send a command to a node using:
<node> command {args}
For example:
mininet> h1 ifconfig
The interpreter automatically substitutes IP addresses
for node names when a node is the first arg, so commands
like
mininet> h2 ping h3
should work.
Some character-oriented interactive commands require
noecho:
mininet> noecho h2 vi foo.py
However, starting up an xterm/gterm is generally better:
mininet> xterm h2
顯示節點:
mininet> nodes
available nodes are:
c0 h1 h2 s1
顯示網絡鏈接:
mininet> net
h1 h1-eth0:s1-eth1
h2 h2-eth0:s1-eth2
s1 lo: s1-eth1:h1-eth0 s1-eth2:h2-eth0
c0
輸出所有節點的信息:
mininet> dump
<Host h1: h1-eth0:10.0.0.1 pid=3278>
<Host h2: h2-eth0:10.0.0.2 pid=3279>
<OVSSwitch s1: lo:127.0.0.1,s1-eth1:None,s1-eth2:None pid=3282>
<OVSController c0: 127.0.0.1:6633 pid=3268>
從上面的輸出中,你可以看到有一台交換機和兩台主機。
在 Mininet 的CLI 中第一個字符串是設備名,那后面的命令就在該設備上執行。例如我們想在h1設備上執行ifconfig
則輸入如下命令:
mininet> h1 ifconfig -a
h1-eth0 Link encap:Ethernet HWaddr 3e:94:43:b1:ad:48
inet addr:10.0.0.1 Bcast:10.255.255.255 Mask:255.0.0.0
inet6 addr: fe80::3c94:43ff:feb1:ad48/64 Scope:Link
UP BROADCAST RUNNING MULTICAST MTU:1500 Metric:1
RX packets:22 errors:0 dropped:0 overruns:0 frame:0
TX packets:8 errors:0 dropped:0 overruns:0 carrier:0
collisions:0 txqueuelen:1000
RX bytes:1764 (1.7 KB) TX bytes:648 (648.0 B)
lo Link encap:Local Loopback
inet addr:127.0.0.1 Mask:255.0.0.0
inet6 addr: ::1/128 Scope:Host
UP LOOPBACK RUNNING MTU:65536 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:0
RX bytes:0 (0.0 B) TX bytes:0 (0.0 B)
上面的輸出中,可以看見 h1-eth0
跟 lo
兩個接口,需要注意的是,在 Linux 系統的 shell 中運行ifconfig
是看不到h1-eth0。
與h1-eth0
相反的是,switch
默認是跑在 root 的網絡namespace上面,所以在switch
上執行命令與在 Linux 下的 shell 中是一樣的。
mininet> s1 ifconfig-a
eth0 Link encap:Ethernet HWaddr 08:00:27:98:dc:aa
inet addr:10.0.2.15 Bcast:10.0.2.255 Mask:255.255.255.0
inet6 addr: fe80::a00:27ff:fe98:dcaa/64 Scope:Link
UP BROADCAST RUNNING MULTICAST MTU:1500 Metric:1
RX packets:46716 errors:0 dropped:0 overruns:0 frame:0
TX packets:40265 errors:0 dropped:0 overruns:0 carrier:0
collisions:0 txqueuelen:1000
RX bytes:10804203 (10.8 MB) TX bytes:40122199 (40.1 MB)
lo Link encap:Local Loopback
inet addr:127.0.0.1 Mask:255.0.0.0
inet6 addr: ::1/128 Scope:Host
UP LOOPBACK RUNNING MTU:65536 Metric:1
RX packets:43654 errors:0 dropped:0 overruns:0 frame:0
TX packets:43654 errors:0 dropped:0 overruns:0 carrier:0
collisions:0 txqueuelen:0
RX bytes:37264504 (37.2 MB) TX bytes:37264504 (37.2 MB)
lxcbr0 Link encap:Ethernet HWaddr fe:5e:f0:f7:a6:f3
inet addr:10.0.3.1 Bcast:10.0.3.255 Mask:255.255.255.0
inet6 addr: fe80::a8c4:b5ff:fea6:2809/64 Scope:Link
UP BROADCAST RUNNING MULTICAST MTU:1500 Metric:1
RX packets:52 errors:0 dropped:0 overruns:0 frame:0
TX packets:20 errors:0 dropped:0 overruns:0 carrier:0
collisions:0 txqueuelen:0
RX bytes:4759 (4.7 KB) TX bytes:2952 (2.9 KB)
ovs-system Link encap:Ethernet HWaddr 3e:79:59:3d:d9:bb
BROADCAST 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:0
RX bytes:0 (0.0 B) TX bytes:0 (0.0 B)
s1 Link encap:Ethernet HWaddr 6e:8c:5d:91:d5:44
inet6 addr: fe80::fc47:8aff:fe6a:4155/64 Scope:Link
UP BROADCAST RUNNING MTU:1500 Metric:1
RX packets:13 errors:0 dropped:0 overruns:0 frame:0
TX packets:8 errors:0 dropped:0 overruns:0 carrier:0
collisions:0 txqueuelen:0
RX bytes:1026 (1.0 KB) TX bytes:648 (648.0 B)
s1-eth1 Link encap:Ethernet HWaddr 5e:a2:f7:86:f3:b1
inet6 addr: fe80::5ca2:f7ff:fe86:f3b1/64 Scope:Link
UP BROADCAST RUNNING MULTICAST MTU:1500 Metric:1
RX packets:8 errors:0 dropped:0 overruns:0 frame:0
TX packets:22 errors:0 dropped:0 overruns:0 carrier:0
collisions:0 txqueuelen:1000
RX bytes:648 (648.0 B) TX bytes:1764 (1.7 KB)
s1-eth2 Link encap:Ethernet HWaddr b2:c6:37:e0:d9:61
inet6 addr: fe80::b0c6:37ff:fee0:d961/64 Scope:Link
UP BROADCAST RUNNING MULTICAST MTU:1500 Metric:1
RX packets:8 errors:0 dropped:0 overruns:0 frame:0
TX packets:21 errors:0 dropped:0 overruns:0 carrier:0
collisions:0 txqueuelen:1000
RX bytes:648 (648.0 B) TX bytes:1674 (1.6 KB)
veth14524J Link encap:Ethernet HWaddr fe:ca:13:f5:dd:b4
inet6 addr: fe80::fcca:13ff:fef5:ddb4/64 Scope:Link
UP BROADCAST RUNNING MULTICAST MTU:1500 Metric:1
RX packets:8 errors:0 dropped:0 overruns:0 frame:0
TX packets:40 errors:0 dropped:0 overruns:0 carrier:0
collisions:0 txqueuelen:1000
RX bytes:648 (648.0 B) TX bytes:4190 (4.1 KB)
veth2K19CE Link encap:Ethernet HWaddr fe:f1:f7:e8:49:45
inet6 addr: fe80::fcf1:f7ff:fee8:4945/64 Scope:Link
UP BROADCAST RUNNING MULTICAST MTU:1500 Metric:1
RX packets:8 errors:0 dropped:0 overruns:0 frame:0
TX packets:42 errors:0 dropped:0 overruns:0 carrier:0
collisions:0 txqueuelen:1000
RX bytes:648 (648.0 B) TX bytes:4370 (4.3 KB)
veth9WSHRK Link encap:Ethernet HWaddr fe:87:1d:33:f6:41
inet6 addr: fe80::fc87:1dff:fe33:f641/64 Scope:Link
UP BROADCAST RUNNING MULTICAST MTU:1500 Metric:1
RX packets:8 errors:0 dropped:0 overruns:0 frame:0
TX packets:43 errors:0 dropped:0 overruns:0 carrier:0
collisions:0 txqueuelen:1000
RX bytes:648 (648.0 B) TX bytes:4460 (4.4 KB)
vethH2K7R5 Link encap:Ethernet HWaddr fe:5e:f0:f7:a6:f3
inet6 addr: fe80::fc5e:f0ff:fef7:a6f3/64 Scope:Link
UP BROADCAST RUNNING MULTICAST MTU:1500 Metric:1
RX packets:14 errors:0 dropped:0 overruns:0 frame:0
TX packets:48 errors:0 dropped:0 overruns:0 carrier:0
collisions:0 txqueuelen:1000
RX bytes:1776 (1.7 KB) TX bytes:5030 (5.0 KB)
vethO99MI2 Link encap:Ethernet HWaddr fe:cf:ee:97:fb:7f
inet6 addr: fe80::fccf:eeff:fe97:fb7f/64 Scope:Link
UP BROADCAST RUNNING MULTICAST MTU:1500 Metric:1
RX packets:14 errors:0 dropped:0 overruns:0 frame:0
TX packets:51 errors:0 dropped:0 overruns:0 carrier:0
collisions:0 txqueuelen:1000
RX bytes:1767 (1.7 KB) TX bytes:5294 (5.2 KB)
上面的輸出中包含交換機的虛擬網卡 s1,以及主機的 eth0。
為了區別顯示host 主機的網絡是隔離的,我們可以通過arp
與route
命令來做演示,分別在 s1與h1上面演示如下:
mininet> s1 arp
Address HWtype HWaddress Flags Mask Iface
localhost ether 00:16:3e:54:9c:03 C lxcbr0
localhost ether 52:54:00:12:35:02 C eth0
localhost ether 52:54:00:12:35:03 C eth0
localhost ether 00:16:3e:51:24:a7 C lxcbr0
mininet> s1 route
Kernel IP routing table
Destination Gateway Genmask Flags Metric Ref Use Iface
default localhost 0.0.0.0 UG 0 0 0 eth0
10.0.2.0 * 255.255.255.0 U 0 0 0 eth0
10.0.3.0 * 255.255.255.0 U 0 0 0 lxcbr0
172.17.0.0 * 255.255.0.0 U 0 0 0 docker0
mininet> h1 arp
mininet> h1 route
Kernel IP routing table
Destination Gateway Genmask Flags Metric Ref Use Iface
10.0.0.0 * 255.0.0.0 U 0 0 0 h1-eth0
這樣可以做到將每一個主機,交換機,以及控制器都放到他自己的標准的 network namespace 中,但是這種做法並沒有什么特別的優勢,除非你想復制一個非常復雜的網絡。Mininet 不支持這種做法,你可以通過--innamespace
參數來查看更多的信息。譯者注:感覺有點像 LXC 或者說想最近比較火的 Docker
注意:只有網絡是虛擬出來的,每一個主機里面的進程使用的都是同一套目錄,可以看到相同的進程集合,我們打印不同主機下面的進程列表看看:
mininet> h1 ps -a
PID TTY TIME CMD
3899 pts/3 00:00:00 tmux
4000 pts/23 00:00:00 sudo
4001 pts/23 00:00:51 wireshark
4030 pts/23 00:00:00 dbus-launch
4530 pts/23 00:00:43 dumpcap
4541 pts/22 00:00:00 sudo
4542 pts/22 00:00:00 mn
mininet> h2 ps -a
PID TTY TIME CMD
3899 pts/3 00:00:00 tmux
4000 pts/23 00:00:00 sudo
4001 pts/23 00:00:52 wireshark
4030 pts/23 00:00:00 dbus-launch
4530 pts/23 00:00:43 dumpcap
4541 pts/22 00:00:00 sudo
4542 pts/22 00:00:00 mn
mininet> s1 ps -a
PID TTY TIME CMD
3899 pts/3 00:00:00 tmux
4000 pts/23 00:00:00 sudo
4001 pts/23 00:00:54 wireshark
4030 pts/23 00:00:00 dbus-launch
4530 pts/23 00:00:46 dumpcap
4541 pts/22 00:00:00 sudo
4542 pts/22 00:00:00 mn
如上所示, h1,h2,s1三個進程列表是完全相同的。
其實完全可以做到各個主機完全獨立,就想 LXC 那樣,但是目前 Mininet 並沒有這么做。在 Mininet 中所有的進程都放在 root 下面,這樣你可以在 Linux的 shell 中直接用kill
或者ps
這些命令查看或者殺死進程。
Test connectivity between hosts
現在,驗證您可以h1 ping 通 h2:
mininet> h1 ping h2 -c 1
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=8.57 ms
--- 10.0.0.2 ping statistics ---
1 packets transmitted, 1 received, 0% packet loss, time 0ms
rtt min/avg/max/mdev = 8.576/8.576/8.576/0.000 ms
mininet中的命令語法如上所示。host1 command host2
。
在 Wireshark 中可以看到 OpenFlow 的控制流量,可以看到h1 ARPs h2的 mac,並將一個 packet_in
發送到 c0
,然后c0
發送packet_out
消息流廣播到交換機(在本例中,唯一的其他數據端口)。第二個主機接受到的ARP請求,並發送一個廣播答復。此回復進到控制器,該控制器將其發送到h1
並且 pushes down a flow entry。
現在第一主機知道的第二個IP地址,並且可以通過ICMP ping 來回顯請求。這個請求,連同其從第二主機對應的應答,both go the controller and result in a flow entry pushed down (along with the actual packets getting sent out).
重復前一條命令:
mininet> h1 ping -c 1 h2
這次 ping 的時間將比第一次低的多, A flow entry covering ICMP ping traffic was previously installed in the switch, so no control traffic was generated, and the packets immediately pass through the switch.
使用pingall
命令可以讓每一個節點直接都產生上面的效果。
mininet> pingall
Run a simple web server and client
我們不單可以在主機上面運行ping
命令,每一條 Linux下的命令或者程序都可以在 Mininet 中運行:
接下來,嘗試開始於h1啟動一個簡單的HTTP服務器上,然后從h2發出請求,最后關閉Web服務器:
mininet> h1 python -m SimpleHTTPServer 80 &
mininet> h2 wget h1
--2014-09-15 08:10:11-- http://10.0.0.1/
Connecting to 10.0.0.1:80... connected.
HTTP request sent, awaiting response... 200 OK
Length: 2647 (2.6K) [text/html]
Saving to: ‘index.html’
0K .. 100% 71.7M=0s
2014-09-15 08:10:11 (71.7 MB/s) - ‘index.html’ saved [2647/2647]
mininet> h1 kill %python
退出mininet交互命令:
mininet>exit
cleanup
如果Mininet出於某種原因崩潰,可以用下面命令來清理:
sudo mn -c
Part 2: 高級選項Advanced Startup Options
回歸測試Run a Regression Test
Mininet 可以用於直接運行回歸測試,不一定要切換到他的 CLI 下面。
運行回歸測試:
$ sudo mn --test pingpair
這條命令會創建一個小的拓撲結構,然后啟動 OpenFLow 的控制器,然后跑 ping 測試,最后再把拓撲結構跟控制器關掉。
另一種有用的試驗是iperf的(給它約10秒來完成):
還有一直常用的測試是iperf
(完成這個測試大概需要10s 鍾):
$ sudo mn --test iperf
此命令創建的相同Mininet,並在其中一台 host 上面跑 iperf server, 然后在另外一台 host 上面運行iperf client 然后解析取得帶寬情況。
更改拓撲結構大小和類型 Changing Topology Size and Type
Mininet 默認的拓撲結構是由兩台 host 以及一台交換機組成的,你可以用--topo
參數來更改拓撲結構。
假設你要在一個交換機與三台 host 之間做 ping 探測驗證(verify all-pairs ping connectivity)。:
運行回歸測試:
$ sudo mn --test pingall --topo single,3
另一個例子中,使用線性拓撲(其中每個交換機配有一個主機,並且所有的交換機連接在一起):
$ sudo mn --test pingall --topo linear,4
課喲用參數來控制拓撲結構是 Mininet 中最有用的功能之一,非常強大。
鏈路變化 Link variations
Mininet2.0允許你設置連接參數,甚至可以通過命令行實現自動化設置:
$ sudo mn --link tc,bw=10,delay=10ms
mininet> iperf
...
mininet> h1 ping -c10 h2
上面的設置每兩個節點之間的延遲是10ms,因為 ICMP 請求傳過了兩條鏈路(一次是到大交換機,一次到達主機),往返時間(RRT)就應該是40ms。
你還可以使用 PythonAPI 來做更多的事兒,不過現在我們先繼續往下演練。
調整輸出信息Adjustable Verbosity
Mininet默認輸出信息的級別是 Info
,Info
級別會輸出 Mininet的詳細信息。
我們也可以通過 -v
參數來設置輸出DEBUG
信息。
$ sudo mn -v debug
...
mininet> exit
這樣會打印出更多額外的細節。現在嘗試一下output
參數,這樣可以在 CLI 中打印更少的信息。
$ sudo mn -v output
mininet> exit
除了上面的幾個級別,還有其他的級別可以使用,比如warning
等
Custom Topologies自定義拓撲結構
在custom/topo-2sw-2host.py
中是一個例子可以拿來參考,我們可以看到通過 PythonAPI 我們可以很簡單的來定義拓撲結構。
這個例子直接連接兩台交換機,每個交換機帶有一台主機。
"""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() ) }
我們提供一個自定義的mininet 文件,就可以創建新的拓撲結構、交換機類型。
我們在命令行里面測試一下:
$ sudo mn --custom ~/mininet/custom/topo-2sw-2host.py --topo mytopo --test pingall
*** Creating network
*** Adding controller
*** Adding hosts:
h1 h2
*** Adding switches:
s3 s4
*** Adding links:
(h1, s3) (h2, s4) (s3, s4)
*** Configuring hosts
h1 h2
*** Starting controller
*** Starting 2 switches
s3 s4
*** Ping: testing ping reachability
h1 -> h2
h2 -> h1
*** Results: 0% dropped (2/2 received)
*** Stopping 2 switches
s3 ..s4 ..
*** Stopping 2 hosts
h1 h2
*** Stopping 1 controllers
c0
*** Done
completed in 1.220 seconds
ID= MAC
默認情況下,host 的 mac 地址是隨機分配的。這會導致每次 mininet 創建的時候,MAC地址都會改變,這會給調試帶來一些困難
--mac
參數可以解決上面的問題,栗子如下:
之前:
$ sudo mn
mininet> h1 ifconfig
h1-eth0 Link encap:Ethernet HWaddr c2:d9:4a:37:25:17
inet addr:10.0.0.1 Bcast:10.255.255.255 Mask:255.0.0.0
inet6 addr: fe80::c0d9:4aff:fe37:2517/64 Scope:Link
UP BROADCAST RUNNING MULTICAST MTU:1500 Metric:1
RX packets:17 errors:0 dropped:0 overruns:0 frame:0
TX packets:7 errors:0 dropped:0 overruns:0 carrier:0
collisions:0 txqueuelen:1000
RX bytes:1398 (1.3 KB) TX bytes:578 (578.0 B)
lo Link encap:Local Loopback
inet addr:127.0.0.1 Mask:255.0.0.0
inet6 addr: ::1/128 Scope:Host
UP LOOPBACK RUNNING MTU:65536 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:0
RX bytes:0 (0.0 B) TX bytes:0 (0.0 B)
使用--mac
參數:
$ sudo mn --mac
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
inet6 addr: fe80::200:ff:fe00:1/64 Scope:Link
UP BROADCAST RUNNING MULTICAST MTU:1500 Metric:1
RX packets:17 errors:0 dropped:0 overruns:0 frame:0
TX packets:8 errors:0 dropped:0 overruns:0 carrier:0
collisions:0 txqueuelen:1000
RX bytes:1414 (1.4 KB) TX bytes:676 (676.0 B)
lo Link encap:Local Loopback
inet addr:127.0.0.1 Mask:255.0.0.0
inet6 addr: ::1/128 Scope:Host
UP LOOPBACK RUNNING MTU:65536 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:0
RX bytes:0 (0.0 B) TX bytes:0 (0.0 B)
n contrast, the MACs for switch data ports reported by Linux will remain random. This is because you can ‘assign’ a MAC to a data port using OpenFlow, as noted in the FAQ. This is a somewhat subtle point which you can probably ignore for now.
XTerm Display xterm屏顯
為了方便更復雜的調試工作,可以使用 mininet 的 xterms
可以通過x
選項來給每一個 host 與交換機啟動一個xterm
。
$ sudo mn -x
后一秒鍾,在xterm終端會彈出,並且具有自動設置窗口的名稱(h1
,h2
…)。
或者,您也可以用下面的方式打開更多的xterm。
默認情況下,僅僅 host 需要一個但大戶的 namespace,而交換機的窗口則不用(與政策的終端類似)
but can be a convenient place to run and leave up switch debug commands, such as flow counter dumps.
在你想看到交互命令的時候,xterm 很有用,但是如果你僅僅想看到輸出信息,那你可能想停掉 xterm
例如:
在switch: s1 (root)
的 xterm下面運行:
# dpctl dump-flows tcp:127.0.0.1:6634
因為交換機中沒有數據流量,所以不會有信息輸出。
To use dpctl
with other switches, start up mininet in verbose mode and look at the passive listening ports for the switches when they’re created.
現在,在host: h1
的xterm中運行:
# ping 10.0.0.2
回到s1
的 xterm中查看:
# dpctl dump-flows tcp:127.0.0.1:6634
現在就可以看見數據流了。
另外我們可以直接用dpctl
命令直接調用 Mininet CLI 里面的命令,而不需要啟動任何xterm
或者指定交換機的IP 跟端口。
我們看已通過ifconfig
命令來判斷xterm 是否在root
的名字空間下,如果所有的網卡都顯示出來(包含eth0
),那他就是在root
下。
從 mininet 的 CLI中退出:
mininet>exit
這樣 mininet 的 CLI就自動關閉了。
Other Switch Types 其他類型的交換機
我們可以使用不同的交換機類型。例如:運行 user-space 交換機:
$ sudo mn --switch user --test iperf
值得注意的是這種交換機下,帶寬相比於前面的內核態交換機要小的多。
如果做 ping 探測,也會有更高的延遲,這是因為現在的數據包需要從內核態轉換到用戶空間,消耗了更多的資源。
另一方面,用戶空間的交換機會有一些新功能,如果交換機的性能不是關鍵問題是的時候。
在 Mininet 虛擬機中預裝了另外一個交換機類型是 Open vSwitch(OVS)
,在iperf
測試中,帶寬會比內核態交換機更大。
$ sudo mn --switch ovsk --test iperf
Mininet Benchmark
To record the time to set up and tear down a topology, use test ‘none’:
$ sudo mn --test none
Everything in its own Namespace (user switch only)
默認情況下,主機都放在自己的命名空間,
而交換機和控制器的root
命名空間。
我們可以通過--innamespace
參數來把交換機放在自己的名字空間中。
$ sudo mn --innamespace --switch user
Instead of using loopback, the switches will talk to the controller through a separately bridged control connection.
就其本身而言,這個選項是沒有多大用處的,但它確實提供了如何分離不同交換機的例子。
請注意,此選項不會(截至12年11月19日)與Open vSwitch的工作。
需要注意的是這個選項在Open vSwitch
中是沒法使用的(截至12年11月19日是沒法使用)
mininet>exit
Part 3: Mininet Command-Line Interface (CLI) Commands
第3部分:Mininet命令行界面(CLI)命令
Display Options
我們可以通過啟動一個最小拓撲結構,然后讓他一直運行,來來查看 mininet 的 CLI 的選項列表:
$ sudo mn
顯示選項:
mininet>help
Python Interpreter
如果在 Mininet CLI中的命令的第一個字符串是py
,那這個條命令會用 Python 來執行。
這對於擴展 Mininet,探測 mininet的內部工作機智都有幫助。
每個主機,交換機和控制器都有一個與之關聯的對象。
在Mininet命令行下運行:
mininet> py 'hello ' + 'world'
打印 locals:
mininet> py locals()
{'h2': <Host h2: h2-eth0:10.0.0.2 pid=5166> , 'net': <mininet.net.Mininet object at 0x7f7c47668ad0>, 'h1': <Host h1: h1-eth0:10.0.0.1 pid=5165> , 'c0': <OVSController c0: 127.0.0.1:6633 pid=5157> , 's1': <OVSSwitch s1: lo:127.0.0.1,s1-eth1:None,s1-eth2:None pid=5169> }
還可以通過 dir()函數來查看節點的方法和屬性:
mininet> py dir(s1)
['IP', 'MAC', 'TCReapply', '__class__', '__delattr__', '__dict__', '__doc__', '__format__', '__getattribute__', '__hash__', '__init__', '__module__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__', '__weakref__', 'addIntf', 'attach', 'checkSetup', 'cleanup', 'cmd', 'cmdPrint', 'config', 'configDefault', 'connected', 'connectionsTo', 'controlIntf', 'controllerUUIDs', 'datapath', 'defaultDpid', 'defaultIntf', 'deleteIntfs', 'detach', 'dpctl', 'dpid', 'dpidLen', 'execed', 'failMode', 'fdToNode', 'inNamespace', 'inToNode', 'intf', 'intfIsUp', 'intfList', 'intfNames', 'intfs', 'isSetup', 'lastCmd', 'lastPid', 'linkTo', 'listenPort', 'monitor', 'name', 'nameToIntf', 'newPort', 'opts', 'outToNode', 'params', 'pexec', 'pid', 'pollOut', 'popen', 'portBase', 'ports', 'read', 'readbuf', 'readline', 'sendCmd', 'sendInt', 'setARP', 'setDefaultRoute', 'setHostRoute', 'setIP', 'setMAC', 'setParam', 'setup', 'shell', 'start', 'startShell', 'stdin', 'stdout', 'stop', 'terminate', 'waitOutput', 'waitReadable', 'waiting', 'write']
您可以通過使用help()函數讀取在線文檔,查看節點上可用的方法:
mininet> py help(h1) #(按`q`退出文檔)
You can also evaluate methods of variables:
mininet> py h1.IP
<bound method Host.IP of <Host h1: h1-eth0:10.0.0.1 pid=5165> >
mininet> py h1.IP()
10.0.0.1
Link Up/Down
斷開/聯通鏈路,對於提供容錯能力的測試非常有用。
比如端口h1
與s1
之間的連接:
mininet> link s1 h1 down
你應該可以看到一個OpenFlow產生了一個的端口狀態變化通知。
重新連接h1
s1
:
mininet>link s1 h1 up
XTerm Display
要顯示h1
與 h2
的 xterm:
mininet> xterm h1 h2
Part 4: Python API Examples
在Mininet源代碼 中的示例目錄包括如何使用Mininet的Python的API,
還有一些可能有用的代碼並沒有放到主代碼庫中。
SSH daemon per host
這個栗子對於要在每台設備上啟用 ssh 服務可能很有幫助。
$ sudo ~/mininet/examples/sshd.py
在另外一個終端上,就可以ssh到任何主機並運行交互式命令:
$ ssh 10.0.0.1
$ ping 10.0.0.2
...
$ exit
退出mininet:
exit
你會想重新看看那這些栗子可以看Introduction to Mininet ,里面介紹了 Python API。
Part 5: Walkthrough Complete!
恭喜!你已經完成了Mininet演練。之后可以隨意嘗試新的拓撲結構和控制器或查看源代碼。
Next Steps to mastering Mininet
閱讀 OpenFlow 的教程
雖然你可以得到合理的利用Mininet的CLI,但是如果你掌握了 Python API,Mininet會變得更加有用和強大的。
所以去看 Mininet 的文檔
后面會解釋如何遠程控制 mininet(e.g. one running outside Mininet’s control)。
Appendix: Supplementary Information
這些都不是必需的,但你會發現它們非常有用。
Using a Remote Controller
注意:這一步是不是默認演練的一部分;如果你在mininet 之外運行一個控制器,這個附錄將有些幫助。
在 OpenFLow 的教程中介紹了可以使用controller --remote
參數來啟動一個交換機,然后你可以用SDN 控制器比如POX
, NOX
, Beacon
或者 Floodlight
之類的來控制這個交換機。
當您啟動Mininet網絡,每個交換機可以連接到控制器,無論這個控制器在哪里。
如果你本地裝有開發工具或者控制器,又或者你想在不同的物理機上面運行控制器,這種設置會非常方便。
如果你想嘗試一下這個,只需要加上 ip 或者port 就可以:
$ sudo mn --controller=remote,ip=[controller IP],port=[controller listening port]
例如,要運行POX的交換機,你可以這樣做
$ cd ~/pox
$ ./pox.py forwarding.l2_learning
在另一個窗口,啟動Mininet連接到“遠程”控制器(這實際上是在本地運行,但Mininet的控制范圍之外):
$ sudo mn --controller=remote,ip=127.0.0.1,port=6633
注意,這些其實都是默認的IP地址和端口值。
如果你制造一些流量(如h1 ping h2),
你應該能夠觀察到窗口顯示該交換機連接,而且輸出了一些流量數據。
mininet虛擬機中已經預裝了一些OpenFlow的控制器,你可以很輕松的就把這些東西搞起來。
NOX Classic
使用 mininet 的默認util/install.sh -a
並不會安裝 NOX。
如果你想安裝它,執行sudo ~/mininet/util/install.sh -x
需要注意的是NOX Classic已被棄用,可能不會在將來得到支持。
早 NOX 中運行pyswitch
來做一個回歸測試,
首先確認NOX_CORE_DIR
已經在環境變量中設置好。
首先驗證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
。
注意,此時,mn
應該由sudo -E
來調用,以保持NOX_CORE_DIR環境變量。
如果你是通過--controller remote
來遠程啟用的 nox,那就不需要加-E
參數了。
或者,你可以改變的/etc/sudoers
文件,把
Defaults env_reset
修改成
Defaults !env_reset
使運行sudo的時候的環境變量的設置不會改變。