一起学习交流~

Mininet

SDN jsq 6个月前 (04-02) 626次浏览 已收录 0个评论

Mininet

一、mininet的源码安装与验证

(1)实验环境

实验环境为Ubuntu-14.04.6-server&Ubuntu-20.04.4-desktop(server版为命令行界面,desktop版为GUI界面用以实现MiniEdit和xterm界面)

image-20220324191937314

image-20220324194458720

Mininet的安装有三种方式:一种是从网上直接下载安装好Mininet的虚拟机镜像,然后在VMware或者VirtureBox上打开Mininet虚拟机即可。这种安装方法是最简单的,但是该方法不支持最新版本的Open vSwitch。第二种是在本地安装Mininet源代码。该安装方法在安装过程中可以设置Open vSwitch的版本。第三种是安装Mininet文件包,该安装方法也不支持最新版本的Open vSwitch。推荐使用第二种安装方法(此处使用的也是第二种源码安装),安装命令即参数解释如下:

1、命令格式:

./install.sh [options]

2、参数解释:

典型的[option]主要有下面几种:

​ -a:完整安装,包括Mininet VM,还包括Open vSwitch的依赖关系、OpenFlow、Wireshark分离器和POX等。默认情况下,这些工具将被安装在home目录中.

​ -nfv:安装Mininet核心文件及依赖、OpenFlow和Open vSwitch.

​ -s mydir:使用此选项可将源代码建立在一个指定的目录中,而不是home目录。

命令 含义
install.sh -a 完整安装(默认安装在home目录下)
install.sh -s mydir -a 完整安装(安装在其他目录)
install.sh -nfv 安装Mininet+用户交换机+OVS(安装在home目录下)
install.sh -s mydir -nfv 安装Mininet+用户交换机+OVS(安装在其他目录下)
(2)Mininet源码包的获取

使用git获取:

git clone https://github.com/mininet/mininet.git     git下来的源码包默认在输入命令的当前目录下

没有git工具的先使用如下命令安装git

apt-get install git

进入mininet目录,执行以下命令,查看当前Mininet版本

cd mininet
cat INSTALL | more

进入mininet/util,执行以下命令安装Mininet

cd util
./install.sh -a

执行如下命令测试Mininet基本功能

mn --test pingall
mn --version

二、mininet拓扑构建与命令的使用

(1)网络构建参数

topo:用于指定网络拓扑,Mininet支持创建的网络拓扑为:minimal、single、linear和tree

​ minimal:创建一个交换机和两个主机相连的简单拓扑。默认无--topo的参数的情况下即创建这种简单拓扑。其内部实现就是调用了single,2对应的函数。

​ single,n:设置一个交换机和n个主机相连的拓扑

​ linear,n:创建n个交换机,每个交换机只连接一个主机,并且所有交换机成线型排列。

​ tree,depth=n,fanout=m:创建深度为n,每层树枝为m的树形拓扑

​ –cutom:在上述已有的拓扑的基础上,Mininet支持自定义拓扑,使用一个简单的Python API即可。

(2)构建实列

创建minimal拓扑

mn

root@ubuntu-mininet:~# mn
*** Creating network
*** Adding controller
*** Adding hosts:
h1 h2 
*** Adding switches:
s1 
*** Adding links:
(h1, s1) (h2, s1) 
*** Configuring hosts
h1 h2 
*** Starting controller
c0 
*** Starting 1 switches
s1 ...
*** Starting CLI:

创建single拓扑

mn --topo=single,3

root@ubuntu-mininet:~# mn --topo=single,3
*** Creating network
*** Adding controller
*** Adding hosts:
h1 h2 h3 
*** Adding switches:
s1 
*** Adding links:
(h1, s1) (h2, s1) (h3, s1) 
*** Configuring hosts
h1 h2 h3 
*** Starting controller
c0 
*** Starting 1 switches
s1 ...
*** Starting CLI:

说明:单一(Single)拓扑指整个网络拓扑中交换机有且只有一个,交换机可以下挂一个或多个主机。

创建linear拓扑

mn --topo=linear,3

