mininet简介(二:官网翻译)

--custom文件中添加新的CLI命令

--custom文件中很容易添加新的CLI命令:

def mycmd( self, line ):
    "mycmd is an example command to extend the Mininet CLI"
    net = self.mn
    output( 'mycmd invoked for', net, 'with line', line, '\n'  )
CLI.do_mycmd = mycmd

这会把mycmd命令添加到Mininet CLI中:

sudo mn --custom mycmd.py -v output
mininet> help mycmd
mycmd is an example command to extend the Mininet CLI
mininet> mycmd foo
mycmd invoked for <mininet.net.Mininet object at 0x7fd7235fb9d0> with line foo

请注意,添加到CLI的命令功能名称应具有do_前缀

其他例子

可以在mininet /examples中找到Mininet脚本的其他示例。

这些示例旨在具有教育意义,因为它们展示了可以使用Mininet API的不同方式。 我们鼓励您尝试阅读Python代码并自行运行示例。 如果他们由于某种原因不起作用,看看你能否找出原因!

您可能会发现其中一些(例如consoles.py)是您可以构建的有趣的演示。

特别是,您可能会发现(miniedit.py)是使用Mininet进行简单实验的特别有用的GUI。

注意:这些示例旨在作为阅读和理解的教学材料,而不是作为您可能遇到的任何问题的完整,开箱即用的解决方案。 您可以使用一些代码进行修改,但能够检查和理解代码非常重要。

了解Mininet API

在本简介的过程中,您已经了解了许多包含Mininet API的Python类,包括TopoMininetHostSwitchLink及其子类等类。将这些类划分为级别(或层)很方便,因为通常使用较低级别的API构建高级API。

Mininet的API建立在三个主要级别:

低级API:低级API由基本节点和链接类(例如主机host,交换机switch和链路link及其子类)组成,这些类实际上可以单独实例化并用于创建网络,但它有点笨拙。

中级API:中级API添加Mininet对象,该对象充当节点和链接的容器。它提供了许多方法(例如addHost()addSwitch()addLink()),用于添加节点和网络链接,以及网络配置,启动和关闭(特别是start()stop()。 )

高级API:高级API添加拓扑模板抽象,Topo类,它提供了创建可重用,参数化拓扑模板的功能。这些模板可以传递给mn命令(通过--custom选项)并从命令行使用。

了解每个API级别很有价值。通常,当您想直接控制节点和交换机时,可以使用低级API。当您想要启动或停止网络时,通常使用中级API(尤其是Mininet类)。

当您开始考虑创建完整的网络时,事情变得有趣。可以使用任何API级别创建完整的网络(如示例所示),但通常您需要选择中级API(例如Mininet.add *())或高级API(Topo.add*())来创建您的网络。

以下是使用每个API级别创建网络的示例:

低级API:结点和链路

h1 = Host( 'h1' )                                                                                                     
h2 = Host( 'h2' )                                                                                                     
s1 = OVSSwitch( 's1', inNamespace=False )                                                                             
c0 = Controller( 'c0', inNamespace=False )                                                                            
Link( h1, s1 )                                                                                                        
Link( h2, s1 )                                                                                                        
h1.setIP( '10.1/8' )                                                                                                  
h2.setIP( '10.2/8' )                                                                                                  
c0.start()                                                                                                            
s1.start( [ c0 ] )                                                                                                    
print h1.cmd( 'ping -c1', h2.IP() )                                                                                   
s1.stop()                                                                                                             
c0.stop() 

中级API:网络对象

net = Mininet()                                                                                                       
h1 = net.addHost( 'h1' )                                                                                              
h2 = net.addHost( 'h2' )                                                                                              
s1 = net.addSwitch( 's1' )
c0 = net.addController( 'c0' )                                                                                          
net.addLink( h1, s1 )                                                                                                 
net.addLink( h2, s1 )                                                                                                 
net.start()
print h1.cmd( 'ping -c1', h2.IP() )                                                                                   
CLI( net )                                                                                                            
net.stop()  

高级API:拓扑和模板

class SingleSwitchTopo( Topo ):                                                                                               
    "Single Switch Topology"                                                                                                  
    def build( self, count=1 ):                                                                                      
        hosts = [ self.addHost( 'h%d' % i )                                                                                   
                  for i in range( 1, count + 1 ) ]                                                                                
        s1 = self.addSwitch( 's1' )                                                                                           
        for h in hosts:                                                                                                       
            self.addLink( h, s1 )                                                                                             

net = Mininet( topo=SingleSwitchTopo( 3 ) )                                                                               
net.start()                                                                                                               
CLI( net )                                                                                                                
net.stop()   

