Mininet是一款非常轻巧但是功能很强大的网络模拟器。网络研究者可以使用Mininet创建支持OpenFlow的SDN拓扑。随着SDN研究的发展,多控制器协作成为未来的研究方向,所以使用Mininet构建多控制器网络拓扑也成为一种需求。本篇将讲述如何使用Mininet搭建多控制器网络拓扑。

Multi-Controller

多控制器有两种理解,一种理解是面向交换机的多控制器。即一个交换机会连接多个控制器,控制器之间的关系可以是equal,也可以是master/slave模式。关于多控制器的介绍,有兴趣的读者可以参考OpenFlow1.3协议的multi-controller部分内容。另一种理解是面向控制器的多控制器。即,多个控制器分别管理各自的数据平面网络,且数据平面之间有链路互联。这种模式下,控制器之间没有关系,控制器所控制的数据平面也没有关系。关于多控制器方面的研究,笔者会在后续的博客中大篇幅介绍。

本篇将针对这两种理解,介绍如何搭建多控制器的Mininet拓扑。

面向交换机的多控制器网络拓扑

对于一个交换机而言,可以连接多个控制器,其实现方式非常简单, 在Mininet的源码中已经实现。从Mininet的node.py文件中,我们可以找到有用的代码:

    def start( self, controllers ):
            """Start OpenFlow reference user datapath.
               Log to /tmp/sN-{ofd,ofp}.log.
               controllers: list of controller objects"""
            # Add controllers
            clist = ','.join( [ 'tcp:%s:%d' % ( c.IP(), c.port )
                                for c in controllers ] )
            ofdlog = '/tmp/' + self.name + '-ofd.log'
            ofplog = '/tmp/' + self.name + '-ofp.log'
            intfs = [ str( i ) for i in self.intfList() if not i.IP() ]
            self.cmd( 'ofdatapath -i ' + ','.join( intfs ) +
                      ' punix:/tmp/' + self.name + ' -d %s ' % self.dpid +
                      self.dpopts +
                      ' 1> ' + ofdlog + ' 2> ' + ofdlog + ' &' )
            self.cmd( 'ofprotocol unix:/tmp/' + self.name +
                      ' ' + clist +
                      ' --fail=closed ' + self.opts +
                      ' 1> ' + ofplog + ' 2>' + ofplog + ' &' )
            if "no-slicing" not in self.dpopts:
                # Only TCReapply if slicing is enable
                sleep(1)  # Allow ofdatapath to start before re-arranging qdisc's
                for intf in self.intfList():
                    if not intf.IP():
                        self.TCReapply( intf )

start函数发起了交换机到控制器的网络连接。传入的参数controllers是一个可迭代的数组,clist是整合之后的控制器信息,包括控制器的IP和控制器的端口。之后调用self.cmd函数启动连接,连接到控制器。

start函数在UserSwitch和OVSSwitch等交换机类中均有对应实现。所以,只需在启动交换机时,传入对应的控制器列表即可。

关键代码举例如下:

    net = Mininet(controller=None, switch=OVSSwitch, link=TCLink)
    s1 = net.addSwitch('s1')
    controller_list = []

    for i in xrange(3):
        name = 'controller%s' % str(i)
        c = net.addController(name, controller=RemoteController,
                          port=6661 + i)
        controller_list.append(c)

    s1.start(controller_list)

其余代码如头文件引入,主函数等请参考后续示例代码。

面向控制器的多控制器网络拓扑