root@ubuntu-mininet:~# mn --topo=linear,3
*** Creating network
*** Adding controller
*** Adding hosts:
h1 h2 h3 
*** Adding switches:
s1 s2 s3 
*** Adding links:
(h1, s1) (h2, s2) (h3, s3) (s2, s1) (s3, s2) 
*** Configuring hosts
h1 h2 h3 
*** Starting controller
c0 
*** Starting 3 switches
s1 s2 s3 ...
*** Starting CLI:

说明:线性(linear)拓扑指交换机连接呈线形排列,且每个交换机所连接主机数目只有一个

创建tree拓扑

mn --topo=tree,depth=2,fanout=2

root@ubuntu-mininet:~# mn --topo=tree,depth=2,fanout=2
*** Creating network
*** Adding controller
*** Adding hosts:
h1 h2 h3 h4 
*** Adding switches:
s1 s2 s3 
*** Adding links:
(s1, s2) (s1, s3) (s2, h1) (s2, h2) (s3, h3) (s3, h4) 
*** Configuring hosts
h1 h2 h3 h4 
*** Starting controller
c0 
*** Starting 3 switches
s1 s2 s3 ...
*** Starting CLI:

说明:数形(tree)拓扑指交换机连接成树形排列,且每个交换机所连接主机一般有多个关系使用参数depth和fanout,depth表示交换机的深度,fanout表示叶子数。

调用Python API创建自定义拓扑

此种方式将在下一小结详细讲述。

(3)内部交互命令

Mininet启动参数总结:

参数 作用
-h,–help 显示帮助信息
–switch=SWITCH 设置交换机得类型[kernel user ovsk]
–host=HOST 设置主机进程[process]
–controller=CONTROLLER 设置控制器类型[nox_dump none ref remote nox_pysw]
–topo=TOPO 设置拓扑[tree reversed single linear minimal],arg1,arg2,…argN
-c,–clean 清除拓扑并退出
–custom=CUSTOM 从.py文件中读取定制参数
–test=TEST 测试[cli build pingall pingpair iperf all iperfudp none]
-x,–xterms 为每个节点打开xterm
–mac 设置mac地址等于DPID
–arp 设置ARP对
–ip=IP 设置远程控制器得IP地址
–port=PORT 设置远程控制器的侦听端口
–link [tc bw loss delay]设置链路属性

Mininet常用命令总结:

命令 作用
help 默认列出所有命令文档,后面加命令名将介绍该命令用法。
dump 打印节点信息
gterm 给定节点上开启gonme-terminal,可能导致mn崩溃
xterm 给定接口上开启xterm
intfs 列出所有网络接口
iperf 两个节点之间进行简单的IPerf TCP测试
iperfudp 两个节点之间用制定带宽UDP进行测试
net 显示网络连接情况
pingpair 在前两个主机之间互ping测试
source 从外部文件中读入命令
link 禁用或开启两个节点之间的链路
nodes 列出所有的接口信息
pingall 所有主机节点之间互ping
py 执行Python表达式
sh 运行外部shell命令

三、mininet调用Python API创建自定义拓扑

(1)创建自定义拓扑命令格式

mn --custom custom-topo.py --topo mytopo

注:custom-topo.py为自定义拓扑的Python代码,且文件和当前目录相同时可以使用相对路径,否则使用绝对路径。
(2)Mininet Python API示例

创建一个单个交换机下挂4个主机的网络拓扑

#!/usr/bin/python                             
from mininet.topo import Topo
from mininet.net import Mininet
from mininet.util import dumpNodeConnections
from mininet.log import setLogLevel

TOPOS = {'mytopo':(lambda:SingleSwitchTopo())}

class SingleSwitchTopo(Topo):
    "Single switch connected to n hosts."
    def build(self, n=4):
        switch = self.addSwitch('s1')
        # Python's range(N) generates 0..N-1
        for h in range(n):
            host = self.addHost('h%s' % (h + 1))
            self.addLink(host, switch)

def simpleTest():
    "Create and test a simple network"
    topo = SingleSwitchTopo()
    net = Mininet(topo)
    net.start()
    print( "Dumping host connections" )
    dumpNodeConnections(net.hosts)
    print( "Testing network connectivity" )
    net.pingAll()
    net.stop()

