实验1:SDN拓扑实践

一、实验要求

1.能够使用源码安装Mininet;
2.能够使用Mininet的可视化工具生成拓扑;
3.能够使用Mininet的命令行生成特定拓扑;
4.能够使用Mininet交互界面管理SDN拓扑;
5.能够使用Python脚本构建SDN拓扑。

二、实验环境

Ubuntu 20.04 Desktop amd64

三、实验要求

(一)基本要求

1.使用Mininet可视化工具,生成下图所示的拓扑,并保存拓扑文件名为学号.py。

2.使用Mininet的命令行生成如下拓扑:

a) 3台交换机,每个交换机连接1台主机,3台交换机连接成一条线。

b) 3台主机,每个主机都连接到同1台交换机上。

3.在2 b)的基础上,在Mininet交互界面上新增1台主机并且连接到交换机上,再测试新拓扑的连通性。

4.编辑(一)中第1步保存的Python脚本,添加如下网络性能限制,生成拓扑:

a) h1的cpu最高不超过50%;

b) h1和s1之间的链路带宽为10,延迟为5ms,最大队列大小为1000,损耗率50。

修改后的代码:

#!/usr/bin/env python

from mininet.net import Mininet
from mininet.node import Controller, RemoteController, OVSController
from mininet.node import CPULimitedHost, Host, Node
from mininet.node import OVSKernelSwitch, UserSwitch
from mininet.node import IVSSwitch
from mininet.cli import CLI
from mininet.log import setLogLevel, info
from mininet.link import TCLink, Intf
from subprocess import call

def myNetwork():

    net = Mininet( topo=None,
                   build=False,
                   ipBase='10.0.0.0/8')

    info( '*** Adding controller\n' )
    c0=net.addController(name='c0',
                      controller=Controller,
                      protocol='tcp',
                      port=6633)

    info( '*** Add switches\n')
    s2 = net.addSwitch('s2', cls=OVSKernelSwitch)
    s1 = net.addSwitch('s1', cls=OVSKernelSwitch)

    info( '*** Add hosts\n')
    h2 = net.addHost('h2', cls=Host, ip='10.0.0.2', defaultRoute=None)
    h3 = net.addHost('h3', cls=Host, ip='10.0.0.3', defaultRoute=None)
    h1 = net.addHost('h1', cls=Host, ip='10.0.0.1', defaultRoute=None,cpu=0.5)
    h4 = net.addHost('h4', cls=Host, ip='10.0.0.4', defaultRoute=None)

    info( '*** Add links\n')
    net.addLink(s1, s2)
    net.addLink(h1, s1, bw=10, delay='5ms', max_queue_size=1000, loss=50, use_htb=True)
    net.addLink(h2, s1)
    net.addLink(h3, s2)
    net.addLink(h4, s2)

    info( '*** Starting network\n')
    net.build()
    info( '*** Starting controllers\n')
    for controller in net.controllers:
        controller.start()

    info( '*** Starting switches\n')
    net.get('s2').start([c0])
    net.get('s1').start([c0])

    info( '*** Post configure switches and hosts\n')

    CLI(net)
    net.stop()

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

mininet运行结果:

(二)进阶要求

代码如下:

"""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 build( self ):
        "Create custom topo."
        l1 = 2
        l2 = 2*l1
        l3 = 2*l2
        switch_l1 = []
        switch_l2 = []
        switch_l3 = []
        host = []
        
        # add switches for three layers
        for switches in range(l1):
            switchName = "s"+str(switches+1)
            self.addSwitch(switchName)
            switch_l1.append(switchName)

        for switches in range(l2):
            switchName = "s"+str(switches+l1+1)
            self.addSwitch(switchName)
            switch_l2.append(switchName)

        for switches in range(l3):
            switchName = "s"+str(switches+l1+l2+1)
            self.addSwitch(switchName)
            switch_l3.append(switchName)
        
        # add hosts
        for hosts in range(2*l3):
            hostName = "h"+ str(hosts+1)
            self.addHost(hostName)
            host.append(hostName)

        # link the layer 1 and layer 2
        for i in range(l1):
            sw = switch_l1[i]
            for j in range(l2):
                self.addLink(sw,switch_l2[j])
        
        #link the layer 2 and layer 3
        for i in range(0,l2,2):
            sw1 = switch_l2[i]
            sw2 = switch_l2[i+1]
            for j in range(2*i,2*i+4):
                self.addLink(sw1,switch_l3[j])
                self.addLink(sw2,switch_l3[j])

        #link the host and layer 3
        for i in range(l3):
            sw = switch_l3[i]
            self.addLink(sw,host[2*i])
            self.addLink(sw,host[2*i+1])

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

mininet运行结果:


(三)个人总结

1.遇到的一些问题与解决方案

①步骤1中保存的py文件代码有误

  • 利用miniedit建立好拓扑关系后,保存py文件,到步骤3需要修改其代码时,发现代码并非想要的。
  • 重新查阅实验手册后,发现是保存py文件的方式有误(选择的不是Export Level 2 Script)。
  • 解决方案:重新打开miniedit建立拓扑关系,并选择Export Level 2 Script保存。问题得以解决。

②步骤3中新建的主机无法与交换机连接

  • 后来发现是addLink的第四个参数设置错误,port1已被占用,所以无法建立连接。
  • 解决方案:将第四个参数改为4,建立连接成功。问题得以解决。

③步骤3中新建的主机ping不到

  • 一开始以为是没有设置IP地址的原因,但在设置IP地址后仍然ping不到。

  • 查阅资料后发现还需要用attach打开交换机上对应的接口。

  • 解决方案:在终端输入 py s1.attach('s1-eth4')

  • 问题得以解决。

④自定义拓扑网络时报错

  • 写好代码,在终端输入命令后,提示
  • 检查后发现这是由于Python字符串与数字拼接,+作为连接符的时候,不会自动把int转换成str所导致的。
  • 解决方法:在+后面加上str,将int类型数据转化为str类型。

2.实验感想与收获

  • 本次实验有关SDN的拓扑,实验难度尚可,基础要求跟着实验要求走,很容易就解决了。比较难的是进阶部分,通过观察图例发现拓扑结构类似一棵树,于是利用了一些关于树的性质写出了代码。在本次实验的过程中还是犯了一些粗心的小毛病,例如上面提到的保存py文件的方法出错了,下次一定要更细心。

  • 通过本次实验学习到了mininet的一些基本用法,熟悉了几种基础的网络拓扑结构,同时还尝试利用编写python代码自定义了一个拓扑结构,对网络拓扑结构的建立过程有了更深刻的理解。撰写博客的过程中也熟悉了markdown的语法。

  • 期待下一次实验~

posted @ 2022-09-12 17:05  GodotX  阅读(99)  评论(0)    收藏  举报