如您所见,对于此示例,中级API实际上是最简单和最简洁的,因为它不需要创建拓扑类。 低级和中级API灵活且功能强大,但与高级Topo API及其拓扑模板相比,可能不太方便重用。
另请注意,在2.2.0之前的Mininet版本中,高级Topo不支持节点之间的多个链接,但是较低级别的API会支持多个链接。 目前Topo也不关心哪些开关由哪些控制器控制(您可以使用自定义Switch子类来执行此操作,如上所述。)使用中级和低级API,您可以手动启动开关 如果需要,将适当的控制器列表传递给每个交换机。

Mininet API文档

Mininet包含每个模块和API调用的Python文档字符串。 这些可以从Python的常规help()机制访问。 例如,

python
	>>> from mininet.node import Host
	>>> help(Host.IP)
	Help on method IP in module mininet.node:
	
	IP(self, intf=None) unbound mininet.node.Host method
		Return IP address of a node or specific interface.

Mininet网站http://api.mininet.org上也提供了相同的文档。
您可能希望使用doxypy自己生成HTML(和PDF)文档:

sudo apt-get install doxypy
cd ~/mininet
make doc
cd doc
python -m SimpleHTTPServer

此时,您可以将Web浏览器指向运行Mininet的主机的端口8000,并浏览每个Mininet类的文档。

性能测量