if __name__ == '__main__':
    # Tell mininet to print useful information
    setLogLevel('info')
    simpleTest()

创建一个单个路由器接入3个网段(单一主机代替)的网络拓扑

#!/usr/bin/python

from mininet.topo import Topo
from mininet.net import Mininet
from mininet.cli import CLI

TOPOS = {'mytopo':(lambda:RouterTopo())}

class RouterTopo(Topo):
    def build(self):
        h1 = self.addHost('h1')
        h2 = self.addHost('h2')
        h3 = self.addHost('h3')
        r1 = self.addHost('r1')

        self.addLink(h1, r1)
        self.addLink(h2, r1)
        self.addLink(h3, r1)

if __name__ == '__main__':
    topo = RouterTopo()
    net = Mininet(topo = topo, controller = None) 

    h1, h2, h3, r1 = net.get('h1', 'h2', 'h3', 'r1')
    h1.cmd('ifconfig h1-eth0 10.0.1.11/24')
    h2.cmd('ifconfig h2-eth0 10.0.2.22/24')
    h3.cmd('ifconfig h3-eth0 10.0.3.33/24')

    h1.cmd('route add default gw 10.0.1.1')
    h2.cmd('route add default gw 10.0.2.1')
    h3.cmd('route add default gw 10.0.3.1')

    for h in (h1, h2, h3):
        h.cmd('./scripts/disable_offloading.sh')
        h.cmd('./scripts/disable_ipv6.sh')

    r1.cmd('ifconfig r1-eth0 10.0.1.1/24')
    r1.cmd('ifconfig r1-eth1 10.0.2.1/24')
    r1.cmd('ifconfig r1-eth2 10.0.3.1/24')

    r1.cmd('./scripts/disable_arp.sh')
    r1.cmd('./scripts/disable_icmp.sh')
    r1.cmd('./scripts/disable_ip_forward.sh')

    net.start()
    CLI(net)
    net.stop()

重要类、方法、函数、变量解释:

代码 含义
Topo Mininet拓扑的基类
build() 要在拓扑类中重写的方法。构造函数参数(n)将由Topo.init()自动传递给它。该方法创建一个模板(基本上是一个节点名称的图形和一个配置信息的数据库),然后Mininet使用该模板创建实际的拓扑。
addSwitch() 向拓扑添加交换机并返回交换机名称
addHost() 向拓扑添加主机并返回主机名称
addLink() 向Topo添加双向链接(并返回链接键,但这并不重要)。Mininet中的链接是双向的,除非另有说明。
Mininet 创建和管理网络的主要类
start() 启动网络设备
pingAll() 通过尝试让所有节点互相ping来测试连接性
stop() 关闭网络设备
(3)具体实现

输入命令mn --custom custom-topo.py --topo mytopo

*** Creating network
*** Adding controller
*** Adding hosts:
h1 h2 h3 h4 
*** Adding switches:
s1 
*** Adding links:
(h1, s1) (h2, s1) (h3, s1) (h4, s1) 
*** Configuring hosts
h1 h2 h3 h4 
*** Starting controller
c0 
*** Starting 1 switches
s1 ...
*** Starting CLI:
mininet> 

四、mininet可视化构建拓扑

Mininet可视化,直接在界面上编辑任意拓扑,生成python自定义拓扑脚本,使用Mininet可视化界面方便了用户自定义拓扑创建,为不熟悉python脚本的使用者创造了更简单的环境,界面直观,可操作性强。

Mininet 2.2.0+内置miniedit 。在mininet/examples下提供miniedit.py脚本,执行脚本后显示可视化界面,可自定义拓扑及配置属性。

(1)Miniedit可视化界面的启动

在mininet/examples执行如下命令启动Mininet可视化界面MiniEdit

./miniedit.py

image-20220326010027767

(2)建立拓扑

选择左侧的网络组件,组建拓扑

image-20220326010413684

(3)Miniedit属性配置

在控制器上进行鼠标右击长按,选择Properties即可对控制器进行配置

image-20220326010555345

