1. Mininet简介
1.1 Minint系统架构
1.1.1 kernel datapath架构
1.1.2 userspace datapath架构
1.3 Mininet的主要特点
2. Mininet代码
2.1 Mininet源代码的目录结构
3.Mininet的使用
3.1 MininetCLI命令的功能表
Mininet是一款轻量级的进程虚拟化网络仿真工具,其最重要的一个特点就是它的所有代码几乎可以无缝迁移到真实的硬件环境,方便为网络添加新的功能并进行相关测试。
Mininet是一个可以在有限资源的普通电脑上快速建立大规模SDN原型系统的网络仿真工具。该系统由虚拟的终端节点、OF交换机、控制器组成,这使得它可以模拟真实网络,可对各种想法或网络等进行开发验证。由于Mininet是基于Linux Container这一内核虚拟化技术开发出的进程虚拟化平台,因此其实现进程虚拟化主要是用到了Linux内核的namespace机制,其从Linux版本2.6.27开始支持namespace机制,可以实现进程级的虚拟化。在Linux中不同namespace的进程看到的系统资源可能是不同的。默认所有进程都在root namespace中,某个进程可以通过unshare系统调用拥有一个新的namespace,通过namespace机制可以虚拟化3类系统资源。
网络协议栈:通俗来讲,每个namespace都可以独自拥有一块网卡(可以是虚拟出来的),root namespace看到的就是物理网卡,不同namespace里的进程看到的网卡是不一样的。
进程表:简单来说,就是每个namespace中的第一个进程看到自己的PID是1,以为自己是系统中的第一个进程(实际是init)。同时,不同namespace中的进程之间是不可见的。
挂载表:不同namespace中看到文件系统挂载情况是不一样的。
正是因为Linux内核支持这种namespace机制,可以在Linux内核中创建虚拟主机和定制拓扑,这也是Mininet可以在一台电脑上可以创建支持OF协议的SDN的关键所在。
基于上述namespace机制,Mininet架构按datapath的运行权限不同,分为kernel datapath和userspace datapath两种。其中kernel datapath把分组转发的逻辑编译进入Linux内核,效率非常高;userspace datapath把分组转发逻辑实现为一个应用程序,叫做ofdatapath,效率不及kernel datapath,但更为灵活,更容易重新编译。
Mininet的kernel datapath架构如图所示,控制器和交换机的网络接口都在root 命名空间中,每个主机都在自己独立的命名空间里,这也就表明每个主机在自己的命名空间中都会有自己独立的虚拟网卡eth0。控制器就是一个用户进程,它会在 loopback 上预留的6633 端口监听来自交换机安全信道的连接。每个交换机对应几个网络接口,如s0-eth0、s0-eth1以及一个ofprotocol进程,它负责管理和维护同一控制器之间的安全信道。
Mininet的userspace datapath架构如图所示,与kernel datapath架构不同,网络的每个节点都拥有自己独立的namespace。因为分组转发逻辑是实现在用户空间,所以多出了一个进程叫ofdatapath。另外,Mininet除了支持kernel datapath和userspace datapath这两种架构以外,还支持OVS交换机。OVS充分利用内核的高效处理能力,它的性能和kernel datapath相差无几
灵活性
可以通过软件的方式简单、迅速的创建一个用户自定义的网络拓扑,缩短开发测试周期,支持系统级的还原测试,且提供python API,简单易用。
可移植性
Mininet支持OF、OVS等SDN部件,在Mininet上运行的代码可以轻松移植到支持OF的硬件设备上。
可扩展性
在一台电脑上模拟的网络规模可以轻松扩展到成百千个节点
真实性
模拟真实网络环境,运行实际的网络协议栈,实时管理和配置网络,可以运行真实的程序,在Linux上运行的程序基本都可以在Mininet上运行,如Wireshark。
Mininet网络仿真工具主要基于Python语言,其代码主要可以分为两大部分:运行文件和Python库文件。在库文件中Python对网络中元素进行抽象和实现,如定义主机类来表示网络中的一台主机,然后运行文件则基于这些库完成模拟过程。
Mininet 源代码中共有 bin、custom、doc、mininet.egg-info、build、debian、examples、dist、mininet、util 10个子目录以及mnexec.c、setup.py等文件,目录结构如图所示。
(1)bin/:该文件夹下的mn文件是Mininet的运行文件,应用Python程序编写的文件,定义了MininetRunner类,Mininet安装后执行mn时即调用本程序,为整个测试创建基础平台。该文件代码的主要结构如图9-4所示。
Mininet运行文件mn执行过程中函数调用如下:首先,应用parseArgs()解析命令行传递的参数;然后通过setup()调用Mininet.net.init()来校验运行环境配置;再调用 begin()执行给定参数,完成包括创建拓扑、地址分配等操作;接着调用Mininet.net.Mininet()创建网络平台mn;应用Mininet.cli.CLI()函数创建CLI对象;并通过调用mn.start()启动网络实例;启动网络实例后,执行指定的测试命令,默认为cli,即调用CLI(mn)进入交互环境;执行结束后调用mn.stop()退出应用的网络实例。
(2)custom/:可以防止用户自定义的Python文件,如自定义的拓扑等。
(3)doc/:doxygen.cfg文件执行doxygen生成文档时的配置文件。
(4)debian/:生成deb安装包时的配置文件。
(5)mininet/:mininet的核心代码都在该文件夹内,下一小节将对各模块进行详细介绍。此外,该文件夹中的_init_.py文件用于将Python代码导入控制文件;clean.py文件提供两个函数:sh(cmd)调用shell来执行cmd,cleanup()用于清理残余进程或临时文件;test子文件夹用于存放测试的例子。
(6)util/:可放置辅助文件,包括安装脚本、文档辅助生成等。
(7)INSTALL:安装说明。
(8)setup.py:安装Python包时的配置文件,在Makefile中调用。
(9)CONTRIBUTORS:作者信息。
(10)README.md:说明文件。
(11)mnexec.c:执行一些快速命令,如关闭文件描述等,该文件是C程序,编译后生成的二进制文件mnexec被Python 库调用。
运行Mininet的操作十分简单,只需使用以下命令即可启动Mininet,会创建默认的一个小型测试网络。经过短暂时间的等待即可进入以“mininet>”引导的命令行界面。进入“mininet>”命令行界面后,默认拓扑将创建成功,即将拥有一个一台控制节点(Controller)、一台交换机(Switch)和两台主机(Host)的网络。
可以互相ping一下测试连通性
Mininet除了创建默认的网络拓扑之外,还提供了丰富的参数设定方式用来设定网络拓扑、交换机、控制器、MAC地址、链路属性等,以满足使用者在仿真过程中多样性的需求
(1)设置网络拓扑
--topo用于指定OpenFlow的网络拓扑。Mininet已经为大多数应用实现了5种类型的OpenFlow网络拓扑,分别为:tree、single、reversed、linear和minimal。默认情况下,创建的是minimal拓扑,该拓扑为一个交换机与两个主机相连;--topo single,n则表示1个OpenFlow交换机下挂连接n个主机;reversed与single类型相似,区别在于single的主机编号和相连的交换机端口编号同序,而reversed的主机编号和相连的交换机端口编号反序;--topo linear,n 则表示将创建 n 个OpenFlow交换机,且每个交换机只连接一个主机,并且所有交换机连接成直线;--topo tree,depth=n,fanout=m则表示创建一个树型拓扑,深度是n,扇出是m,例如,当depth=2,fanout=8时,将创建9个交换机连接64个主机(每个交换机连接8个设备,设备中包括交换机及主机)。
--custom:在上述已有拓扑的基础上,Mininet 支持自定义拓扑,使用一个简单的Python API即可,例如导入自定义的mytopo:
#sudo mn --custom ~/mininet/custom/topo-2sw-2host.py --topo mytopo --test pingall
(2)设置交换机
--switch:Mininet 支持 4 类交换机,分别是:UserSwitch、OVS 交换机、OVSLegacyKernelSwitch和IVS交换机。其中,运行在内核空间的交换机的性能和吞吐量要高于用户空间交换机,可以通过运行iperf命令测试链路的TCP带宽速率来验证:
#sudo mn --switch ovsk --testIPerf
(3)设置控制器
--controller:通过参数设置的控制器可以是 Mininet 默认的控制器(NOX)或者虚拟机之外的远端控制器,如Floodlight、POX等,指定远端控制器的方法如下:
#sudo mn --controller=remote,ip=[controllerIP],port=[controllerlistening port]
(4)配置MAC地址
--mac:设置MAC地址的作用是增强设备MAC地址的易读性,即将交换机和主机的MAC地址设置为一个较小的、唯一的、易读的ID,以便在后续工作中减少对设备识别的难度。
#sudo mn --mac
(5)设置链路属性
--link:链路属性可以是默认Link及TCLink。将链路类型指定为TC后,可以进一步指
定具体参数。具体参数命令显示如下:
#sudo mn --link tc,bw=[bandwidth],delay=[delay time],loss=[loss rate],max_que_size=[queue size]
bw表示链路带宽,使用Mbit/s为单位表示;延迟delay以字符串形式表示,如‘5ms’、‘100us’和‘1s’;loss 表示数据分组丢失率的百分比,用 0~100的一个百分数表示;max_queue_size表示最大排队长度,使用数据分组的数量表示。
创建Mininet拓扑成功后,一般可用nodes、dump、net等基本命令查看拓扑的节点、链路及网络等。为了方便使用及了解Mininet中所有的可用CLI命令,可在mininet>引导的命令行界面使用help命令进行查看。
常用CLI命令 |
功能 |
dump |
打印节点信息 |
gterm |
给定节点上开启gnome-terminal |
xterm |
给定节点上开启xterm |
intfs |
列出所有网络接口 |
iperf |
两个节点之间使用TCP尽心那个带宽测试 |
iperfudp |
两个节点间使用UDP进行带宽测试 |
net |
显示网络连接情况 |
noecho |
运行交互式窗口,关闭回应(echoing) |
pingpair |
在两个节点之间互ping测试 |
source |
从外部文件中读取命令 |
dpctl |
在所有交换机上用dpctl执行相关命令,本地为tcp127.0.0.1:6634 |
link |
禁用或启用两个节点间的链路 |
nodes |
列出所有的节点信息 |
pingall |
所有节点间互ping |
py |
执行python表达式 |
sh |
运行外部Shell命令 |
quit/exit |
退出 |