mininet学习记录

为了以后方便写文档,把途中学习到的东西暂时的先记录下来。

一.安装mininet

在安装中遇到了几个问题,首先是在中文版的ubutun下安装mininet报错,报错信息也没有太大看懂,于是就重新装了一个英文版的Ubuntu系统,在安装的过程中倒是没有出现太大的问题。

使用的是官网中的第二中方法进行安装的:

1.安装git以及下载mininet

sudo apt install git 

git clone git://github.com/mininet/mininet

2.查看mininet中存在版本

cd mininet
git tag  # list available versions
git checkout -b 2.2.1 2.2.1  # or whatever version you wish to install
cd ..

记得cd.. 要把目录退出到mininet文件夹之外。

3.使用命令安装mininet

mininet/util/install.sh -nfv

我的需求参数-nfv就能够满足了,这三个参数代表了安装mininet,OpenFlow reference switch以及 Open vSwitch

顺道把嗅探器OpenFlow wireshark 给安装了

mininet/util/install.sh -h

4.验证是否安装成功:

在验证之前,先把linux中的一些网络管理工具下载好,主要是ifconfig这个工具,不然也会报错。

sudo apt install net-tools
sudo mn --test pingall

若是输出了默认网络之间相互ping的信息,则证明安装成功了。

记录一个小问题,在安装的过程中,git clone的速度不知道为啥突然很慢,于是直接在mininet的github主页下载了其安装包并解压后,当时也是直接按照上面的流程给安装了,但是出现了问题,说找不到mininet这个文件夹。后来发现下载的安装包的名字是mininet-master,所以把名字改回mininet就好了。

 

二.mininet的初步使用

首先把mininet在github上的introduction和官网上的walkthrough都浏览了一遍,大概了解了mininet的工作流程,把需要用到的几个重要的部分大概的描述一下。

1. 进入到mininet

sudo mn 

一切运行mn的指令都必须在sudo的操作下才能够进行,该指令打开了一个mininet默认的拓扑结构,两个主机和一个交换机。

接着就进入到了mininet的操作界面,在此界面下可以进行的基本操作:

mininet> help    展示出mininet的一些基本指令和使用介绍
mininet> nodes   展示出拓扑中所有的节点
mininet> net     展示出拓扑中节点以及接口的链接情况
mininet> dump    展示出所有节点的具体信息:ip和接口

2. mininet中的bash操作

若想要对其中的一个节点执行bash操作,只需要在mininet之前加入该节点的名称即可,如要查看节点h1和s1的网络配置:

mininet> h1 ifconfig -a
mininet> s1 ifconfig -a

这里有个点需要注意,因为在mininet中默认host建立时是独立的namespace,而交换机的namespace是和linux内核的root namespace共享的。所以在h1的ifconfig中会看到自己的h1-eth0,但是你在本机上ifconfig时,是无法查看到的,而s1的ifconfig信息与本地主机的ifconfig信息是一样的,namespace主要是隔离网络以及其它资源,具体可参考linux中命名空间以及mininet命名空间应用 。

因为命名空间的使用,可以让mininet中虚拟出的host能够配置自己的网络环境,并且不同host之间是相互独立的,但是每次关闭的时候原来配置的host网络环境就消失了,这是因为mininet中虚拟的host只是其中的一个进程,随着进程的关闭,host消失了,自然网络配置也消失了。

其他的bash操作也可以类似于上面的操作,如一些基本的bash操作:ps -a,ls,cat,route等。

3. mininet中测试节点间的连通性

利用ping 操作来进行连通性检查,如检查h1与h2之间的连通:

h1 ping -c 1 h2

由于是第一次的建立两个host之间的通信,会有一个ARP来寻找目的主机MAC的过程,所以会比较慢,但是这个过程会被记录下来,第二次的两个host之间的ping就会快很多。

当然两个主机之间是可以通信的,若是在h1上运行一个简单的HTTP服务时,h2可以去获取h1的服务。

