简介:这份PDF资料面向在Ubuntu 16.04环境下学习软件定义网络(SDN)与网络功能虚拟化(NFV)的开发者与网络实验人员,聚焦于通过源码方式安装Mininet这一轻量级网络仿真平台,帮助读者在本地快速搭建可自定义的网络拓扑,用于OpenFlow协议验证、网络流量分析与教学演示。资源包共1个PDF文件,大小约94KB,内容围绕源码获取、完整安装脚本执行、安装结果测试与版本查看等环节展开,并延伸至树状数据中心网络的构建思路,涉及核心、聚合、边缘交换机与主机的分层结构及扇出参数调整。目前已有2473人学习下载,适合具备一定Linux基础、希望深入理解Mininet安装机制与拓扑编程的读者参考,可据此完成从环境部署到简单网络仿真的完整实践,为后续SDN应用开发与实验调试提供可复用的操作依据。
1. 为什么今天还有人要在 Ubuntu 16.04 上源码装 Mininet
如果你手头有一台跑着 Ubuntu 16.04 的旧机器、一个只兼容老内核的仿真环境,或者一套锁死在 Python 2.7 上的网络实验脚本,那你大概率绕不开「源码安装 Mininet」这条路。Mininet 本身是个轻量级网络仿真器,能在一台机器上用软件模拟出交换机、主机、链路和控制器,做 SDN 教学、协议验证、拓扑压测都靠它。apt 装当然快,但 Ubuntu 16.04 官方源里的 Mininet 版本偏旧,OpenFlow 版本、Python 绑定、内核模块都可能和你的实验需求对不上,这时候源码编译就是唯一可控的路径。
这篇笔记面向两类人:一是在旧系统上必须把 Mininet 跑起来、且要能改源码的工程师;二是想搞清楚 Mininet 安装到底动了系统哪些地方、以后排错不抓瞎的从业者。我会按「依赖怎么备、源码怎么编、装完怎么验、坑在哪」的顺序讲,命令都能直接抄。需要先说明:Ubuntu 16.04 已经停止常规维护,源码安装的很多坑其实来自它的老工具链,这一点后面会反复提到。
2. 装之前先把依赖和内核这摊事理清楚
2.1 Mininet 源码安装到底依赖哪些组件
Mininet 不是一个孤立的二进制,它站在一堆系统组件上面。源码安装前,你得先明白每个依赖是干嘛的,不然报错了都不知道该动谁。
核心依赖分四类。第一类是编译工具链:gcc、g++、make、python2.7-dev,Mininet 的主体是 Python,但里面有些 C 扩展和mnexec这类辅助程序要编译。第二类是网络工具:iproute2、net-tools、openvswitch相关包,Mininet 默认用 Open vSwitch 做交换机,没有它就只能退到user模式的慢速交换机。第三类是 Python 库:pyparsing、pexpect,前者解析拓扑参数,后者用来和交互式命令打交道。第四类是内核能力:网络命名空间(network namespace)、cgroup、veth pair,这些是 Mininet 隔离主机和链路的底层机制。
在 Ubuntu 16.04 上,一条命令能把大部分依赖拉齐:
# 更新索引并安装编译与运行依赖 sudo apt-get update sudo apt-get install -y \ git build-essential python2.7 python2.7-dev \ iproute2 net-tools ethtool socat \ openvswitch-switch openvswitch-common \ python-pyparsing python-pexpect \ help2man这里有几个点要解释。python2.7-dev必须装,否则编译 Python C 扩展时会报Python.h: No such file or directory。openvswitch-switch提供ovs-vsctl和ovs-ofctl,Mininet 启动时会调用它们创建网桥。help2man是生成 man 手册用的,缺了它make install阶段可能中断。socat在部分拓扑里用于端口转发,不是必需但建议装上。
提示:如果你的机器之前装过 apt 版的 Mininet,先
sudo apt-get remove mininet清掉,否则源码装完后which mn可能指向旧版本,排查起来很费劲。
2.2 内核模块和命名空间要先自检
Mininet 能不能跑,一半取决于内核。Ubuntu 16.04 默认内核是 4.4 系列,命名空间和 Open vSwitch 支持是够的,但有些精简版系统或容器环境会裁掉模块。装之前先做三项自检。
第一项,看网络命名空间是否可用:
# 创建一个测试命名空间,成功则说明内核支持 sudo ip netns add mn_test sudo ip netns list sudo ip netns delete mn_test如果ip netns add报Operation not supported,说明内核没开CONFIG_NET_NS,这种情况在物理机上少见,在容器里常见,基本没法继续。
第二项,看 Open vSwitch 内核模块:
# 加载 ovs 模块并确认 sudo modprobe openvswitch lsmod | grep openvswitchlsmod有输出才算正常。如果modprobe报模块找不到,可能是linux-image-extra没装,补一句sudo apt-get install linux-image-extra-$(uname -r)再试。
第三项,确认 cgroup 挂载:
# 查看 cgroup 挂载点 mount | grep cgroupMininet 用 cgroup 做 CPU 和带宽限制,没有它--link tc之类的功能会失效,但基础拓扑还能跑。这三项自检做完,你对自己机器的底子就有数了,后面出问题能快速定位是内核还是用户态的事。
3. 从源码到可运行:Mininet 编译安装全流程
3.1 拉取源码与目录结构速览
Mininet 的源码托管在公开的 Git 仓库上,直接克隆即可。注意 Ubuntu 16.04 自带的 Git 版本较老,克隆大仓库时偶尔会有协议兼容问题,如果失败先sudo apt-get install -y git升级。
# 克隆 Mininet 源码到本地 cd ~ git clone https://github.com/mininet/mininet.git cd mininet # 查看当前分支和最近提交,确认代码状态 git branch git log --oneline -5克隆下来后,先别急着编译,花两分钟看目录结构,后面排错全靠它。mininet/下是 Python 包主体,bin/放mn等入口脚本,custom/是自定义拓扑示例,util/里有个install.sh是官方一键安装脚本,examples/是各种演示。mnexec.c在mininet/目录下,这是用 C 写的辅助程序,负责在命名空间里执行命令,编译时如果它挂了,mn启动会直接报错。
我一般会先看一眼util/install.sh里都装了什么,心里有数再手动执行,而不是无脑跑脚本。脚本里会调用apt-get装依赖、编译、装 Open vSwitch,步骤和手动做差不多,但它的好处是版本组合经过验证。如果你追求可控,就手动来;如果想省事,util/install.sh -a也能用,但要知道它改了什么。
3.2 编译安装的具体命令与参数
Mininet 的安装分两步:先make编译 C 辅助程序,再make install把 Python 包和脚本装到系统路径。官方推荐用make install而不是python setup.py install,因为前者会一并处理mnexec和 man 手册。
# 在 mininet 源码根目录执行编译 make # 编译成功后安装到系统 sudo make install # 刷新动态链接库缓存,确保 mnexec 能被找到 sudo ldconfigmake这一步主要编译mnexec.c,产出mnexec可执行文件。如果报gcc: command not found,说明build-essential没装好。如果报Python.h找不到,回去补python2.7-dev。make install会把mn、mnexec等装到/usr/local/bin,Python 包装到/usr/local/lib/python2.7/dist-packages。
这里有个参数值得说:make install默认前缀是/usr/local,如果你想装到别处,可以PREFIX=/opt/mininet sudo -E make install,但装到非标准路径后要自己配PATH和PYTHONPATH,新手不建议折腾。另外,make install不会自动装 Open vSwitch,OVS 得单独用 apt 装,前面依赖那步已经覆盖了。
装完后验证一下关键文件在不在:
# 确认 mn 和 mnexec 已就位 which mn which mnexec # 查看 Mininet 版本 mn --versionmn --version能打印出版本号,说明 Python 包路径没问题。如果报ImportError: No module named mininet,多半是PYTHONPATH没包含安装目录,检查python2.7 -c "import mininet; print(mininet.__file__)"的输出。
3.3 装完必须跑的三项验证
装完不验证,等于没装。我习惯跑三项测试,从轻到重,任何一项挂了都能缩小排查范围。
第一项,最小拓扑启动:
# 启动一个单交换机双主机拓扑,执行 pingall 后退出 sudo mn --test pingall这条命令会创建h1、h2和s1,然后让h1pingh2。输出里出现*** Results: 0% dropped就说明数据面通了。如果卡在*** Creating network不动,多半是 OVS 没起来,去看sudo service openvswitch-switch status。
第二项,指定控制器和交换机类型:
# 用远程控制器占位,交换机用 ovs,验证参数解析 sudo mn --controller=remote,ip=127.0.0.1 --switch=ovs --test pingall这里--controller=remote只是占位,没有真控制器也能启动,因为 Mininet 默认拓扑不强制连控制器。--switch=ovs明确用 Open vSwitch,如果报ovs-vsctl: not found,说明 OVS 没装或不在PATH。
第三项,交互模式里手动敲命令:
# 进入交互 CLI sudo mn # 在 mininet> 提示符下依次执行 mininet> nodes mininet> h1 ping -c 2 h2 mininet> exitnodes列出所有节点,h1 ping -c 2 h2验证连通性。这一步能过,说明你的 Mininet 已经具备日常实验能力。三项都过,源码安装就算成功了。
4. 源码装 Mininet 最容易翻车的几个地方
4.1 现象:mn启动报Cannot find required executable mnexec
原因很直接:mnexec没编译出来,或者编译出来了但不在PATH里。源码安装时make失败但被忽略,直接跑了make install,就会这样。另一种情况是装到了/usr/local/bin,但当前 shell 的PATH没包含它。
解决分两步。先确认文件存在:ls -l /usr/local/bin/mnexec。不存在就回源码目录重新make,看编译报错。存在但which mnexec找不到,就export PATH=/usr/local/bin:$PATH,并写进~/.bashrc。如果make时报mnexec.c里某个头文件缺失,补装libc6-dev。
4.2 现象:pingall全部丢包,但节点都起来了
这是最经典的坑。节点能创建、nodes能列出,但主机之间 ping 不通。原因通常是 Open vSwitch 的网桥没正确建立,或者内核转发没开。
先看 OVS 状态:sudo ovs-vsctl show,正常应该看到s1网桥和两个端口。如果网桥是空的,说明 Mininet 创建网桥时失败了,去看/var/log/openvswitch/ovs-vswitchd.log。另一个常见原因是net.ipv4.ip_forward没开,虽然 Mininet 内部通信不依赖它,但某些拓扑会受影响,执行sudo sysctl -w net.ipv4.ip_forward=1再试。还有一个隐蔽原因:之前实验残留的 OVS 配置没清,sudo mn -c清理后再启动。
4.3 现象:ImportError: No module named pyparsing
Mininet 用pyparsing解析拓扑参数,缺了它mn直接起不来。Ubuntu 16.04 的python-pyparsing包对应 Python 2,装它就行。但如果你之前用pip装过 Python 3 版本的pyparsing,可能会出现版本冲突,python2.7 -c "import pyparsing"报错但python3正常。
解决:sudo apt-get install -y python-pyparsing,然后用python2.7 -c "import pyparsing; print(pyparsing.__version__)"确认。如果还报错,检查是不是PYTHONPATH里混进了 Python 3 的 site-packages,用python2.7 -c "import sys; print(sys.path)"看一眼,把可疑路径从环境变量里去掉。
4.4 现象:make install报权限错误或 man 手册生成失败
make install要写/usr/local,必须sudo。如果忘了sudo,会在拷贝阶段报Permission denied。另一个坑是help2man没装,生成mn.1时失败,整个 install 中断。补装help2man即可。
还有一种情况:之前用sudo跑过make,导致源码目录里部分文件属主变成 root,后续用普通用户make时写不进去。解决是sudo chown -R $USER:$USER ~/mininet把属主改回来,再重新编译。这个坑很隐蔽,因为报错信息往往指向具体文件而不是权限本身。
4.5 现象:重启机器后 Mininet 不能用了
Ubuntu 16.04 上,Open vSwitch 服务默认可能没设开机自启,重启后ovs-vswitchd没跑,Mininet 启动时创建网桥就失败。表现是mn卡住或报could not connect to ovs。
解决:sudo systemctl enable openvswitch-switch设自启,然后sudo systemctl start openvswitch-switch立即启动。验证sudo service openvswitch-switch status显示 active。另外,如果你之前手动modprobe openvswitch加载了模块,重启后模块也没了,把openvswitch写进/etc/modules让它开机加载。
5. 让源码安装的 Mininet 真正好用:两个进阶技巧
源码安装最大的价值不是「装上了」,而是「能改」。apt 装的 Mininet 你动不了源码,源码装的你可以直接改 Python 包里的逻辑,加自定义拓扑、改默认参数、甚至给mn加子命令。这里分享两个我常用的技巧。
第一个技巧:用PYTHONPATH做开发态覆盖,不动系统安装。你可以在~/mininet-dev/下放一份改过的mininet包,然后export PYTHONPATH=~/mininet-dev:$PYTHONPATH,这样mn会优先加载你的版本,系统里那份保持干净。调试时改完直接跑,不用反复make install。验证加载路径用python2.7 -c "import mininet; print(mininet.__file__)",输出指向你的开发目录就对了。
第二个技巧:自定义拓扑文件放在custom/下,用mn --custom加载。比如写一个三交换机环形拓扑:
# ~/mininet/custom/ring3.py from mininet.topo import Topo class Ring3Topo(Topo): def build(self): # 创建三台交换机和三台主机 switches = [self.addSwitch('s%d' % i) for i in range(1, 4)] hosts = [self.addHost('h%d' % i) for i in range(1, 4)] # 主机直连对应交换机 for h, s in zip(hosts, switches): self.addLink(h, s) # 交换机组成环 self.addLink(switches[0], switches[1]) self.addLink(switches[1], switches[2]) self.addLink(switches[2], switches[0]) topos = {'ring3': Ring3Topo}加载命令是sudo mn --custom ~/mininet/custom/ring3.py --topo ring3 --test pingall。topos字典的键就是--topo后面跟的名字。这个文件改完立即生效,不需要重新安装,非常适合快速迭代实验拓扑。
参数上要留意:addLink可以带bw、delay、loss等参数模拟链路质量,比如self.addLink(h, s, bw=10, delay='5ms'),但bw依赖tc和 cgroup,前面自检没过的机器上会静默失效,不报错但限速不生效,这点要心里有数。
最后一个习惯:每次实验前sudo mn -c清理残留,实验后也清一次。源码装的 Mininet 在异常退出时容易留下 OVS 网桥和命名空间,攒多了会拖慢系统甚至导致新拓扑创建失败。我吃过这个亏,后来把mn -c当成肌肉记忆,省了很多排查时间。希望帮到你。
本文还有配套的精品资源,点击获取