在交换机上进行鼠标右击长按,选择Properties即可对交换机进行配置,交换机需配置16位的DPID

image-20220326010711467

在主机上进行鼠标右击长按,选择Properties即可对主机进行配置,主机需配置IP地址image-20220326010819480

也可对链路进行属性配置,主要配置带宽、时延、丢包率等

image-20220326010858866

(3)Miniedit运行

单击左下角“run”,即可运行设置好的网络拓扑,同时在后台可以看到相应的配置信息

运行后对交换机、主机进行右击长按,可查看交换机的bridge信息及打开Host的终端,交换机信息如下

image-20220326011907196

image-20220326011920536

(4)Miniedit保存脚本

Miniedit设置好拓扑后,可通过选择“File > Export Level 2 Script”,将其保存为python脚本,默认在mininet/examples目录下

五、mininet流表应用

(1)dpctl命令

dpctl 程序是一个命令行工具用来检测和管理 OpenFlow 数据通路,它能够显示当前的状态数据通路,包括功能配置和表中的条目,以及合适使用 OpenFlow 的内核模块,可以用来添加,删除,修改和监视 datapaths。

命令格式:dpctl

常用命令:

命令 作用
dpctl show tcp:\:6634 查看交换机端口信息基本情况
dpctl dump-flows tcp:\:6634 查看流表
dpctl add-flow in_port=1,actions=output:2 添加流表
dpctl del-flows 删除流表
tcpdump -n -i \ 抓取网卡上的数据包
(2)手动添加流表示例

使用如下python自定义拓扑文件创建拓扑

#!/usr/bin/python3
from itertools import product
from locale import setlocale
from re import s
from mininet.topo import Topo
from mininet.net import Mininet
from mininet.util import dumpNetconnections
from mininet.log import setLogLevel

TOPoS = {'mytopo':(lambda : LinearSwitchTopo())}

class LinearSwitchTopo(Topo) :
    def build(self):
        switch1 = self.addSwitch('s1')
        switch2 = self.addSwitch('s2')
        host1 = self.addHost('h1')
        self.addLink(host1, switch1)
        host2 = self.addHost('h2')
        self.addLink(host2,switch1)
        host3 = self.addHost('h3')
        self.addLink(host3,switch2)
        host4 = self.addHost('h4')
        self.addLink(host4,switch2)
        self.addLink( switch1,switch2)

def simpleTest():
    topo = LinearSwitchTopo()
    net = Mininet(topo)
    net.start
    dumpNetConnections(net.hosts)
    net.pingAll

if __name__ == '__main__':
    setLogLevel('info')
    simpleTest()

执行如下命令运行自定义脚本,并远程指定一个不存在的控制器,使交换机不受控制控制。

mn --custom custom-topo.py --topo mytopo --controller=remote,ip=127.0.0.1,port=6653

image-20220326154403138

测试无流表状态下主机间的通信:

使用命令xterm h1 h2 h3打开主机的可视化终端

image-20220326154613441

执行命令dpctl dump-flows查看当前所有交换机的flow table信息,发现交换机s1、s2中都没有流表

image-20220326154740933

在主机h2、h3中执行命令tcpdump -n -i h2/3-eth0抓取网卡上的数据包

image-20220326155203240

在主机h1中分别ping主机h2、h3

image-20220326155413725

可以看到主机h1 Ping h2和h3失败了,主机h2和h3上没有收到任何ICMP echo request packet。原理解析:ping操作时,由于拓扑里没有SDN控制器,也没有用dptcl给OpenFlow交换机添加任何flow entry,所以交换机不会做转发决定,并直接丢弃h1到h2及h1到h3的ping包。

执行如下命令为所有交换机添加流表

dpctl add-flow in_port=1,actions=output:2
dpctl add-flow in_port=2,actions=output:1

image-20220326161024026

执行命令dpctl dump-flows  查看交换机流表,两条flow entry添加成功。

image-20220326161651025

image-20220326180408829

添加协议流表使h1、h2通信

执行dpctl del-flows 删除之前添加的流表。

执行如下命令添加两条traffic类型为IPv4(0x0800)协议相关的flow entry,并查看下发的流表。

