搞SDN实验的人十有八九都绕不开Ryu和Mininet这对组合。我上次在一台Ubuntu18.04上从头装了一遍中间踩了不少坑包括Python版本冲突、pip依赖编译不过、Mininet残留进程、OpenFlow握手失败前前后后折腾了大半天。如果你也在准备搭一套SDN实验环境或者想在公司内部快速做个网络自动化Demo这篇记录可以直接照抄。我会把安装链路、参数选择、验证方法一次讲清楚并标注哪些地方容易翻车。适合一边看一边敲。1. 为什么是Ubuntu18.04 Ryu Mininet1.1 Ryu和Mininet分别解决什么问题Ryu是当下SDN实验里非常常用的控制器项目。说人话就是它是一台“决策大脑”交换机会把看不懂的数据包交给它它决定怎么转发再把转发规则下发给交换机。Ryu基于Python支持OpenFlow多个协议版本同时留了一套干净的应用接口你可以用Python很轻松地写上层的网络策略。Mininet则是一台“网络模拟机”它用进程和虚拟网卡在一台Linux主机上模拟出多个交换机、主机和链路完全不需要真实硬件。两者配合你可以在纯软件环境里跑通一整套OpenFlow协议流程从拓扑启动、控制器握手、数据包上报、流表下发到最终流量转发全部能看见。这套组合的实际价值很明确用它验证算法、测试网络策略、写课程作业、做入门研究都非常顺手。相比买交换机、搭真机拓扑成本基本为零而且复现别人实验的速度快多了。对刚接触SDN的人来讲Ryu的代码可读性比Java系的控制器好很多报错信息也更直白。我见过很多做网络方向的学生第一个Demo都是在这套组合上跑通的。1.2 为什么是这套组合而不是其他控制器有人会纠结控制器还有Floodlight、ONOS、OpenDaylight这些为什么非要用Ryu。我的看法很直接如果你的目标是理解OpenFlow基础、快速写自定义应用Ryu是学习曲线最平缓的一个。Floodlight走Java路线模块化深度更大但代码量摆在那里打开工程先看半小时才能找到入口ONOS和OpenDaylight更适合大型编排场景启动之后一堆服务在跑光排日志就要半天。Ryu只有一个进程一个Python虚拟环境就能装完启动命令就一行对新手极度友好。Mininet自带的默认控制器也值得一提。它只能让拓扑里的主机互相连通本质上只是做一个简单的转发谈不上自定义逻辑。你一旦想控制转发路径、做链路发现、做包分析就必须外接正经控制器。Ryu和Mininet可以跑在同一台机器上协议交互都走本机回环接口不需要额外网络环境这种“单机SDN实验床”是其他控制器给不了的便利。至于系统为什么选Ubuntu18.04纯粹是因为国内外的SDN相关资料大量基于这个版本。它的apt源里直接有Mininet包Python3.6虽然老但配合虚拟环境照样能跑Ryu。用更新的Ubuntu22.04也不是不行但Python3.10下一些依赖包需要重新编译折腾成本明显更高。实验环境宁可选择资料最多的版本别追新。2. 安装前的环境准备与总体规划2.1 先花两分钟确认系统状态我建议用虚拟机搭一个干净的系统分配内存至少2GB如果想同时跑多个交换机最好给4GB。确认系统版本、架构、Python情况打开终端一次跑完lsb_release -a uname -m python3 --version pip3 --versionUbuntu18.04的默认Python版本是3.6.9配套的pip版本比较老后面需要升级。如果pip3不存在先安装sudo apt update sudo apt install -y python3-pip git vim net-tools curl wget build-essential为什么强调装build-essential因为Ryu的部分依赖比如eventlet相关的加密和链接库在编译时少不了gcc和头文件没有这些工具链后面pip install会报一堆红字错误。接下来做一次软件源升级sudo apt update sudo apt upgrade -y这一步耗时但值得。干净的系统如果不先升级装上Mininet后很容易遇到依赖库版本过低导致的诡异问题。升级完成后我习惯执行一下sudo reboot让系统以最新内核运行实验环境能少很多干扰。2.2 规划安装顺序和目录这里给出我的顺序建议先装Mininet再装Ryu。Mininet安装脚本可能会带上Open vSwitch、Wireshark这些底层组件它们不会和Ryu的Python库产生冲突。Ryu我们会单独放进虚拟环境和系统Python隔离开装完再也不会弄脏系统环境。我习惯创建两个目录源码和虚拟环境分开管理sudo mkdir -p /opt/sdn sudo chown $USER:$USER /opt/sdn mkdir -p ~/ryu-env/opt/sdn用来放Mininet源码等需要编译安装的东西~/ryu-env用于存放Python虚拟环境。这样以后想删掉环境直接删除目录就行不需要动系统任何包比在全局环境里装Ryu清爽得多。2.3 为什么非要用虚拟环境直接执行sudo pip3 install ryu当然能装但我不推荐。Ryu会拉入eventlet、oslo.config、netaddr、paramiko等一大串依赖这些包又会去覆盖系统Python的对应版本。等哪一天系统某个工具依赖了旧版本就被弄坏。更现实的问题是后续你可能会同时研究多个控制器有的写Ryu有的写别的虚拟环境能给你隔离出一块互不干扰的区域。打个比方虚拟环境相当于手机里的应用沙盒系统Python是系统目录。你可以在沙盒里随意折腾Ryu之后删掉沙盒系统目录还是干净的。下面所有Ryu相关命令默认都做了虚拟环境处理这也是很多初学者最忽略的一步。3. 安装Mininet能快则快也要知道源码安装的路径3.1 直接通过apt安装Mininet最简单的方式一条命令sudo apt install -y mininet装完后验证版本mn --version能看到版本号就说明核心装好了。apt安装的优势是省事Ubuntu官方源里的版本虽然不算最新但跑基本的pingall和Ryu实验完全足够。对绝大多数人来说直接走这条路就行没必要一上来就编译源码。如果你后面需要更多实验组件也可能随时用apt补装openvswitch-switch、wireshark等。安装过程中如果提示某些软件包无法安装优先确认apt update有没有真正跑完。有时候是网络源连接超时重新跑一次sudo apt update再安装就好不要急着换源。3.2 源码安装Mininet的完整路线如果apt里的Mininet版本太老或者你需要修改Mininet自己的源码那就走源码安装。先进入/opt/sdn拉取Mininet仓库cd /opt/sdn git clone 官方Mininet仓库地址 cd mininet这里我不写具体仓库地址了以你当时查到的官方地址为准。克隆完成后查看安装脚本帮助./util/install.sh -h常见参数我解释一下-n只安装Mininet核心程序速度最快-a安装所有推荐依赖包括Open vSwitch、Wireshark等适合想一步到位的人-w额外安装Wireshark方便后面抓包。如果你只想要一个能连Ryu的最小环境用./util/install.sh -n就够了。不过我在实验中发现很多SDN教程会用到Open vSwitch的高级功能所以建议干脆用./util/install.sh -a。代价是编译时间会很长可以去泡杯咖啡。需要留意的是源码安装结束后Mininet可能会在~/mininet或/opt/sdn/mininet目录下运行还要把mn命令的路径加入环境变量。如果用apt安装就不存在这个问题这也是我推荐普通用户直接apt的原因。3.3 安装后立即验证Mininet是否可用不管用哪种方式装完都跑一次最基本的连通性测试sudo mn --topo single,3 --mac --switch ovs --controller default进入mininet提示符后执行mininet pingall如果看到所有主机之间都是OK说明Mininet核心工作正常。这里的--mac参数让每台主机的MAC地址从00:00:00:00:00:01开始递增方便后续抓包识别--switch ovs明确使用Open vSwitch作为交换机实现。测试完用exit退出。如果发现进程残留比如直接关掉了终端下次启动Mininet时可能报错那就先执行sudo mn -c这个命令会清理所有残留的网络命名空间和进程算是Mininet玩家的必备口诀。4. 安装Ryu控制器把Python依赖坑踩平4.1 先创建Python虚拟环境并检查pipRyu的安装在我看来难度比Mininet大因为坑都藏在国内读者最容易忽略的Python环境里。先确保有python3-venvsudo apt install -y python3-venv python3-dev libffi-dev libssl-dev然后创建虚拟环境python3 -m venv ~/ryu-env创建完成后激活source ~/ryu-env/bin/activate激活后命令行前面会出现(ryu-env)标志。现在升级关键的构建工具pip install -U pip setuptools wheel这一步很有必要。Ubuntu18.04自带的pip版本太老直接装Ryu非常容易在处理setup.py时出错。升级完这些基础工具后面会少很多问题。顺便提一句如果你的pip在安装依赖包时下载缓慢可以临时指定一个网络延迟更低的镜像源具体源名根据你自己所在网络环境去选这里不展开。4.2 安装Ryu本体和依赖库在激活的虚拟环境中执行pip install ryu安装过程会拉取几十个依赖包其中eventlet、oslo.config、netaddr、paramiko都是重量级包。如果网络状况不好过程中可能卡在下载某个包上。我第一次装的时候卡了快二十分钟最后发现是pip版本太老导致的兼容问题升级后重跑一次就顺利了。如果安装过程中报错十有八九是缺系统级编译依赖。比如看到和cffi、cryptography相关的错误说明缺少libffi-dev或libssl-dev按前面说的补装就行。装完之后重新执行pip install ryu这次基本能顺利通过。装好后可以用pip list | grep ryu pip list | grep eventlet确认Ryu和eventlet都出现在列表里。4.3 验证Ryu能否正常启动闲话不多说先看版本号ryu-manager --version能输出版本号说明安装没问题。再启动一个最简单的二层交换机应用ryu-manager ryu/app/simple_switch_13.py看到日志刷出来最后变成类似join a single switch的状态就说明控制器已经起来了。此时不要关掉这个窗口它在后台监听控制端口。另外开一个终端查看监听端口sudo netstat -tlnp | grep ryu注意看是6653还是6633记下这个端口。不同版本、不同配置下默认端口有差异后面Mininet连控制器时用错端口是头号排查点。如果启动时报缺少某个Python模块直接回到虚拟环境补装对应包即可。但千万别急着把所有依赖全部升级到最新Ryu对一些库的版本有隐性要求全量升级反而会造成新的不兼容。5. 让Mininet连上Ryu从安装到跑通的最后一步5.1 先把控制器应用拉起来在做连接测试之前我强烈建议先启动Ryu再启动Mininet。原因很简单Mininet启动交换机会立刻发起OpenFlow连接如果控制器还没就位交换机会反复重连虽然最终也能连上但日志里会多一些无谓的报错。在激活虚拟环境的情况下启动Ryusource ~/ryu-env/bin/activate ryu-manager ryu/app/simple_switch_13.py保持这个窗口在前台运行。simple_switch_13.py的作用是模拟一个二层自学习交换机控制器收到未知目的地的包会先学习源MAC然后泛洪处理等目标MAC也学习到位后续相同流向的数据包就会直接命中流表不再上报控制器。这是SDN流表机制最直观的演示。如果想在后台启动方便关掉终端继续干活也可以用nohup ryu-manager ryu/app/simple_switch_13.py /tmp/ryu.log 21 不过调试阶段还是建议前台运行日志看起来更直观。5.2 启动Mininet并指定远程控制器新开一个终端启动Mininetsudo mn --topo linear,2 --mac --switch ovs --controller remote,ip127.0.0.1,port6653把port改成你刚才netstat查到的实际端口。如果Ryu监听的是6633就写6633。这里的--topo linear,2表示两个交换机串联每个交换机下面挂一台主机。拓扑逻辑是h1 -- s1 -- s2 -- h2你可以在Mininet里用net命令查看当前网络结构也可以用nodes列出所有节点。启动时如果看到Ryu日志窗口刷出交换机的连接信息说明OpenFlow握手已经成功。正常情况下Ryu会识别到交换机的datapath_id后续所有流表操作都围绕这个ID展开。5.3 跑通pingall并查看流表在Mininet提示符下执行mininet pingall如果四个方向的主机都能ping通恭喜Ryu和Mininet已经正式打配合了。第一次ping时控制器的日志会频繁上报packet_in消息因为交换机没有现成的流表每个未知目的地的包都要交给控制器判断。等ping结束后再执行mininet dpctl dump-flows能看到类似下面的流表项cookie0x0, duration..., table0, n_packets..., idle_timeout..., priority1, ip,in_port1,nw_src...,nw_dst..., actionsoutput:2这就是控制器下发的精确转发规则。你来回多ping几次再执行dpctl dump-flows会发现流表项数量逐渐稳定下来而不是每次都有大量packet_in上报。这说明自学习机制生效了。如果只想查看某个交换机的流表也可以用sudo ovs-ofctl dump-flows s1s1是Mininet创建的第一个OVS网桥的名字。5.4 顺手做一次抓包分析很多人装完环境就收工了我建议再做一步抓包因为OpenFlow报文交互过程永远看不腻。在Mininet运行期间把数据包保存下来sudo tcpdump -i s1-eth2 -vv -w /tmp/of.pcap tcp port 6653然后让h1 ping h2等待几秒停掉tcpdump用Wireshark打开临时目录下的pcap文件。重点看一次性连接后有没有Packet In、Packet Out、Flow Mod这三类OpenFlow消息。每一条消息对应控制器和交换机的一次对话。这一步会让你对流表下发机制理解得非常扎实。6. 常见问题与排查技巧实录6.1 端口对不上或OpenFlow握手没反应我把这个问题排到第一位因为八成的新手失败都栽在这里。现象是Mininet启动时没有任何报错但Ryu日志里也什么都没有。这时候先查端口sudo netstat -tlnp | grep ryu然后对照Mininet启动命令里的port参数。很多教程默认写6653但某些Ryu版本默认监听6633参数一错连接就建立不起来。另外确认Ryu是否真的运行在虚拟环境里如果之前用全局Python装过可能启动的是另一个残留进程。还有一种情况是防火墙挡了本机回环虽然用127.0.0.1通常不会触发防火墙但如果你开了ufw还是检查一下sudo ufw status如果开启直接放行对应端口或者临时关闭ufw再测。6.2 pip安装Ryu时依赖编译失败我在乌班图18.04上遇到最多的是cryptography编译失败日志末尾能看到“fatal error: openssl/opensslv.h: No such file or directory”。原因是系统缺少OpenSSL开发头文件。解决sudo apt install -y libssl-dev libffi-dev python3-dev装完头文件激活虚拟环境重新升级pip和setuptoolssource ~/ryu-env/bin/activate pip install -U pip setuptools wheel pip install ryu记住一个原则失败后先把缺失的系统组件补齐而不是反复重装Python包。系统组件是地基本Python依赖是房屋。6.3 Mininet启动时报缺少ovs-vsctl如果在执行mn命令时出现“cannot find required executable ovs-vsctl”或者“could not find required executable ovs-vsctl”基本是Open vSwitch没装或者没装全。用apt补齐sudo apt install -y openvswitch-switch如果你当初是源码安装Mininet但只用了-n参数现在补一条cd /opt/sdn/mininet ./util/install.sh -v这个参数会专门安装Open vSwitch相关组件。装完再启动Mininet大概率就好了。6.4 重复实验后的残留进程这个坑几乎每个人都踩过。实验做完不退出Mininet直接关终端下次再启动的时候报错说网络命名空间冲突或者拓扑里的网桥一直创建不起来。最直接的清理命令sudo mn -c如果清理完仍有问题我习惯补上这几条sudo pkill -f ryu-manager sudo pkill -f ovs-vswitchd sudo systemctl restart openvswitch-switch前提是当前没有其他重要的Open vSwitch业务纯实验环境这么操作没问题。清理之后重新sudo mn启动一切会恢复正常。6.5 问题排查速查表现象可能原因处理办法Mininet连不上控制器端口不一致netstat查端口启动命令里修改portRyu启动报缺少模块依赖没装全或venv未激活确认(ryu-env)前缀补装依赖pip编译报错系统头文件缺失安装libssl-dev、libffi-dev、python3-devmn找不到ovs-vsctlOVS未安装apt装openvswitch-switchpingall不通流表残留或控制器未启动sudo mn -c清理重新顺序启动拓扑无法创建上次未正常退出sudo mn -c清理重启交换机服务最后分享一个我很喜欢的启动方式把Ryu的启动过程封装成一个脚本每次实验只敲一条命令省得每次都要手动激活虚拟环境再敲一长串参数。脚本内容很简单#!/bin/bash source ~/ryu-env/bin/activate exec ryu-manager ryu/app/simple_switch_13.py保存成~/sdn/start_ryu.sh然后chmod x ~/sdn/start_ryu.sh。Mininet那边也可以做类似封装把固定的拓扑和remote参数写进脚本。这套组合在实际操作中最大的价值就是“可复现”你今晚记录的命令明天重启机器后照样能一键跑通。踩过几次坑之后我现在装SDN环境都严格走这套流程很少再被环境问题打断实验思路。
阅读完成 · 觉得有帮助?