建议使用这些参数,但您可以自由使用您熟悉的任何工具。
带宽(bwm-ngethstats
延迟(使用ping
队列(使用monitor.py中的tc
TCP CWND统计信息(tcp_probe,也许我们应该将它添加到monitor.py中)
CPU使用率(全局:top或每容器cpuacct

OpenFlow与自定义路由

Mininet最强大和最有用的功能之一是它使用软件定义网络。 使用OpenFlow协议和相关工具,您可以将开关编程为使用输入它们的数据包执行几乎任何操作。 OpenFlow使像Mininet这样的仿真器更加有用,因为网络系统设计(包括使用OpenFlow的自定义数据包转发)可以轻松地传输到硬件OpenFlow交换机以进行线速操作。 可以在以下位置找到使用Mininet和OpenFlow创建简单学习交换机的教程:
https://github.com/mininet/openflow-tutorial/wiki添加链接描述

OpenFlow控制器

如果在未指定控制器的情况下运行mn命令,它将选择默认控制器,如ControllerOVSController,具体取决于可用的内容。
这等价于:

$ sudo mn --controller default

该控制器实现了一个简单的以太网学习交换机,最多可支持16个独立的交换机。
如果在脚本中调用Mininet()构造函数而未指定控制器类,则默认情况下它将使用Controller()类创建Stanford / OpenFlow引用控制器控制器的实例。 像ovs-controller一样,它将你的开关变成简单的学习交换机,但是如果你使用Mininet的install.sh -f脚本安装了控制器,那么修补后的控制器版本应该支持大量的交换机(理论上最多4096个,但是你 可能会更早地将计算资源最大化。)您还可以通过指定--controller refmn选择参考控制器。
如果要使用自己的控制器,可以轻松创建Controller()的自定义子类并将其传递给Mininet。 在mininet.controller.NOX()中可以看到一个示例,它使用作为选项传入的一组模块调用NOX classic。
以下是创建和使用自定义POX Controller子类的简单示例:

#!/usr/bin/python                                                                                      
                                                                                                       
from mininet.net import Mininet                                                                        
from mininet.node import Controller                                                                    
from mininet.topo import SingleSwitchTopo                                                              
from mininet.log import setLogLevel                                                                    
                                                                                                       
import os                                                                                              
                                                                                                       
class POXBridge( Controller ):                                                                         
    "Custom Controller class to invoke POX forwarding.l2_learning"                                     
    def start( self ):                                                                                 
        "Start POX learning switch"                                                                    
        self.pox = '%s/pox/pox.py' % os.environ[ 'HOME' ]                                              
        self.cmd( self.pox, 'forwarding.l2_learning &' )                                               
    def stop( self ):                                                                                  
        "Stop POX"                                                                                     
        self.cmd( 'kill %' + self.pox )                                                                
                                                                                                       
controllers = { 'poxbridge': POXBridge }                                                               
                                                                                                       
if __name__ == '__main__':                                                                             
    setLogLevel( 'info' )                                                                              
    net = Mininet( topo=SingleSwitchTopo( 2 ), controller=POXBridge )                                  
    net.start()                                                                                        
    net.pingAll()                                                                                      
    net.stop()   

请注意,编写上述脚本时,它也可以用作mn的自定义参数,以便与不同的拓扑和测试以及Mininet CLI一起使用:

$ sudo mn --custom poxbridge.py --controller poxbridge --topo tree,2,2 --test pingall -v output
*** Ping: testing ping reachability
h1 -> h2 h3 h4 
h2 -> h1 h3 h4 
h3 -> h1 h2 h4 
h4 -> h1 h2 h3 
*** Results: 0% dropped (0/12 lost)

如果你看一下mininet / node.pyNOX类的实现,你会发现它实际上可以接受选项,允许启动不同的模块,具体取决于传递给它的参数,来自构造函数或mn命令行。

外部OpenFlow控制器

自定义Controller()子类是自动启动和关闭控制器的最方便的方法。 创建start()stop()方法很容易,因此Mininet会根据需要自动启动和停止控制器。
(有关更多信息,请查看此博客文章。)
但是,您可能会发现将Mininet连接到已在其他位置运行的现有控制器很有用,例如LAN上的某个位置,另一个VM或笔记本电脑上。
RemoteController类充当控制器的代理,该控制器可以在控制网络上的任何地方运行,但必须手动启动和关闭,或者通过Mininet直接控制之外的其他机制启动和关闭。
你可以使用MininetRemoteController

from functools import partial
net = Mininet( topo=topo, controller=partial( RemoteController, ip='127.0.0.1', port=6633 ) )

或者,你可能会更喜欢:

net = Mininet( topo=topo, controller=lambda name: RemoteController( name, ip='127.0.0.1' ) )

甚至,这也可以:

net = Mininet( topo=topo, controller=None)
net.addController( 'c0', controller=RemoteController, ip='127.0.0.1', port=6633 )

请注意,在这种情况下,控制器controller(如主机host和交换机switch)是构造函数,而不是对象(但请参阅下面的其他信息!)您可以使用partiallambda在线创建自定义构造函数,或者您可以传入自己的函数 (必须采用name参数并返回控制器对象)或类(例如RemoteController的子类。)
您还可以创建多个控制器并创建自定义Switch()子类,根据需要连接到不同的控制器:

c0 = Controller( 'c0' )  # local controller
c1 = RemoteController( 'c1', ip='127.0.0.2' )  # external controller
cmap = { 's1': c0, 's2': c1, 's3': c1 }

class MultiSwitch( OVSSwitch ):
    "Custom Switch() subclass that connects to different controllers"
    def start( self, controllers ):
        return OVSSwitch.start( self, [ cmap[ self.name ] ] )

您还可以从mn命令行指定外部控制器:

$ sudo mn --controller remote,ip=192.168.51.101

通过传入控制器对象来滥用API

在Mininet 2.2.0及更高版本中,您可以选择传入一个Controller对象而不是一个构造器(甚至是一个对象列表。)这是因为尽管API明确指定构造函数是需要。
这允许您执行以下操作:

net = Mininet( topo, controller=RemoteController( 'c0', ip='127.0.0.1' ) )

要想获得您想要的行为,扔需要允许构造器。

多路径路由

重要的是要记住以太网桥(也称为学习交换机)将泛滥其MAC表中丢失的数据包。他们还会充斥ARP和DHCP请求等广播。这意味着如果您的网络中有环路或多个路径,它将无法与默认的ovs-controllercontroller控制器,NOX的pyswitch或POX的l2_learning一起使用,它们都充当学习交换机/以太网桥。
尽管这个问题显而易见,但它已成为一个常见问题
更新的(也是更复杂的)OpenFlow控制器确实支持多路径路由 - 请参阅控制器的文档以确定是否需要任何特殊配置。
如果您正在构建类似胖树的拓扑,您可能希望看一下使用POX实现的基本数据中心控制器RipLPOX。您可以将它用作自定义多路径路由的起点。
为了方便起见,您可能还希望实现一个自定义Controller()子类来调用RipLPOX。
或者,如果你真的大胆/疯狂,你甚至可以尝试将Mininet和POX或RipLPOX导入一个Python脚本!但你可能不想这样做。)

更新mininet

如果我们需要对Mininet进行更改或添加以修复错误或其他问题,并且您已从源代码安装Mininet,您可能希望更新Mininet的副本。 这可以使用以下两种方法之一轻松完成:
使用符号链接更新到Mininet源代码树(可以轻松更新Mininet的python代码):

cd ~/mininet
    git checkout master # assuming you want to update to the current master branch
sudo make develop # this only needs to be done initially and when mnexec.c changes
git fetch
git pull --rebase

更新将Mininet源复制到/ usr / lib / python …(允许您删除或移动Mininet源树):

cd ~/mininet
    git checkout master # assuming you want to update to the current master branch
git fetch
git pull --rebase
    sudo make install

使用Mininet的有用背景

Random list, no particular order
面向对象编程 (创建类,从类创建对象等)
导入Python模块 http://docs.python.org/tutorial/modules.html
从Python调用系统实用程序(system utilities) http://docs.python.org/library/subprocess.html
http://docs.python.org/library/os.html

https://github.com/amoffat/pbs
以您自己的格式解析输出文件 http://docs.python.org/library/re.html
将命令行参数传递给脚本 http://docs.python.org/dev/library/argparse.html
matplotlib 绘图 http://matplotlib.sourceforge.net

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值