dpctl add-flow dl_type=0x0800,nw_dst=10.0.0.2,actions=output:2
dpctl add-flow dl_type=0x0800,nw_dst=10.0.0.1,actions=output:1
dpctl dump-flows

image-20220326234455745

在主机h1中ping主机h2、h3发现无法ping通

image-20220326234812739

原理解析:用dpctl对交换机添加flow,让交换机把所有EtherType为0x0800(IPv4)并且destiation IP为10.0.0.2的traffic从s1-eth2这个端口发出去。用dpctl对交换机添加flow,让交换机把所有EtherType为0x0800(IPv4)并且destiation IP为10.0.0.1的traffic从s1-eth1这个端口发出去。但处在同一网段下的主机,它们之间的交流是L2 forwarding,需要靠ARP来解析MAC地址,之前只匹配了0x0800(IPv4)协议,并没有匹配到0x0806(ARP),这样当交换机收到h1的ARP包后,因为没有控制器,flow table里面也没有相应的flow告诉它如何转发这个ARP包,交换机只能将它丢弃,从而导致h1 ping h2失败,所以需要添加ARP协议的流表来使通信。

执行命令dpctl add-flow dl_type=0x0806,actions=NORMAL 添加ARP(0x0806)协议相关的流表,让交换机以NORMAL形式(即广播)将所有ARP包从各个端口广播出去。

image-20220326235925197

在主机h1中ping主机h2、h3

image-20220327000040060

(3)控制器下发流表协议实例

在OpenDaylight虚拟机中布置好ODL控制器环境(ODL控制器环境的搭建见ODL文章)

在Mininet虚拟机中执行命令wireshark 开启wireshark抓包工具,监听网卡any上的数据流量

image-20220331183130741

创建Python自定义拓扑脚本文件custom-topo.py,代码如下:

#!/usr/bin/python3
from itertools import product
from locale import setlocale
from re import s
from mininet.topo import Topo
from mininet.net import Mininet
from mininet.util import dumpNetconnections
from mininet.log import setLogLevel

TOPoS = { 'mytopo ' : (lambda : LinearSwitchTopo())}

class LinearSwitchTopo(Topo) :
    def build(self):
        switch1 = self.addSwitch('s1')
        switch2 = self.addSwitch('s2')
        host1 = self.addHost('h1')
        self.addLink(host1, switch1)
        host2 = self.addHost('h2')
        self.addLink(host2 , switch1)
        host3 = self.addHost('h3')
        self.addLink(host3 , switch2)
        host4 = self.addHost('h4')
        self.addLink(host4,switch2)
        self.addLink(switch1,switch2)

def simpleTest():
    topo = LinearSwitchTopo()
    net = Mininet(topo)
    net.start
    dumpNetConnections(net.hosts)
    net.pingAll

if __name__ == '__main__':
    setLogLevel( 'info ' )
    simpleTest( )

执行如下命令通过mn命令执行自定义脚本,并远程指定控制ODL的IP地址

mn --custom custom-topo.py --topo mytopo --controller=remote,ip=192.168.130.134,port=6653 --switch ovs,protocols=OpenFlow13

执行命令pingall验证Mininet中虚拟主机的连通性

image-20220331184440286

执行dpctl dump-flows查看交换机上的流表

image-20220331192208714

可以在Wireshark上看到openflow_V4协议数据包

image-20220331185527373

登录ODL控制器,打开浏览器输入URL地址http://127.0.0.1:8181/index.html,登录控制的web页面查看拓扑。

image-20220331185950945

OpenFlow协议解析

首先发送HELLO消息,建立初始化连接,协商使用的OpenFlow协议版本。由下图可知,ODL与Mininet之间应用的是OpenFlow1.0版本协议。

image-20220331235011322

OpenFlow版本协商完成后,控制器发送一条features_request消息获取交换机的特性信息,包括交换机的ID(DPID)、缓冲区数量、端口及端口属性等等。相应的,交换机回复features_reply消息。

image-20220331235144628