mininet> h1 python -m SimpleHTTPServer 80 &
mininet> h2 wget -O - h1
...
mininet> h1 kill %python

4.在本机的命令行bash上的操作

$ sudo mn --test pingpair  测试拓扑之间的连接,没有写具体拓扑则为默认拓扑
$ sudo mn --test iperf     测试拓扑节点间的带宽
$ sudo mn --test pingall --topo single,3  修改了拓扑,并测试拓扑的连通性
$ sudo mn --test pingall --topo linear,4  与上一样
$ sudo mn -x               打开所有节点的bash框

也可以在bash命令中修改链路之间的参数,如延迟和带宽:

 $ sudo mn --link tc,bw=10,delay=10ms
 mininet> iperf
 ...
 mininet> h1 ping -c10 h2

当然这个修改在Python的API中更加容易修改,笔者偏向于在Python的API中修改。

5.自定义拓扑规则

在第4个小节中使用到的拓扑都是mininet内置的,可能满足不了平常工作的需求,于是需要自定义一些拓扑,并且也可以在bash中进行执行,自定义如下,程序写入在custom/topo-2sw-2host.py文件中:

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() ) }

注意最后那个字典,topos是规定的,其中的key可以修改,但是在bash中需要用到该key。在bash中的使用如下:

$ sudo mn --custom ~/mininet/custom/topo-2sw-2host.py --topo mytopo --test pingall

MAC地址也是很重要的一个参数,因为在mininet运行时,对host和switch的mac是随机生成,在调试中就会遇到很大的问题,所以给在bash命令中加入--mac这个参数,让mininet按顺序的给host安排mac地址,当然也可以在Python API中设置对应的MAC。

6.mininet中使用Python语句

在建立拓扑之后,mininet命令行中可以通过在开头加入py来进行执行Python语句

mininet> py 'hello ' + 'world'
mininet> py locals()       打印出所有的变量
mininet> py dir(s1)        打印出s1的所有可用的属性和函数
mininet> py h1.IP()        查看h1的Ip

6. 使用ssh进行host之间的连接

测试运行mininet自带例子中的ssh.py,构造的拓扑结构为1个switch和4个hosts。在利用scp函数进行在两个host之间传输数据:

$ sudo ~/mininet/examples/sshd.py

打开了host2的xterm,从而使用scp来把host2 的Download底下一个structure1_1文件传输到host1中用户john的/home/john下。

scp /Download/structure1_1 [email protected]:/home/john

在使用该指令时出现了几次错误,首先是没有注意到需要传输文件的权限,把它改成了777的权限;然后是没有注意到传输到目的文件夹的权限,刚开始传的地方设置的是/etc底下,john没有这个权限,于是改成了/home/john底下,就存在权限了。

还有一个问题就是,不知道为啥不能够直接以root的用户传输,一直显示密码错误,但是都改了好几次的密码,还是显示密码错误,于是只能通过john用户进行保存了文件了。

还有一个有趣的事情是,所有的host都是使用相同的文件系统。而且我自己编写的拓扑结构不知道为嘛不能进行ssh连接,显示connect refuse,有时间需要对这个ssh.py文件好好看一下。

 

三.mininet的可视化操作

其实就是运行了mininet自带例子中的一个miniedit.py文件,然后生成了一个GUI,在此GUI上进行拓扑结构的画图就ok了,开始我话的一个拓扑图如下:

 

    mininet学习记录_第1张图片

有两个网段:ws和h1-h3,只要设置好两个网段之间的IP和默认路由就OK了,然后在r1中打开转发机制就能够相互ping通了,但是不能够进行ssh的链接。对于r1:需要设置,sysctl ipv4.ip_forward=1,开启转发机制。

但是设置对于r1来说设置路由的话需要在命令行中设置,所以需要用ifconfig 来修改IP,route add 来增加路由信息。

四.Python API的使用

