譯者注:
這篇 Blog 是在學習 SDN 過程當中翻譯的Mininet 官方的文檔。文檔主要是介紹了 Mininet 的簡單用法。會分紅幾個部分放出來,原文。下面是正文html
首先是是命令語法node
$
這個符號表明如今處於 Linux 的shell 交互下,須要使用的是 Linux 命令mininet>
這個符號表示如今處於 Mininet 交互下,須要使用的是 Mininet 的命令#
這個符號表示的是如今處於 Linux 的 root 權限下。以上相應的狀態下下屬於對應的命令,就可以獲得正常的輸出。須要注意的是mininet>
的狀況比較特殊,須要使用 minient 的命令來進行交互。python
咱們首先來啓動 Mininet。git
鍵入如下命令來顯示Mininet的幫助信息:github
$ 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 的幫助信息。web
爲了使用 Wireshark 來查看 OpenFlow 的控制信息,咱們先打開 Wireshark 並讓他在後臺運行。docker
$ sudo wireshark &
在 Wireshark 的過濾選項中,輸入of
,而後選擇 Apply。shell
In Wireshark, click Capture, then Interfaces, then select Start on the loopback interface (lo
).bash
如今窗口上暫時應該沒有任何 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 之類的終端仿真器了,後面的演示中能夠用到。
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
這些命令查看或者殺死進程。
如今,驗證您能夠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
咱們不單能夠在主機上面運行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
若是Mininet出於某種緣由崩潰,能夠用下面命令來清理:
sudo mn -c
Mininet 能夠用於直接運行迴歸測試,不必定要切換到他的 CLI 下面。
運行迴歸測試:
$ sudo mn --test pingpair
這條命令會建立一個小的拓撲結構,而後啓動 OpenFLow 的控制器,而後跑 ping 測試,最後再把拓撲結構跟控制器關掉。
另外一種有用的試驗是iperf的(給它約10秒來完成):
還有一直經常使用的測試是iperf
(完成這個測試大概須要10s 鍾):
$ sudo mn --test iperf
此命令建立的相同Mininet,並在其中一臺 host 上面跑 iperf server, 而後在另一臺 host 上面運行iperf client 而後解析取得帶寬狀況。
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 中最有用的功能之一,很是強大。
Mininet2.0容許你設置鏈接參數,甚至能夠經過命令行實現自動化設置:
$ sudo mn --link tc,bw=10,delay=10ms mininet> iperf ... mininet> h1 ping -c10 h2
上面的設置每兩個節點之間的延遲是10ms,由於 ICMP 請求傳過了兩條鏈路(一次是到大交換機,一次到達主機),往返時間(RRT)就應該是40ms。
你還可使用 PythonAPI 來作更多的事兒,不過如今咱們先繼續往下演練。
Mininet默認輸出信息的級別是 Info
,Info
級別會輸出 Mininet的詳細信息。
咱們也能夠經過 -v
參數來設置輸出DEBUG
信息。
$ sudo mn -v debug ... mininet> exit
這樣會打印出更多額外的細節。如今嘗試一下output
參數,這樣能夠在 CLI 中打印更少的信息。
$ sudo mn -v output mininet> exit
除了上面的幾個級別,還有其餘的級別可使用,好比warning
等
在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
默認狀況下,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.
爲了方便更復雜的調試工做,可使用 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就自動關閉了。
咱們可使用不一樣的交換機類型。例如:運行 user-space 交換機:
$ sudo mn --switch user --test iperf
值得注意的是這種交換機下,帶寬相比於前面的內核態交換機要小的多。
若是作 ping 探測,也會有更高的延遲,這是由於如今的數據包須要從內核態轉換到用戶空間,消耗了更多的資源。
另外一方面,用戶空間的交換機會有一些新功能,若是交換機的性能不是關鍵問題是的時候。
在 Mininet 虛擬機中預裝了另一個交換機類型是 Open vSwitch(OVS)
,在iperf
測試中,帶寬會比內核態交換機更大。
$ sudo mn --switch ovsk --test iperf
To record the time to set up and tear down a topology, use test ‘none’:
$ sudo mn --test none
默認狀況下,主機都放在本身的命名空間,
而交換機和控制器的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
第3部分:Mininet命令行界面(CLI)命令
咱們能夠經過啓動一個最小拓撲結構,而後讓他一直運行,來來查看 mininet 的 CLI 的選項列表:
$ sudo mn
顯示選項:
mininet>help
若是在 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
斷開/聯通鏈路,對於提供容錯能力的測試很是有用。
好比端口h1
與s1
之間的鏈接:
mininet> link s1 h1 down
你應該能夠看到一個OpenFlow產生了一個的端口狀態變化通知。
從新鏈接h1
s1
:
mininet>link s1 h1 up
要顯示h1
與 h2
的 xterm:
mininet> xterm h1 h2
在Mininet源代碼 中的示例目錄包括如何使用Mininet的Python的API,
還有一些可能有用的代碼並無放到主代碼庫中。
這個栗子對於要在每臺設備上啓用 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。
恭喜!你已經完成了Mininet演練。以後能夠隨意嘗試新的拓撲結構和控制器或查看源代碼。
閱讀 OpenFlow 的教程
雖然你能夠獲得合理的利用Mininet的CLI,可是若是你掌握了 Python API,Mininet會變得更加有用和強大的。
因此去看 Mininet 的文檔
後面會解釋如何遠程控制 mininet(e.g. one running outside Mininet’s control)。
這些都不是必需的,但你會發現它們很是有用。
注意:這一步是否是默認演練的一部分;若是你在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的控制器,你能夠很輕鬆的就把這些東西搞起來。
使用 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的時候的環境變量的設置不會改變。