ofpt_feature_reply数据包详情如下,交换机的DPID是数据通道独一无二的标识符。本实验中交换机缓冲区数量(n_buffers)为256,交换机支持的流表数量(n_tables)为254,交换机所支持的功能,如下所示。

image-20220331235239146

当交换机收到数据包后查找流表无匹配项时,将数据包封装在packet_in消息发给控制器,由控制器通过packet_out消息下发决策,使发送和接收数据包的两主机间进行通信。

image-20220331235418029

image-20220331235518577

flow mod消息涉及流表项的下发匹配信息,下图显示的是flow mod匹配项的类型信息。

image-20220331235552246

(4)Mininet多数据中心网络拓扑流量带宽实现
步骤1:在mininet源码中加入测试程序

执行命令在mkdir -p /home/sdnlab/log,命令添加目录/home/sdnlab/log

在mininet/mininet/有个net.py文件,我们打开它在其中的Mininet类中添加iperf_single()函数,实现在两个主机间进行iperf udp测试,并且在server端记录,代码如下

def iperf_single(self,hosts=None,udpBw='10M',period=60,port=5001):
        """Run iperf between two hosts using UDP.
           hosts:list of hosts; if None,uses opposite hosts
           returns:results two-element array of server and client speeds"""
        if not hosts:
            return
        else:
            assert len(hosts) == 2
        client, server = hosts
        filename = client.name[1:] + '.out'
        output('*** Iperf: testing bandwidth between ')
        output("{} and {}\n".format(client.name,server.name))
        iperfAgrs = 'iperf -u '
        bwAgrs = '-b ' + udpBw + ' '
        print("***start server***")
        server.cmd(iperfAgrs + '-s -i 1' + ' > /home/sdnlab/log/' + filename + '&')
        print("***start client***")
        client.cmd(iperfAgrs + '-t ' + str(period) + ' -c ' + server.IP() + ' ' + bwAgrs + ' > /home/sdnlab/log/' + 'client' + filename + '&')

image-20220402232921364

在Mininet类中添加自定义命令iperfmulti()函数,iperfmulti函数主要是实现依次为每一台主机随机选择另一台主机作为iperf的服务器端,通过调用iperf_single,自身以客户端身份按照指定参数发送UDP流,服务器生成的报告以重定向的方式输出到文件中,使用iperfmulti命令,主机随机地向另一台主机发起一条恒定带宽的UDP数据流。代码如下

def iperfMulti(self,bw,period=60):
        base_port = 5001
        server_list =[]
        client_list = [h for h in self.hosts]
        host_list = []
        host_list = [h for h in self.hosts]

        cli_outs = []
        ser_outs = []

        _len = len(host_list)
        for i in range(0,_len):
            client = host_list[i]
            server = client
            while( server == client ):
                server = random.choice(host_list)
            server_list.append(server)
            self.iperf_single(hosts= [client,server],udpBw=bw,period=period,port=base_port)
            sleep(.05)
            base_port += 1

        sleep(period)
        print("test has done")

image-20220402233028989

其次,/mininet/mininet/中还有个cli.py文件,用于注册命令,我们在其中注册iperfmulti命令

def do_iperfmulti(self,line):
        args = line.split()
        if len(args) == 1:
            udpBw = args[0]
            self.mn.iperfMulti(udpBw)
        elif len(args) == 2:
            udpBw = args[0]
            period = args[1]
            err = False
            self.mn.iperfMulti(udpBw,float(period))
        else:
            error( 'invalid number of args: iperfmulti udpBw period\n' +
                   'udpBw examples: 1M 120\n' )

image-20220402233246636

完成这些后,我们在/mininet/bin/mn文件中加入iperfmulti可执行命令,如下所示:

TESTS = { name: True
          for name in ( 'pingall', 'pingpair', 'iperf', 'iperfudp' ,'iperfmulti') }

CLI = None  # Set below if needed

# Locally defined tests
def allTest( net ):
    "Run ping and iperf tests"
    net.start()
    net.ping()
    net.iperf()
    net.iperfmulti()

ALTSPELLING = { 'pingall': 'pingAll', 'pingpair': 'pingPair',
                'iperfudp': 'iperfUdp' ,'iperfmulti':'iperfMulti' }