面向控制器的多控制器网络拓扑定义了多个交换机,并使其分别连接到不同的控制器,从而完成拓扑搭建。在下列示例代码中,我们定义了7个网络分别连接到7个控制器,每一个网络中有5个全连接的交换机,不同网络之间还有链路,使得7个网络彼此联通。代码比较简单,不再赘述,读者可自行阅读。

    #!/usr/bin/python

    """
        This example create 7 sub-networks to connect 7  domain controllers.
        Each domain network contains at least 5 switches.
        For an easy test, we add 2 hosts for one switch.
        So, in our topology, we have at least 35 switches and 70 hosts.
        Hope it will work perfectly.
    """

    from mininet.net import Mininet
    from mininet.node import Controller, RemoteController, OVSSwitch
    from mininet.cli import CLI
    from mininet.log import setLogLevel, info
    from mininet.link import Link, Intf, TCLink
    from mininet.topo import Topo
    import logging
    import os


    def multiControllerNet(con_num=7, sw_num=35, host_num=70):
        "Create a network from semi-scratch with multiple controllers."
        controller_list = []
        switch_list = []
        host_list = []

        net = Mininet(controller=None, switch=OVSSwitch, link=TCLink)

        for i in xrange(con_num):
            name = 'controller%s' % str(i)
            c = net.addController(name, controller=RemoteController,
                                  port=6661 + i)
            controller_list.append(c)
            print "*** Creating %s" % name

        print "*** Creating switches"
        switch_list = [net.addSwitch('s%d' % n) for n in xrange(sw_num)]

        print "*** Creating hosts"
        host_list = [net.addHost('h%d' % n) for n in xrange(host_num)]

        print "*** Creating links of host2switch."
        for i in xrange(0, sw_num):
            net.addLink(switch_list[i], host_list[i*2])
            net.addLink(switch_list[i], host_list[i*2+1])

        print "*** Creating interior links of switch2switch."
        for i in xrange(0, sw_num, sw_num/con_num):
            for j in xrange(sw_num/con_num):
                for k in xrange(sw_num/con_num):
                    if j != k and j > k:
                        net.addLink(switch_list[i+j], switch_list[i+k])

        print "*** Creating intra links of switch2switch."

        # 0-4  5-9 10-14 15-19 20-24 25-29 30-34
        # domain1 -> others
        net.addLink(switch_list[4], switch_list[6])
        net.addLink(switch_list[4], switch_list[10])
        net.addLink(switch_list[1], switch_list[15])
        net.addLink(switch_list[1], switch_list[20])

        # domain2 -> others
        net.addLink(switch_list[6], switch_list[10])
        net.addLink(switch_list[8], switch_list[12])
        net.addLink(switch_list[8], switch_list[18])
        net.addLink(switch_list[7], switch_list[25])

        # domain3 -> others
        net.addLink(switch_list[10], switch_list[16])
        net.addLink(switch_list[12], switch_list[16])
        net.addLink(switch_list[10], switch_list[21])
        net.addLink(switch_list[12], switch_list[27])

        # domain4 -> others
        net.addLink(switch_list[16], switch_list[21])
        net.addLink(switch_list[18], switch_list[27])
        net.addLink(switch_list[18], switch_list[31])
        net.addLink(switch_list[19], switch_list[34])

        # domain5 -> others
        net.addLink(switch_list[21], switch_list[27])
        net.addLink(switch_list[23], switch_list[31])

        # domain6 -> others
        net.addLink(switch_list[25], switch_list[31])
        net.addLink(switch_list[27], switch_list[32])

        #domain7 has not need to add links.

        print "*** Starting network"
        net.build()
        for c in controller_list:
            c.start()

        _No = 0
        for i in xrange(0, sw_num, sw_num/con_num):
            for j in xrange(sw_num/con_num):
                switch_list[i+j].start([controller_list[_No]])
            _No += 1

        #print "*** Testing network"
        #net.pingAll()

        print "*** Running CLI"
        CLI(net)

        print "*** Stopping network"
        net.stop()

    if __name__ == '__main__':
        setLogLevel('info')  # for CLI output
        multiControllerNet(con_num=7, sw_num=35, host_num=70)

总结

Mininet功能很强大,基本可以满足日常的科研需求。更多的参考案例,可查看mininet的examples目录。最后,简单的启动脚本可以供参考。该脚本可以启动7个窗口,分别在不同的端口上启动7个ryu控制器,从而使得7个网络的交换机可以连接到对应的网络。

    for i in $(seq 1 7);
        do
        let port=i+6660
        xterm -title "app$i" -hold -e ryu-manager ryu/app/simple_switch_13 --ofp-tcp-listen-port=$port &
        done

