简介:一份适合网络工程/SDN课程学生的Mininet实验报告范例,整合了可视化工具Miniedit创建拓扑、命令行与交互式界面构建主机交换机,以及Python脚本搭建网络拓扑等核心实验内容,同时涵盖ping测试、节点连通性验证等环节,并附Mininet特性说明和常用命令速查。报告来源于西安财经大学信息学院《网络应用设计与系统集成》课程,以图文步骤记录了从启动miniedit、配置交换机主机到保存并运行拓扑的完整过程,也给出linear、single、tree等典型拓扑的Python构建示例。资源共1个doc文档,压缩包大小1.37MB,结构完整清晰,既适合课程实验参考,也可作为初学者理解软件定义网络仿真平台的入门材料。现已有1067人学习该资源。
1. 用 Mininet 搭网络拓扑:为什么一个虚拟环境能把人卡住一整天
第一次接触 Mininet 的人,多半是卡在同一个地方:照着实验手册敲sudo mn,拓扑是出来了,但一到pingall就丢包,或者 miniedit 可视化界面根本起不来。这个工具本身不复杂,复杂的是它依赖的虚拟化环境——OpenvSwitch 内核模块没加载、Python 版本不对、甚至 VMware 网卡模式选错,都会让一个本来几秒就能跑通的拓扑变得莫名其妙。
本篇文章要落地的是 Mininet 环境搭建与三种拓扑构建方式:可视化工具 miniedit、交互式命令行、Python 脚本。这套环境是 SDN 实验的常见起点,也是很多网络课程报告里必写的一环。读完你可以照着步骤从零建出 linear、single、tree 三类拓扑,并且知道每个命令背后的参数含义,遇到报错也能自己排查。适合正在做实验、写报告、或者刚接触 SDN 想动手跑通的开发者。
2. 环境准备与拓扑创建方式:先分清三条路再动手
2.1 运行环境选型:虚拟机、物理机还是云主机
Mininet 官方支持 Ubuntu 系系统,最省事的方式是直接在 VMware 里装一个 Ubuntu 镜像。做实验的人经常在物理机上折腾半天,最后发现内核模块编译不过去,玄学问题一大堆,其实虚拟机反而是最稳的路径。原因很简单:Mininet 依赖 OpenvSwitch 和 cgroups,虚拟机里可以随时快照,装坏了恢复成本几乎为零。
我一般建议用 Ubuntu 16.04 或 18.04 的 64 位镜像,内存分配 2GB 以上,网络适配器选 NAT 模式。NAT 模式下虚拟机可以访问外网下载依赖包,同时又和宿主机网络隔离,不会出现网段冲突的问题。硬盘给 20GB 就够,Mininet 本体加依赖包全部装完不到 3GB。
sudo apt-get update sudo apt-get install -y mininet安装完成后先验证一下版本,确认装的是可用的版本,而不是一个半残的旧包。
mn --version如果提示找不到命令,说明 apt 源里没有这个包,需要走源码安装:先git cloneMininet 仓库,然后运行util/install.sh。这个脚本会一并装好 OpenvSwitch、Wireshark 等配套工具,缺点是耗时长,网络不好的时候容易中断。装完再用mn --version验证,能输出版本号就说明核心安装成功。
2.2 三种拓扑创建方式对比:可视化、命令行、脚本各适合什么场景
Mininet 创建拓扑有三条路,对应的场景完全不同。可视化工具 miniedit 适合教学演示和报告截图,鼠标拖拽就能画拓扑,还能导出 Python 脚本;命令行sudo mn --topo适合快速验证一个已知拓扑,一条命令拉起来就测;交互式界面适合在已有拓扑上动态加节点,不改脚本直接操作;Python 脚本则是最正式的方式,适合复现实验、修改参数、批量跑测试。
从实验报告的角度看,三种方式都要会,因为老师验收时可能随机让你用其中一种现场建拓扑。从实际工程角度看,Python 脚本最值得花时间,因为只有它能精确控制带宽、延迟、丢包率这些网络参数。后面几章会把这三种方式逐个走一遍,每一条命令都给出参数说明。
3. 命令行创建拓扑:sudo mn 背后的参数与拓扑类型
3.1 最小拓扑:一个交换机挂两个主机
命令行方式是 Mininet 最直接的入口,sudo mn默认就会创建一个最小拓扑:一个交换机(s1)连接两个主机(h1、h2)。这个默认行为很多人不知道,以为必须加参数才能建拓扑,其实直接敲sudo mn就已经在跑一个完整的 OpenFlow 网络了。
sudo mn进入 Mininet 交互界面后,可以用net命令查看当前的拓扑结构,用nodes查看所有节点。这两个命令是验证拓扑是否正确的最快方式。如果看到 h1、h2、s1 三个节点,并且 h1 和 h2 都连到了 s1 上,说明默认拓扑已经就绪。
mininet> net mininet> nodesnet输出的每一行代表一个节点及其连接的端口信息格式是节点名 接口名:对端节点(对端接口)。nodes会按类型列出所有主机、交换机、控制器。这两个命令在后面的所有实验里都会反复用到,建议把输出格式记熟,排查拓扑错误时第一眼就能看出哪里连错了。
3.2 三种内置拓扑:single、linear、tree 的参数写法
Mininet 内置了三种常用拓扑类型,参数格式都是--topo 类型,参数。这里的参数是英文逗号分隔,没有空格,写错一个标点就会报错。下面把三种写法一次性列出来,每条都标注参数含义。
sudo mn --topo single,3 sudo mn --topo linear,4 sudo mn --topo tree,depth=2,fanout=2single,3表示 1 个交换机连接 3 台主机,所有主机挂在同一个交换机上,适合测试广播和冲突域场景。linear,4表示 4 台交换机串联,每台交换机下挂 1 台主机,形成一条链,适合测试多跳转发和延迟累积。tree,depth=2,fanout=2表示深度为 2、扇出为 2 的树形拓扑,第一层 1 个根交换机,第二层 2 个交换机,第三层 4 台主机,总共 3 层设备。
注意tree拓扑的 depth 是指交换机层数,不是总层数。depth=2 时实际设备层数是 3(根交换机组、中间交换机组、主机组)。很多人在这个参数上踩坑,以为 depth=2 就两层设备,结果主机数量和自己预期对不上。跑完对照实验报告里的拓扑图,应该是 4 台主机连接 2 台中间交换机,2 台中间交换机再连接 1 台根交换机。
4. miniedit 可视化创建拓扑:拖出一个能导出脚本的网络
4.1 启动 miniedit 并完成基本配置
miniedit 是 Mininet 自带的图形化拓扑编辑工具,本质是一个 Python 脚本,路径通常在examples/miniedit.py目录下。不同版本安装路径略有差异,最稳妥的查找方式是直接用find命令定位。
sudo find / -name "miniedit.py" 2>/dev/null找到路径后用sudo python启动。注意这里必须有 root 权限,否则 OpenvSwitch 无法创建虚拟网卡,界面能打开但建拓扑时会报权限错误。
cd /usr/lib/python2.7/dist-packages/mininet/examples sudo python miniedit.py启动后界面会弹出一个空白画布,左侧是节点类型面板,包括 Host、Switch、Controller 等图标。用鼠标拖拽节点到画布上,再用连线工具把主机和交换机连起来。连线时注意顺序:先点击交换机端口,再点击主机端口,顺序反了可能导致端口映射混乱。
4.2 节点属性配置与导出 Python 脚本
拖出拓扑后,右键点击节点选择 Properties 可以配置参数。主机需要配置 IP 地址,交换机需要配置 OpenFlow 协议版本,控制器要选择远程还是本地。这些配置直接决定了拓扑能否正常通信。
# 主机配置示例 h1: 10.0.0.1/8 h2: 10.0.0.2/8 # 交换机配置示例 OpenFlow 1.3配置完成后,通过菜单栏的 File 选择 Export Level 2 Script,会生成一个 Python 脚本文件。这个脚本可以在命令行里直接运行,效果和在可视化界面里创建的拓扑完全一样。导出后用sudo python 脚本名运行,脚本会自动创建相同的拓扑结构,并且如果勾选了 Start CLI 选项,运行后还会进入 Mininet 交互界面,可以直接执行 ping 测试。
这里有个常见坑:导出时如果没有勾选 Edit 菜单里的 Start CLI,脚本运行完会直接退出,无法进入交互界面。做实验时一定要记得勾选这个选项,否则后面没法测试连通性。另外导出的脚本文件名最好用英文,中文文件名在部分版本的 Python 2 环境下会报编码错误。
5. 交互式界面与 Python 脚本:动态改拓扑和批量建拓扑
5.1 交互式 CLI:在已有拓扑中动态添加主机和交换机
sudo mn进入交互界面后,除了执行 pingall、net 这些常规命令,还可以通过py前缀直接执行 Python 代码操作 Mininet 对象。这是在现有拓扑上动态加设备的常用方式,不需要退出重进。
mininet> py net.addHost('h3') mininet> py net.addLink(s1, net.get('h3')) mininet> py s1.attach('s1-eth3') mininet> py net.get('h3').cmd('ifconfig h3-eth0 10.3')第一条命令添加一个名为 h3 的主机节点,第二条命令把 h3 连接到交换机 s1 上,第三条命令把 s1 的 eth3 端口加入 OpenvSwitch 管理,第四条命令给 h3 配置 IP 地址。这四步缺一不可:只 addHost 不 addLink,h3 是孤立节点;只 addLink 不 attach,端口虽然存在但 OpenvSwitch 没启用它;不配 IP 的话,ping 的时候找不到地址。
这一步特别容易翻车的地方在于s1.attach('s1-eth3')这个命令。很多教程没提这个步骤,导致拓扑里明明能看到 h3 连上了 s1,但h1 ping h3就是不通。原因就是 OpenvSwitch 需要显式把端口加入管理。每次交互式添加设备都要记得补上 attach,这个习惯能省掉一半的排查时间。
5.2 Python 脚本构建标准拓扑:linear、single、tree 的一次性写法
交互式命令适合临时操作,但实验报告要求的是编写独立的 Python 脚本。下面给出一个完整的脚本框架,覆盖了 linear、single、tree 三类常用拓扑,以及自定义 IP 的写法。脚本里用到的LinearTopo、SingleTopo、TreeTopo都是 Mininet 内置的拓扑类,无需自己实现。
from mininet.topo import Topo from mininet.net import Mininet from mininet.node import OVSSwitch, Controller from mininet.cli import CLI from mininet.link import TCLink class MyTopo(Topo): def build(self): # single: 一个交换机挂两台主机 s1 = self.addSwitch('s1') h1 = self.addHost('h1', ip='10.0.0.1/8') h2 = self.addHost('h2', ip='10.0.0.2/8') self.addLink(s1, h1) self.addLink(s1, h2) if __name__ == '__main__': topo = MyTopo() net = Mininet(topo=topo, switch=OVSSwitch, controller=Controller, link=TCLink) net.start() CLI(net) net.stop()这个脚本定义了一个自定义拓扑类,内部构建了 1 台交换机和 2 台主机,并给每台主机指定了 IP。运行时先net.start()启动网络,然后CLI(net)进入交互界面,测试完net.stop()清理所有虚拟网络设备。关键参数在Mininet()构造函数里:switch=OVSSwitch指定使用 OpenvSwitch,link=TCLink允许后续对链路设置带宽和延迟。
如果要改成 linear 或 tree 拓扑,只需替换 MyTopo 类的内容,使用 Mininet 内置的类名加参数即可。
from mininet.topo import LinearTopo, SingleTopo, TreeTopo # linear,4: 4台交换机串联,每台下挂1台主机 topo = LinearTopo(k=4) # single,3: 1台交换机下挂3台主机 topo = SingleTopo(k=3) # tree,depth=2,fanout=2: 树形拓扑,2层交换机,扇出2 topo = TreeTopo(depth=2, fanout=2)5.3 网络性能限制:带宽、延迟、丢包率的参数配置
实验报告的进阶部分要求对网络性能做限制,核心是用addLink()的参数控制链路质量。Mininet 的 TCLink 支持四个关键参数:bw 表示带宽,单位 Mbit/s;delay 表示链路延迟,单位 ms;max_queue_size 表示最大队列长度,用于模拟拥塞;loss 表示丢包率,取值范围是 0 到 100 的整数。这四个参数可以在脚本里直接加到 addLink 调用中。
from mininet.link import TCLink class PerfTopo(Topo): def build(self): s1 = self.addSwitch('s1') h1 = self.addHost('h1') h2 = self.addHost('h2') # 限制带宽10Mbit/s,延迟5ms,丢包率1% self.addLink(s1, h1, bw=10, delay='5ms', max_queue_size=100, loss=1) self.addLink(s1, h2, bw=10, delay='5ms', max_queue_size=100, loss=1)这里有个容易忽略的点:mininet()构造时需要显式指定link=TCLink,否则默认使用 OVSLink,addLink 里的 bw、delay、loss 参数会被直接忽略,悄悄失效。不少同学脚本写对了,却因为少了这个参数导致性能限制完全不生效。检查脚本时优先看这一行有没有写对。
6. 常见问题排查:Mininet 构建过程中的几个高频坑
6.1 启动报错:OpenvSwitch 内核模块未加载
现象:运行sudo mn时终端输出一堆关于openvswitch_mod或datapath的错误,然后自动退出。
原因:OpenvSwitch 的内核模块没有加载,或者版本不匹配。常见于刚装完 Mininet 但没有安装 openvswitch-switch 包,或者系统内核升级后模块失效。
解决:先确认模块是否可用,再强制加载。一条命令搞定。
sudo apt-get install -y openvswitch-switch sudo modprobe openvswitch_mod加载完成后重新运行sudo mn。如果仍然报错,把虚拟机关机后重新启动一次,让内核重新加载所有模块。这个问题在 Ubuntu 内核升级后尤其常见,属于 Mininet 环境搭建里的第一个拦路虎。
6.2 pingall 不通:单一主机无法 ping 通其他主机
现象:交互界面里pingall命令显示 h1 可以 ping 通 h2,但 h2 ping 不通 h1,或者所有主机都 ping 不通。
原因:最常见的原因是主机 IP 配置冲突,或者交换机没有正确连接到控制器。另外在交互式手动添加主机时,没有执行s1.attach()也会导致端口不生效。
解决:先用dump命令查看所有节点的接口和 IP 信息。确认每个 host 的 IP 是否在同一个子网内,然后检查交换机的端口状态。
mininet> dump mininet> s1 ovs-ofctl dump-ports s1如果端口列表里缺少某个主机的接口,说明 attach 没生效。用py s1.attach('s1-eth3')补上,再重新 pingall。如果是 IP 不在同一网段,用ifconfig命令修改主机 IP 后重试。
6.3 xterm 无法打开:显示转发或权限问题
现象:在 Mininet 交互界面输入xterm h1后,没有任何反应,或者终端卡住。
原因:xterm 工具没有安装,或当前用户没有 X11 转发权限。在纯命令行环境(SSH 登录虚拟机)里,这个问题尤其常见。
解决:先补装 xterm,再检查 DISPLAY 环境变量。虚拟机本地操作一般没问题,SSH 远程操作时需要用ssh -X开启 X11 转发。
sudo apt-get install -y xterm echo $DISPLAY6.4 Python 脚本运行报错:addHost 的参数写错
现象:脚本运行时报TypeError: addHost() got an unexpected keyword argument。
原因:Mininet 不同版本对 addHost 参数的命名不完全一致。旧版本用ip=,新版本用法相同,但部分扩展参数名有差异,比如 CPU 限制在版本间兼容性较差。
解决:把脚本里的参数和本机 Mininet 版本对照,不确定时在 Python 交互环境里查看函数签名。
python -c "from mininet.topo import Topo; import inspect; print(inspect.signature(Topo.addHost))"6.5 导出脚本后运行报编码错误
现象:miniedit 导出的 Python 脚本用sudo python运行时报SyntaxError: Non-ASCII character。
原因:脚本里包含中文注释,而 Python 2 默认不识别中文编码,文件头部没有声明编码格式。
解决:在脚本第一行加# -*- coding: utf-8 -*-。更省事的做法是导出时文件路径和拓扑节点名全部用英文,避免出现中文。
7. 装完怎么验证跑通:从拓扑结构到连通性的一整套测试
7.1 验证拓扑结构:net、nodes、dump 三连
环境装好、拓扑建起来之后,第一步要验证的是拓扑结构本身是否正确。进入 Mininet 交互界面,依次执行net、nodes、dump三个命令,对照实验预期检查节点数量和连接关系。
mininet> net mininet> nodes mininet> dumpnet看链路连接是否和预期一致,nodes看设备数量是否完整,dump看每个节点的 IP、MAC、端口状态。三个命令信息有重叠,但排查时各有用处:net 管连接,nodes 管数量,dump 管细节。这个验证习惯一直保留着,现在脚本跑起来第一件事就是三连确认拓扑没变形。
7.2 验证连通性:pingall 和定向 ping 的区别
拓扑结构对了不代表网络能通信,必须做连通性测试。pingall会遍历所有主机两两互 ping,适合快速发现整体问题;定向h1 ping h2适合确认某一条具体链路的状态。
mininet> pingall mininet> h1 ping -c4 10.0.0.2pingall的输出格式是h1 -> h2 ✓ h3 ✓,每个对钩代表一对主机通信正常。如果有叉号,说明对应主机对之间存在链路或配置问题。定向 ping 加-c4参数表示发送 4 个包,可以顺便观察延迟和丢包率,如果通了但响应时间波动很大,说明链路性能限制生效了。
7.3 验证性能限制:从 ping 延迟判断参数是否生效
配置了 bw、delay、loss 之后,最直观的验证方式就是看 ping 的延迟。如果链路设置了 5ms 延迟,ping 的 RTT 至少是 10ms(往返双程),实测超过 10ms 且波动在合理范围内,说明延迟参数生效。如果 RTT 显示 0.0xx ms,说明链路没有启用 TCLink,参数被忽略了。
mininet> h1 ping -c 10 10.0.0.2观察输出里的time=字段,然后对比脚本里设置的 delay 参数。这个对比可以作为验证链路参数是否生效的量化依据,写进实验报告的结果分析部分比纯文字描述有说服力得多。
整套环境从安装到验证跑通,现在看来流程清晰,但第一次做这个实验时确实在这些环节上反复折腾过。从那以后每次搭好环境,我都会强制自己走一遍 net、nodes、dump、pingall 这套完整流程,确认拓扑、连通性、性能三个层面都没问题才进入下一步。这个习惯一直保留到现在,希望也能帮到你少走几步弯路。
本文还有配套的精品资源,点击获取