对于有一定Python基础来说,更加喜欢使用Python的API来编写结构,并且设置各类参数,以及设置路由和开启转发机制,都能够在Python脚本中实现,所以显得更加容易操作。并且按照官网分成了低级接口、中级接口和高级接口。笔者还是需要使用高级接口,下面Python代码是实现GUI画出的拓扑图:

 

from mininet.topo import Topo
from mininet.net import Mininet
from mininet.node import Node
from mininet.log import setLogLevel, info
from mininet.cli import CLI


class NetworkTopo(Topo):
    def build(self, **_opts):
        default_IP1 = '192.168.100.254/24'
        default_IP2 = '192.168.1.100/24'
        client_IP1 = '192.168.1.101/24'
        edge1 = '192.168.100.10/24'
        edge2 = '192.168.100.20/24'
        edge3 = '192.168.100.30/24'
        edge_GW = '192.168.100.254'
        client_GW = '192.168.1.100'
        # add the routers
        r1 = self.addNode('r1', ip=default_IP1)
        s1 = self.addSwitch('s1')
        self.addLink(s1, r1, bw=10, delay='5ms',loss=10,intfName2='r1-eth0',
                     params2={'ip': default_IP1})
        h1 = self.addHost('h1', ip=edge1, defaultRoute=edge_GW,mac='00:00:00:00:00:01')
        h2 = self.addHost('h2', ip=edge2, defaultRoute=edge_GW,mac='00:00:00:00:00:02')
        h3 = self.addHost('h3', ip=edge3, defaultRoute=edge_GW,mac='00:00:00:00:00:03')


        u1 = self.addHost('u1', ip=client_IP1, defaultRoute=client_GW,mac='00:00:00:00:01:01')
        self.addLink(u1, r1, bw=10, delay='5ms',loss=10, intfName2='r1-eth1',
                     params2={'ip': default_IP2})

        for h, s in zip([h1, h2, h3], [s1, s1, s1]):
            self.addLink(h, s, bw=10, delay='5ms',loss=10)


def run():
    "Test the first structure"
    topo = NetworkTopo()
    net = Mininet(topo=topo)
    # adding the default gateway
    net['u1'].cmd('route add default gw 192.168.1.100')
    for i in ['h1', 'h2', 'h3']:
        net[i].cmd('route add default gw 192.168.100.254')
    # opening the ip forward signal
    net['r1'].cmd('sysctl -w net.ipv4.ip_forward=1')
    net.start()

    info('***Routing Table on r1:\n')
    info(net['r1'].cmd('route -n'))
    info('***ping the u1 to h1\n')
    net.pingAll
    info(net['u1'].cmd('ping -c 5 r1'))
    info('Testing yhe bandwidth between u1 and h1\n')
    h1, u1 = net.getNodeByName('h1','u1')
    net.iperf((h1,u1),l4Type='UDP' )
    CLI(net)
    net.stop()


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

其中有几个上面没有提到的操作,net['nodename'].cmd.('bash operate'),在Python脚本中实现bash操作。

在此拓扑结构之上,操作了一下通过ssh进行两个主机之间交换文件,步骤如下:

因为在之前直接使用scp进行文件传输的时候,一直显示connect refuse,于是在传输之前对ssh进行一些简单操作

/usr/sbin/ssh         在需要传输文件的主机上都需要运行该操作
ps -a | grep ssh      查看ssh服务是否开启

修改了一下传输的端口,在/etc/ssh/sshd_config这个文件之中修改,我的这个文件中port 22被注释掉了,于是去掉注释就好了。

server sshd restart       重启一下ssh服务

在mininet打开u1的xterm,进行文件的传输

scp Download/structure1_1 [email protected]:/home/john  

当然,为了省去每次都需要在mininet命令行中执行ssh的开启工作,可以在Python脚本中就添加进去,即:

    keys = ['u1', 'h1', 'h2', 'h3']
    for key in keys:
        net[key].cmd('/usr/sbin/sshd')

 

五.后续工作

   之后的工作是如何让host之间调配任务,实现任务的计算等,以及搭载真正的硬件。

 

 

.

你可能感兴趣的:(mininet)