随后,我们在/mininet/util下重新编译Mininet的核心组件

./install.sh -n

使用mn命令创建一个topo,发现iperfmulti命令已经存在

image-20220402233815882

步骤二、构建多数据中心网络拓扑

利用mininet Python API创建数据中心拓扑

vim fattree.py

代码如下:

#!/usr/bin/python
"""Custom topology example
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 re import S
import sunau
from mininet.topo import Topo
from mininet.net import Mininet
from mininet.node import RemoteController,CPULimitedHost
from mininet.link import TCLink
from mininet.util import dumpNodeConnections
from mininet.log import setLogLevel
from itertools import product
from locale import setlocale

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

class MyTopo( Topo ):
        "Simple topology example."
        def build(self):
                "Create custom topo."
                # Initialize topology
                # Topo.__init__( self )
                L1 = 2
                L2 = L1 * 2 
                L3 = L2
                c = []
                a = []
                e = []

                # add core ovs  
                for i in range( L1 ):
                        sw = self.addSwitch( 'c{}'.format( i + 1 ) )
                        c.append( sw )

                # add aggregation ovs
                for i in range( L2 ):
                        sw = self.addSwitch( 'a{}'.format( L1 + i + 1 ) )
                        a.append( sw )

                # add edge ovs
                for i in range( L3 ):
                        sw = self.addSwitch( 'e{}'.format( L1 + L2 + i + 1 ) )
                        e.append( sw )

                # add links between core and aggregation ovs
                for i in range( L1 ):
                        sw1 = c[i]
                        for sw2 in a[:]:
                                # self.addLink(sw2, sw1, bw=10, delay='5ms', loss=10, max_queue_size=1000, use_htb=True)
                                self.addLink( sw2, sw1 )

                # add links between aggregation and edge ovs
                for i in range( 0, L2, 2 ):
                        for sw1 in a[i:i+2]:
                                for sw2 in e[i:i+2]:
                                        self.addLink( sw2, sw1 )

                #add hosts and its links with edge ovs
                count = 1
                for sw1 in e:
                        for i in range(2):
                                host = self.addHost( 'h{}'.format( count ) )
                                self.addLink( sw1, host )
                                count += 1

def simpleTest():
        topo = MyTopo()
        net = Mininet(topo)
        net.start
        # dumpNodeConnections(net,hosts)
        net.pingAll

if __name__ == '__main__':
        setLogLevel('info')
        simpleTest()

Mininet创建网络拓扑的代码中,可以通过改变代码中定义的L1变量来设置核心交换机的数量,并通过添加额外的交换机和链路来构成更复杂的数据中心网络拓扑。随着边缘交换机的增加,主机个数也随之增长,利用Mininet的易用性和扩展性,可以创建基于多种数据中心场景下的网络拓扑,达到更好更全面的实验效果。

随后利用写好的Python文件生成测试拓扑,命令如下

mn --custom fattree.py --topo mytopo --controller=remote,ip=192.168.130.134,port=6653 --switch ovsk,protocols=OpenFlow10

image-20220402234433915

用pingall命令测试主机间的连通性

image-20220402234522017

登录控制器的web界面查看网络拓扑

image-20220402234608037

步骤三:测试TCP网络带宽

在mininet主机下执行命令iperf h1 h2 测试同一交换机内部的主机间连通性及通信带宽。

image-20220402234844987

在mininet主机下执行命令iperf h1 h3 测试相同汇聚交换机下不同机架的主机间连通性及通信带宽。

image-20220402234919733

在mininet主机下执行命令iperf h1 h5 测试相同核心交换机不同汇聚交换机下的主机间连通性及通信带

image-20220402235007995

在mininet主机下执行命令iperfmulti 0.025M 设置带宽参数为0.025M,将能看到8台主机随机地向另外一台主机发送数据包。

image-20220402235211970

在/home/sdnlab/log下可以看到iperfmulti的数据记录

image-20220402235335197

查看服务端数据记录:

image-20220402235448386

查看客户端数据记录

image-20220402235538380

喜欢 (7)
订阅评论
提醒
guest
0 评论
内联反馈
查看所有评论