希望自己的研究能够顺利进行,最终面世。


Fattree topo and iperfmulti function in mininet

2015-02-22 by muzi

This article will show you 1)how to build a fattree topo and 2)how to extend the iperfmulti function in mininet.

本篇博文将讲述1)如何搭建fatree网络拓扑和2)如何在mininet中拓展iperfmulti功能。

众所周知,数据中心是目前网络研究的一个热门领域。随着云计算的兴起与发展,会对数据中心网络提出更多的需求,也为学术研究提供了更多的课题。TE(Traffic Engineering)是网络研究中最基础的研究之一,在TE中Load balance是比较主要的研究内容之一。 然而由于数据中心网络的流量走势与传统网络不同,导致数据中心网络与传统网络的架构有所不同。在传统网络中上下行流量在总流量中占据很大比重,而相比之下,数据中心的流量分类中,横向流量的比重要远远大于传统网络架构的比重。为了更好解决数据中心网络流量问题,数据中心架构的设计就变得非常重要,在众多网络架构中,Fat-tree架构是比较出名和成功的。

SDN兴起于校园网,盛开于数据中心,这是一种比较准确的描述。目前SDN的研究领域内 ...

read more

sFlow入门初涉

2014-11-21 by muzi

前言

sFlow是一个应用在高速交换网络中的监控软件。sFlow需要交换机支持才能使用,万幸OpenvSwitch支持这个功能。netflow同样也是类似功能的软件,可惜没有接触过,也只是听过名字而已。第一次接触到sFlow之后,就觉得很感兴趣,跟着SDNLAB的教程做了一遍之后,记录下自己的学习过程。

安装sFlow

下载sFlow代码:

http://pan.baidu.com/s/1mgmOVck

解压缩,安装:

tar -zxvf sflow.tar.gz
cd sflow/sflow-rt
./start.sh

此时通过浏览器127:0.0.1:8008可以查看到生成的页面。

实验步骤

本实验步骤将介绍如何在一台机器上完成sflow流量监控实验。实验需要运行一个控制器,可以使用mininet自带的控制器,也可以使用RYU等控制器。然后运行mininet,设置OVS的sFlow功能,从而从8008端口上查看到相应的数据。

启动mininet ...

read more

OpenvSwitch2.3.0 and Mininet install

2014-11-02 by muzi

前言

折腾了我两个周的事情是一定要写出来的,后来人就不用继续掉坑里了。在此感谢@南京-小L的帮助。

安装OpenvSwitch2.3.0

不需要安装。但是友情提供一键安装脚本:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40 ...
read more

【原】基于mininet的OpenFlow拓展性拓扑搭建

2014-03-11 by muzi

前言

我们普遍情况下,都是单一控制器去控制一个网络。但是如果多控制器呢?我们如何实现多控制情况下的通信要求呢?

这有点难度!需要一些东西向的协议来实现控制器之间的数据共享与交换。不是我一个人一两天能搞定的事情。且不同控制器对拓扑信息等存储方式不一样,需要一个统一的标准就显得比较困难。我们先不去想太多。首先,我们需要完成的第一项工作就是数据平面上,不同控制器之间的网络可以相互通信。

最简单的通信莫过于ping了!

实验目的

使用mininet搭建两个独立的网络,分别属于不同的控制器。同时,底层数据平面可以相互ping通。这就是我们这个实验的目的。

拓扑搭建

底层拓扑搭建我们使用mininet2.0,因为mininet1.0版本好像没有link文件,也没有intf类。也许是我没有找到吧。

以下的代码的作用在于创建一个OVS的网络,并使虚拟机的某个(无ip)网卡连接到这个网中。

直接上代码:

\#!/usr/bin/python
"""
    This is a topu of our test. It shows that how to add an ...
read more