ARTICLE DETAIL

资讯详情

深耕编程入门与网站建设的一线实战洞察。

Mininet实验报告:三种拓扑构建方式与链路性能限制详解

Mininet实验报告:三种拓扑构建方式与链路性能限制详解 简介这份Mininet实验报告doc文档面向高校网络工程、计算机及相关专业学生聚焦软件定义网络仿真工具Mininet的入门与实战可帮助读者系统掌握创建网络拓扑的三种主要方式可视化工具Miniedit、命令行交互界面以及Python脚本编程。全包仅含1个doc文件大小1.37MB正文16页完整记录了西安财经大学《网络应用设计与系统集成》课程实验一的实验目的、实验内容、技术背景、具体步骤与操作要点。报告中详细介绍了Mininet的特性、常用命令并通过实操演示Miniedit的配置与保存、命令行拓扑构建、交互式添加主机和交换机、ping测试以及Python脚本定义linear、single、tree等拓扑和设置主机IP、带宽、延迟、丢包率等性能参数层次分明、截图与命令对照清晰。已有1066人学习下载适合正在完成Mininet课程作业或准备网络实验报告的学生参考借鉴。1. 这份 Mininet 实验报告的含金量三种建拓扑方式一步到位第一次用 Mininet 做网络实验的人十有八九卡在同一个地方打开虚拟机却不知道第一个命令该敲什么。这份西安财经大学信息学院《网络应用设计与系统集成》实验一的报告恰好把 Mininet 最核心的三条路径全走了一遍——可视化工具 Miniedit、命令行参数、交互式 CLI外加 Python 脚本构建拓扑和链路性能限制。它对学生实验的覆盖很完整从最小拓扑 single,2 到 linear,4 再到 tree,depth2 树形拓扑每个都能直接照着敲。对正在做课程设计或者刚接触 SDN 的读者这份资源最有价值的不是概念解释而是它把「建拓扑 → 验证连通性 → 限制带宽损耗 → 导出脚本」这条完整链路串起来了。尤其适合两类人一是网络工程专业做实验报告的学生需要一份可对照的操作步骤二是刚入职的运维或网络工程师想快速在本地虚拟机上把 Mininet 跑起来验证 OpenFlow 交换机和自定义拓扑的行为。2. 用 Miniedit 可视化建拓扑从启动到导出 Python 脚本的完整流程2.1 启动 Miniedit 的前置准备root 权限与 examples 目录Miniedit 是 Mininet 自带的可视化编辑器它不是一个独立安装的软件而是存放在 Mininet 源码包的 examples 目录里。所以第一步是先确认 Mininet 装在了哪、examples 目录里有没有miniedit.py这个文件。sudo su - find / -name miniedit.py 2/dev/null第一行是切换到 root 权限因为 Mininet 创建虚拟网络接口需要 root 权限普通用户执行会报权限不足。第二行是全盘查找miniedit.py的位置2/dev/null是把没有权限访问目录的报错信息丢弃避免刷屏干扰搜索结果。常见路径是/usr/local/lib/python3/dist-packages/mininet/examples/miniedit.py或者/home/xxx/mininet/examples/miniedit.py。找到位置之后进入该目录启动它cd /home/xxx/mininet/examples python miniedit.py这里有一点值得注意如果直接双击miniedit.py或者在别的目录下用 python 运行大概率会报模块找不到的错误因为 Mininet 的源码包内部存在相对导入必须在 examples 目录下启动才能正确加载依赖。我一般会把这行命令记成习惯——先 cd 到 examples 再启动而不是用绝对路径去执行。2.2 拖三个节点画拓扑主机、交换机、控制器的配置项Miniedit 启动后是一个图形界面左侧工具面板有 Host、Switch、Controller 三类节点右侧是画布。实验要求的是「创建一个简单的网络拓扑结构」通常做法是拖入两个 Host、一个 Switch、一个 Controller然后连线Host 连到 Switch 的端口Controller 连到 Switch 的管理口。连线只是第一步接下来是配置。右键单击节点选择 Properties这里才是 Miniedit 真正的关键操作点。主机的配置项主要是 IP 地址和 MAC 地址在 Host Properties 弹窗里把 IP 填成10.0.0.1、10.0.0.2掩码默认是/8或者/24注意两台主机必须在同一子网否则后面 ping 测试必然失败。交换机的配置项不多主要是选择类型默认是 Default Switch即 Open vSwitch在实验环境里保持默认即可。控制器的配置最重要可以选择 OpenFlow Controller 或 Remote Controller本地实验选 OpenFlow Controller端口默认 6633。配置完节点后建议做一步全局设置点击菜单栏 Edit → Preferences勾选 Start CLI。这个选项的作用是让拓扑启动后自动进入 Mininet 交互命令行后面才能输入pingall、dump等命令。同时在下拉框里确认 OpenFlow 协议版本Mininet 默认支持 1.0 到 1.3实验报告里没特别指定版本保持默认即可。2.3 导出 Level 2 Script 并重新运行关键路径与参数拓扑画完、配置填完下一步是保存。Miniedit 的 File 菜单里有两个导出选项Export Level 2 Script 和 Export Level 3 Script。实验报告用的是 Level 2它导出的 Python 脚本保留了主机、交换机、控制器的连接关系但不包含三层的 IP 路由配置所以脚本运行后还需要手动配 IP 或者依赖默认 IP。导出路径建议直接存到~/mininet_workspace这样好找的地方。导出后用命令行运行cd ~/mininet_workspace sudo python mytopo.py运行后观察输出Mininet 会先启动 Controller然后创建交换机和主机最后打印出每个节点的端口状态。如果一切正常你会看到进入mininet交互提示符此时输入net可以查看拓扑连接输入dump可以看节点详情。一个常见的误区是很多人以为导出的脚本是一份完整的可运行拓扑但 Level 2 Script 导出的其实是一个topo对象的定义不带net.start()和CLI(net)调用。有些版本的 Miniedit 导出脚本会包含这些有些不会。如果运行后只看到拓扑对象定义却没有进入交互界面需要在脚本末尾补上if __name__ __main__: net Mininet(topomytopo) net.start() CLI(net) net.stop()2.4 这份实验涉及的 Miniedit 关键配置文件清单节点/配置项推荐值说明主机 IP10.0.0.1 / 10.0.0.2同一子网否则 ping 不通交换机类型Default Switch (OVS)内核态 Open vSwitch兼容性好控制器OpenFlow Controller本地控制器默认端口 6633OpenFlow 版本1.3 或默认与 Mininet 版本匹配即可Start CLI勾选启动后自动进入交互命令行导出方式Export Level 2 Script保证拓扑可再次加载这份清单是我做完整个实验流水线之后的总结不是实验报告里的原文但照着这个表去点能避开百分之八十的配置遗漏问题。3. 命令行拓扑与交互式 CLI不打开图形界面也能建网3.1 三个最常用的 --topo 参数single、linear、treeMiniedit 适合现场演示和生成脚本但日常验证拓扑连通性命令行才是效率最高的方式。实验报告里要求用命令行创建三种拓扑最小拓扑、线性拓扑、单交换机多主机拓扑。对应的命令分别是sudo mn --topo single,2 sudo mn --topo linear,4 sudo mn --topo single,3第一条命令创建最小拓扑一个交换机连两个主机这是 Mininet 的默认形态也可以用sudo mn直接得到同样的效果。第二条命令创建线性拓扑四个交换机串成一排每台交换机下挂一个主机主机编号从 h1 到 h4交换机编号从 s1 到 s4。第三条命令是三个主机全部接到同一个交换机上交换机的端口会多占几个。需要注意topo参数的语法结构--topo 拓扑类型,参数。single,2表示单交换机两主机linear,4表示四交换机线性链tree类型的参数更复杂格式是tree,depth2,fanout2表示深度为 2、每个节点扇出为 2 的二叉树形拓扑总主机数是fanout^depth也就是 4 台主机。理解了参数语法你就可以自由组合出任意规模的拓扑而不是死记命令。3.2 交互式 CLI 里动态添加节点不重启拓扑加一台主机命令行创建拓扑后进入的是mininet交互界面这是一个 Python 解释器外壳可以执行两类命令一类是 Mininet 内置命令另一类是以py开头的 Python 表达式解析。实验报告里的进阶操作就是在不退出拓扑的情况下动态添加主机这在实际调试时非常有用。py net.addHost(h3) py net.addLink(s1, net.get(h3)) py s1.attach(s1-eth3) py net.get(h3).cmd(ifconfig h3-eth0 10.3)逐行解释py net.addHost(h3)是调用net这个 Mininet 对象的addHost方法在拓扑中创建一个名为 h3 的新主机此时它还是孤立的没有接入任何交换机。第二行py net.addLink(s1, net.get(h3))是在交换机 s1 和 h3 之间创建一条虚拟以太网链路net.get(h3)是获取 h3 这个对象。第三行py s1.attach(s1-eth3)是把交换机的第三个物理端口s1-eth3正式启用并关联到新链路这一步容易漏掉——只 addLink 不 attach主机加上了但数据通路不通。第四行是在 h3 内部执行 ifconfig 命令给它手动设置 IP 地址10.3完整写法是10.0.0.3简写形式在某些版本里会被自动补全。设置完 IP 后测试连通性h1 ping -c1 10.3这条命令是在 h1 的终端里向 10.3 发送 1 个 ICMP 包-c1表示只发一个包。如果返回0 received说明链路没配好回头查 attach 那一步是否漏了。3.3 连通性验证pingall 与定向 ping 的差异实验报告里要求对节点间进行 ping 测试涉及两个层面的验证全量测试和定向测试。mininet pingallpingall的作用是让拓扑中所有主机两两 ping 一遍输出一个矩阵显示哪些主机对之间通了哪些不通。这个命令适合整体检查但有个缺点它只报告结果不输出具体的丢包率和时延定位问题还是要靠定向 ping。定向 ping 的语法在 3.2 已经出现过mininet h1 ping -c4 h2这条命令在 h1 的终端里执行ping -c4 h2也就是向 h2 发送 4 个 ICMP 包输出每个包的往返时间、存活时间最后统计丢包率。范例如64 bytes from 10.0.0.2: icmp_seq1 ttl64 time0.073 ms看到这行就说明链路是通的。实际调试中我的习惯是先pingall快速定位哪对不通再用定向 ping 去细化原因。如果pingall全通但定向 ping 丢包那基本可以确定是性能限制参数的问题而不是拓扑本身的问题这在第 4 章会详细展开。4. 用 Python 脚本精确构建拓扑从 topo 工厂类到链路性能限制4.1 三种内置拓扑的等价写法与适用场景命令行--topo参数的本质是 Mininet 内部帮你实例化了对应的 topo 类。当你需要把拓扑写成 Python 脚本交给别人复现或者要在拓扑基础上做二次定制时就得直接写 Python 代码。实验报告要求用 Python 脚本实现 linear,4、single,3、tree,depth2,fanout2 三种拓扑常见做法是直接调用 Mininet 内置的 topo 工厂类from mininet.topo import LinearTopo, SingleSwitchTopo, TreeTopo # topo linear,4 linear4 LinearTopo(4) # topo single,3 single3 SingleSwitchTopo(3) # topo tree,depth2,fanout2 tree22 TreeTopo(depth2, fanout2)LinearTopo(4)等价于--topo linear,4创建 4 台交换机串行相连每个交换机下挂 1 台主机SingleSwitchTopo(3)等价于--topo single,3创建 1 台交换机下挂 3 台主机TreeTopo(depth2, fanout2)等价于--topo tree,depth2,fanout2创建一棵二叉树深度为 2每个父节点带 2 个子节点共 4 台主机。这三个类都在mininet.topo模块里导入后可以直接实例化。实例化 topo 类之后需要传入 Mininet 才能启动网络from mininet.net import Mininet from mininet.cli import CLI net Mininet(topotree22) net.start() CLI(net) net.stop()这个代码块的后三行是整个 Mininet 脚本的标准骨架net.start()启动网络此时虚拟交换机和主机进程才真正创建CLI(net)进入交互命令行让你手动输入 ping 命令net.stop()在退出 CLI 后关闭所有虚拟设备释放端口和进程。4.2 手动定义 Topo 子类给主机指定 IP 地址内置 topo 类适合快速验证但实验要求里有一条是「1 个交换机2 个主机并且赋予主机 IP 地址」内置类无法满足这种自定义需求需要手动继承 Topo 类写自己的拓扑定义from mininet.topo import Topo class MyTopo(Topo): def __init__(self): Topo.__init__(self) h1 self.addHost(h1, ip10.0.0.1/24) h2 self.addHost(h2, ip10.0.0.2/24) s1 self.addSwitch(s1) self.addLink(h1, s1) self.addLink(h2, s1) if __name__ __main__: from mininet.net import Mininet from mininet.cli import CLI net Mininet(topoMyTopo()) net.start() CLI(net) net.stop()这里的addHost方法接收两个参数第一个是主机名第二个是关键字参数ip格式是10.0.0.1/24注意前缀长度必须写在 IP 后面只写10.0.0.1而不写/24Mininet 会自动分配一个默认掩码可能与预期不符。addSwitch(s1)创建交换机默认使用 Open vSwitch。addLink把主机和交换机连起来只传两个节点名即可Mininet 会自动分配端口。这种写法还有一个好处它把主机的 IP 直接写死在拓扑定义里而不是等网络启动后再手动 ifconfig。做完这个脚本之后进入 CLI 直接用h1 ping -c1 h2就能通不需要中途配地址这在实际复现实验时省掉很多麻烦。4.3 链路性能限制参数bw、delay、loss、max_queue_size 逐个拆解实验报告第四部分提到addHost()可以对主机 cpu 进行设置以百分数形式addLink()可以设置带宽 bw、延迟 delay、最大队列大小 max_queue_size、损耗率 loss。这是整份报告里最有工程价值的部分因为课程实验中绝大多数场景只是验证连通性而真实网络环境里的拥塞、丢包、延迟问题全靠这些参数模拟。from mininet.topo import Topo class PerfTopo(Topo): def __init__(self): Topo.__init__(self) h1 self.addHost(h1, cpu0.5) h2 self.addHost(h2, cpu0.5) s1 self.addSwitch(s1) self.addLink(h1, s1, bw10, delay5ms, loss1, max_queue_size1000) self.addLink(h2, s1, bw10, delay5ms, loss1, max_queue_size1000)参数逐个说清楚。cpu0.5表示该主机最多使用宿主机 CPU 的 50%在 Mininet 进程中它是通过 CGroup 限流实现的注意这里的单位是百分比小数0.5 就是 50%不是 5%。bw10表示链路带宽限制为 10 Mbps内部通过 Linux 的 tc (traffic control) 队列规则实现不设这个参数时链路带宽是宿主机网卡的满速。delay5ms是单向链路延迟加上这个参数后能模拟广域网环境下的 RTT 时延。loss1是丢包率百分数1 表示 1% 的随机丢包取值范围 0~100。max_queue_size1000是交换机端口最大队列长度达到上限后新的数据包会被丢弃这个参数直接影响 TCP 拥塞控制的行为。这几个参数组合起来配合 iperf 就能验证拓扑的「真实感」带宽限制是否生效、丢包率是否符合预期、延迟是否可测量。但要注意bw 限制只对经过虚拟交换机转发的流量生效如果两台主机在同一个交换机的同一个广播域内直接互通绕过了 tc 队列带宽限制可能测不出来这是很多人设置后测不出效果的常见原因。4.4 用 iperf 验证带宽限制是否真的生效设置完bw10之后怎么确定限制真的起作用答案是 iperf。Mininet 的虚拟主机是可以运行真实应用程序的iperf 就是最常用的测速工具。mininet h1 iperf -s -p 5001 mininet h2 iperf -c h1 -p 5001 -t 10第一条命令在 h1 上启动 iperf 服务器模式-s表示 server-p 5001指定监听端口末尾的是让服务在后台运行不阻塞 CLI。第二条命令在 h2 上以客户端模式连接 h1 的 5001 端口-t 10表示持续测试 10 秒。测试结束后会输出类似[SUM] 10.0 Mbits/sec的统计行看到这个数字基本等于你设置的bw10说明限速生效。如果测出来的带宽远高于 10 Mbps比如 80 Mbps、90 Mbps说明 tc 规则没有正确附加到虚拟接口上。这时候先检查 Mininet 版本有些旧版本默认使用的 OVS 用户态数据路径不支持 tc 限速再检查链路上是否还有别的 qdisc 规则冲突可以用sudo tc qdisc show查看。我调试的时候一般会在脚本里给每台主机的 IP 配上之后再检查一次是否所有链路都打印了(10Mbit, 5ms, 1%)这样的参数能打印出来基本就生效了。5. Mininet 实操中的常见坑与排查思路5.1 第二次运行拓扑报端口占用控制器起不来现象第一次运行拓扑正常退出第二次启动时报错提示端口 6633 被占用或者控制器进程启动失败。原因Mininet 没有完全清理上一次运行的残留进程。net.stop()只停掉虚拟主机和交换机但部分版本的 OVS 控制器进程会残留占用 6633 端口。解决在重新运行之前执行一次彻底清理。sudo mn -c这条命令会清理所有 Mininet 相关的进程、虚拟网卡、命名空间和残留配置。如果mn -c还不够再用sudo fuser -k 6633/tcp强制杀掉占用 6633 端口的进程。从那以后我每次跑新拓扑前都先执行sudo mn -c基本上再没遇到过端口占用。5.2 导出 Level 2 Script 运行后没有进入交互界面现象miniedit 导出脚本后用python mytopo.py运行只输出了拓扑对象定义没有启动网络也没有进入mininet交互界面。原因Miniedit 的 Exoprt Level 2 Script 导出的是拓扑定义代码它默认认为你会在自己的 Python 脚本里 import 这个文件再使用所以不含net.start()和CLI(net)这些启动代码。实验报告里说「运行 python 脚本重现拓扑」需要手动补全主入口。解决在导出脚本末尾追加启动代码。if __name__ __main__: from mininet.net import Mininet from mininet.cli import CLI topo MyTopo() net Mininet(topotopo) net.start() CLI(net) net.stop()5.3 主机间 ping 不通但拓扑看起来没问题现象net命令显示 hosts 已经连接到了交换机dump也能看到每个节点的 PID但h1 ping h2一直Destination Host Unreachable或者直接超时。原因主机 IP 缺失或者不在同一子网。Mininet 默认会给主机分配10.0.0.0/8网段的地址但如果手动设置过某一台主机的 IP比如交互式 CLI 里用 ifconfig 改成10.3掩码和子网段就可能不一致导致 ARP 请求无法被正确路由。解决用h1 ifconfig分别查看两台主机的 IP 和掩码确认它们属于同一个子网。如果不在直接补一条命令mininet py net.get(h1).setIP(10.0.0.1/24)顺便提一句ping 不通时还要检查 Controller 是否在运行。在本地实验场景下如果交换机没连上 ControllerOpenFlow 流表不会下发数据包到了交换机就会被丢弃即使 IP 配置正确也 ping 不通。用mininet sh ps -ef | grep controller查看进程是否存活。5.4 设置 bw 限速后 iperf 测不出效果现象addLink(..., bw10, delay5ms)参数都写了但 iperf 测出来的带宽还是 90 Mbps 以上跟没设置一样。原因链路性能限制依赖 Linux tc 模块和网卡的netem调度器如果宿主机内核不支持或者 Mininet 使用的是用户态数据路径userspace switchtc 规则创建的 qdisc 不会生效。解决先把链路参数打印出来确认是否加载成功再检查交换机的数据路径。mininet links输出里每一行结尾会显示(10.0Mbit 5ms 1% loss)之类的参数没有显示就说明参数没传进去。再确认 OVS 的类型sudo ovs-vsctl show看是否用了typenetdev的用户态端口这种端口对 tc 的支持有缺陷。最稳妥的替代方案是换用sudo mn --switch ovs --link tc启动显式指定链路控制使用 tc 模式。5.5 虚拟机上 xterm 打不开主机终端现象在 Mininet CLI 里输入xterm h1宿主机上没有弹出终端窗口或者弹出来是黑屏卡死。原因Mininet 的xterm命令依赖 X11 显示环境如果是在 Windows 上用 VMware/VirtualBox 跑 Linux 虚拟机默认的 Display 环境变量没有配置好xterm 无法连接到 X server。解决先测试 VM 里能不能正常打开图形应用再检查 DISPLAY 变量。echo $DISPLAY如果输出为空执行export DISPLAY:0。如果用的是 SSH 远程登录到虚拟机还需要在 SSH 连接参数里加-X开启 X11 转发。这个功能在实验里不是必需品ping 测试已经能验证连通性打不开 xterm 并不影响实验完成但不妨知道问题出在哪免得在没图形界面的环境里干着急。6. 把实验脚本改造成可重复验证的测试脚本一个自动化的效率技巧实验做完了拓扑验证也通过了但这份资源的价值不应该止步于交一份报告。我一般会把实验里写过的 Python 脚本合并成一个通用的「一键测试脚本」下次再验证任何 Mininet 拓扑直接跑这个脚本省掉打开 Miniedit 拖拉节点的时间。我在做这份实验时写了一个run_test.py思路是接受一个拓扑类型参数自动启动网络然后依次执行dumpNodeConnections打印连接关系、pingAll验证连通性最后用 iperf 测出带宽数据并输出。核心代码长这样from mininet.net import Mininet from mininet.topo import SingleSwitchTopo from mininet.cli import CLI def run(topo): net Mininet(topotopo) net.start() print( 拓扑连接关系 ) net.dumpNodeConnections() print( 连通性测试 ) net.pingAll() print( 带宽测试 ) h1, h2 net.hosts[0], net.hosts[1] h1.cmd(iperf -s -p 5001 ) h2.cmd(iperf -c, h1.IP(), -p 5001 -t 5) net.stop() if __name__ __main__: run(SingleSwitchTopo(2))这段脚本把实验报告的流程变成了可重复的验证工具dumpNodeConnections对应实验报告里的py dumpNodeConnections(net.hosts)pingAll对应交互界面的全量 pingiperf 那两行对应 4.4 的手动测试。整个流程跑完大约 10 秒如果测试脚本运行稳定说明拓扑没有任何问题如果某个环节失败输出也会直接告诉你是连通性问题还是带宽问题。对这份实验报告本身我建议你拿到之后不要急着照着抄一遍完事。先把 miniedit 的可视化流程走一遍理解节点和链路的映射关系再用命令行建同一个拓扑体会两种方式的差异最后把第 4 章的 Python 脚本改一版带带宽限制的配合 iperf 验证。这三步走下来Mininet 的基本功就差不多了。从那以后我每次验证网络类课程设计里的拓扑都强制自己先写一个可重复运行的测试脚本——先跑通连通性再验证性能而不是每次重新敲命令。这个习惯帮我避开了很多「上次还能通、这次突然 ping 不通」的玄学问题希望你也能用上。本文还有配套的精品资源点击获取
返回列表