Day 4 学习笔记
前三天我们一直在看理论,今天终于要动手了。Mininet 是 SDN 领域最常用的网络仿真工具,它能在一台电脑上模拟出由多台交换机和主机组成的网络拓扑,用来做各种网络实验。
这篇文章会带你从零搭建 Mininet 环境,并完成一系列基础实验。
一、什么是 Mininet
Mininet 是一个轻量级的网络仿真工具,由斯坦福大学开发。它的核心能力是:
- 在一台普通电脑上创建虚拟的交换机、主机和链路
- 这些虚拟设备运行的是真实的 Linux 网络栈,不是模拟器
- 支持 OpenFlow 协议,可以连接真实的 SDN 控制器
- 用 Python 脚本就能定义任意网络拓扑
简单说,Mininet 就是一个"网络沙箱",你可以在里面随意搭建、测试网络,不用担心影响真实网络。
1.1 Mininet 能做什么
| 用途 | 说明 |
|---|---|
| 快速原型 | 几分钟搭建一个复杂的网络拓扑进行测试 |
| SDN 实验 | 配合 Ryu/ONOS 等控制器验证 OpenFlow 功能 |
| 网络调试 | 用 Wireshark 抓包分析数据包在虚拟网络中的流转 |
| 教学演示 | 课堂上现场演示网络协议的行为 |
1.2 安装环境
我们选择在 WSL2 + Ubuntu 24.04 上安装 Mininet,这也是目前最推荐的方式。原因:
- WSL2 内核支持网络命名空间,Mininet 需要这个功能
- Ubuntu 软件源丰富,依赖安装方便
- 不需要虚拟机,启动快、资源占用小
二、安装 WSL2
在安装 Mininet 之前,需要先搭建 Linux 环境。WSL2(Windows Subsystem for Linux 2)是 Windows 内置的 Linux 子系统,不需要装虚拟机就能直接用。
2.1 什么是 WSL
WSL 是 Windows 系统内嵌的 Linux 环境。通过 WSL 可以:
- 直接在 Windows 上运行 Ubuntu、Debian 等 Linux 发行版
- 运行 Linux 命令、开发代码
- 直接访问 Windows 电脑的文件系统
2.2 WSL2 vs 虚拟机
| 方案 | 安装复杂度 | 启动速度 | 资源占用 |
|---|---|---|---|
| 虚拟机 | 步骤较多 | 较慢 | 高 |
| WSL2 | 简单 | 秒级启动 | 极低 |
2.3 系统要求
- Windows 11:默认就是 WSL2
- Windows 10 2004 及以后版本:默认是 WSL2
- Windows 10 2004 以前的版本:默认是 WSL1,需要升级系统
2.4 安装步骤
第一步:打开管理员终端
右键点击"开始菜单",选择"终端(管理员)"。一定要选带"管理员"的版本。
第二步:查看可安装的发行版
|
|
第三步:安装 Ubuntu 24.04
|
|
等待安装完成。
第四步:配置用户与密码
安装完成后需要创建默认用户:
- 回车创建用户
- 输入用户名
- 输入两次密码(输入密码时不显示,输入完按回车即可)
配置完成后命令行会切换成刚创建的用户名,此时已进入 Ubuntu 系统。
第五步:验证安装
|
|
输出应显示 Ubuntu 24.04。
2.5 日常使用
| 命令 | 功能 |
|---|---|
wsl |
启动 Linux 系统 |
wsl --shutdown |
关闭 WSL,节省内存 |
wsl --unregister Ubuntu-24.04 |
卸载 Ubuntu |
在 Ubuntu 系统中可以直接访问 Windows 的 C 盘、D 盘、E 盘,文件互通。比如在 WSL 中输入 ls /mnt/d/ 就能看到 D 盘的文件。
三、安装 Mininet
在 WSL2 的 Ubuntu 终端中执行以下步骤。
3.0 基础环境配置
刚装好的 WSL2 Ubuntu 几乎是空的,需要先做几件基础事情。
更新软件源
|
|
这一步会更新系统自带的软件包列表,可能需要几分钟,取决于网速。
安装 Git
Git 是从 GitHub 下载源码的必备工具,Ubuntu 默认没有预装:
|
|
安装 Python
Ubuntu 24.04 自带 Python 3,但 Mininet 的 Makefile 里用的是 python 命令(不是 python3),需要创建软链接:
|
|
安装编译工具
Mininet 的一些组件(如 mnexec)需要用 C 编译器构建:
|
|
3.1 从源码安装
Mininet 官方推荐从 GitHub 源码安装,这样可以获取最新版本:
|
|
3.2 安装过程中的常见问题
| 问题 | 原因 | 解决方法 |
|---|---|---|
Unable to locate package mininet |
Ubuntu 默认源没有 Mininet | 从源码安装 |
Package pep8 has no installation candidate |
Ubuntu 24.04 中 pep8 已改名 | apt install pycodestyle |
externally-managed-environment |
Ubuntu 24.04 禁止全局 pip 安装 | 安装 python3-pip-whl |
Cannot find required executable mnexec |
mnexec 未编译 | cd mininet && sudo make install |
Cannot find required executable ovs-vsctl |
Open vSwitch 未安装 | apt install openvswitch-switch |
3.3 修复 mnexec
mnexec 是 Mininet 的核心执行工具,有时安装脚本不会自动编译它,需要手动处理:
|
|
然后安装 Open vSwitch(Mininet 需要它作为虚拟交换机):
|
|
3.4 验证安装
|
|
如果输出版本号(如 2.3.1b4),说明安装成功。
四、第一个实验:默认拓扑 pingall
Mininet 自带一个默认拓扑:1 台交换机 + 2 台主机。用 --test pingall 可以一键创建拓扑、启动、测试连通性,然后自动退出。
|
|
执行结果:
*** Creating network
*** Adding hosts: h1 h2
*** Adding switches: s1
*** Adding links: (h1, s1) (h2, s1)
*** Configuring hosts h1 h2
*** Starting controller
*** Starting 1 switches: s1 ...
*** Ping: testing ping reachability
h1 -> h2
h2 -> h1
*** Results: 0% dropped (2/2 received)
*** Done
completed in 0.247 seconds
4.1 解读输出
逐步拆解这个过程:
- 创建网络 — Mininet 创建了虚拟的网络命名空间
- 添加主机 — 创建了 h1 和 h2 两台虚拟主机,各自有独立的 IP 地址
- 添加交换机 — 创建了 s1(默认使用 OVS Bridge 模式)
- 添加链路 — h1 连到 s1,h2 连到 s1
- 配置主机 — 给 h1(10.0.0.1)和 h2(10.0.0.2)分配 IP
- Ping 测试 — h1 ping h2,h2 ping h1,全部成功
- 0% dropped — 没有丢包,网络连通性正常
4.2 网络拓扑图
这个实验的拓扑非常简单:
┌──────┐ ┌──────┐
│ h1 │ │ h2 │
│.0.0.1│ │.0.0.2│
└──┬───┘ └───┬──┘
│ │
└────────┬────────┘
│
┌────┴────┐
│ s1 │
│ 交换机 │
└─────────┘
两台主机通过同一台交换机互联,相当于两台电脑连在同一个交换机上。
五、指定拓扑实验
Mininet 内置了几种常见拓扑,通过 --topo 参数指定。
5.1 Single 拓扑:1 台交换机 + N 台主机
|
|
结果:
*** Adding hosts: h1 h2 h3
*** Adding switches: s1
*** Ping: testing ping reachability
h1 -> h2 h3
h2 -> h1 h3
h3 -> h1 h2
*** Results: 0% dropped (6/2 received)
拓扑图:
┌──────┐ ┌──────┐ ┌──────┐
│ h1 │ │ h2 │ │ h3 │
└──┬───┘ └──┬───┘ └──┬───┘
│ │ │
└────┬────┴────┬────┘
│ │
┌────┴─────────┴────┐
│ s1 │
└───────────────────┘
3 台主机两两互通,总共 6 次 ping(h1→h2、h1→h3、h2→h1、h2→h3、h3→h1、h3→h2),全部成功。
4.2 Linear 拓扑:N 台交换机串联
|
|
结果:
*** Adding hosts: h1 h2 h3 h4
*** Adding switches: s1 s2 s3 s4
*** Adding links: (h1,s1) (h2,s2) (h3,s3) (h4,s4) (s2,s1) (s3,s2) (s4,s3)
*** Ping: testing ping reachability
h1 -> h2 h3 h4
h2 -> h1 h3 h4
h3 -> h1 h2 h4
h4 -> h1 h2 h3
*** Results: 0% dropped (12/12 received)
completed in 0.615 seconds
拓扑图:
┌────┐ ┌────┐ ┌────┐ ┌────┐
│ h1 │ │ h2 │ │ h3 │ │ h4 │
└─┬──┘ └─┬──┘ └─┬──┘ └─┬──┘
│ │ │ │
┌─┴──┐ ┌─┴──┐ ┌─┴──┐ ┌─┴──┐
│ s1 │────│ s2 │────│ s3 │────│ s4 │
└────┘ └────┘ └────┘ └────┘
4 台交换机串联成一条线,每台交换机下挂一台主机。注意完成时间从 0.352 秒增加到了 0.615 秒,因为交换机之间的转发路径变长了。
六、交互式操作
除了命令行一键测试,Mininet 还提供了一个交互式 CLI,可以手动操作每个节点。
5.1 启动 Mininet
|
|
启动后进入 Mininet 命令行:
mininet>
5.2 查看节点和拓扑
mininet> nodes
available nodes are:
h1 h2 s1
mininet> net
h1 h1-eth0:s1-eth1
h2 h2-eth0:s1-eth2
s1 lo: s1-eth1:h1-eth0 s1-eth2:h2-eth0
nodes 列出所有节点,net 显示每个节点的接口和连接关系。
5.3 手动 Ping 测试
mininet> h1 ping h2
PING 10.0.0.2 (10.0.0.2) 56(84) bytes of data.
64 bytes from 10.0.0.2: icmp_seq=1 ttl=64 time=1.52 ms
64 bytes from 10.0.0.2: icmp_seq=2 ttl=64 time=0.114 ms
64 bytes from 10.0.0.2: icmp_seq=3 ttl=64 time=0.121 ms
...
h1 ping h2 表示在 h1 上执行 ping 命令。按 Ctrl + C 停止。
可以看到第一个包的延迟是 1.52ms(因为要查 ARP 表),后面稳定在 0.1ms 左右,说明虚拟网络的延迟非常低。
5.4 带宽测试
mininet> iperf
*** Iperf: testing TCP bandwidth between h1 and h2
*** Results: ['91.8 Gbits/sec', '91.6 Gbits/sec']
iperf 测试 h1 到 h2 的 TCP 带宽。结果显示 91.8 Gbits/sec,这是因为虚拟网络走的是内存,带宽远超物理网络。
5.5 自定义拓扑实验
Mininet 内置的拓扑有限,我们可以用 Python 脚本定义任意拓扑。下面是一个 2 交换机 + 4 主机的例子。
创建文件 topo.py:
|
|
拓扑图:
┌────┐ ┌────┐
│ h1 │ │ h2 │
└─┬──┘ └─┬──┘
│ │
┌─┴──┐ ┌─┴──┐
│ s1 │────│ s2 │
└─┬──┘ └─┬──┘
│ │
┌─┴──┐ ┌─┴──┐
│ h3 │ │ h4 │
└────┘ └────┘
运行:
|
|
结果:
*** Ping: testing ping reachability
h1 -> h2 h3 h4
h2 -> h1 h3 h4
h3 -> h1 h2 h4
h4 -> h1 h2 h3
*** Results: 0% dropped (12/12 received)
两台交换机之间有链路连接,h1/h2 通过 s1 通信,h3/h4 通过 s2 通信,跨交换机的流量经过 s1-s2 链路转发。
5.6 tcpdump 抓包
Mininet 的主机可以运行 tcpdump 来抓取经过网卡的数据包。先安装:
|
|
然后启动自定义拓扑进入交互模式:
|
|
在 h1 上启动抓包(后台运行),然后让 h1 ping h2:
mininet> h1 tcpdump -i h1-eth0 -c 5 &
mininet> h1 ping -c 3 h2
输出:
tcpdump: listening on h1-eth0, link-type EN10MB (Ethernet), snapshot length 262144 bytes
11:33:59.283728 IP6 fe80::b838:87ff:fee5:35ad > ip6-allrouters: ICMP6, router solicitation, length 16
PING 10.0.0.2 (10.0.0.2) 56(84) bytes of data.
64 bytes from 10.0.0.2: icmp_seq=1 ttl=64 time=2.07 ms
64 bytes from 10.0.0.2: icmp_seq=2 ttl=64 time=0.121 ms
64 bytes from 10.0.0.2: icmp_seq=3 ttl=64 time=0.111 ms
tcpdump 抓到了 IPv6 路由请求包(ICMP6 router solicitation),这是主机启动时自动发送的。如果想只抓 IPv4 的 ICMP 包,可以用过滤器:
mininet> h1 tcpdump -i h1-eth0 -c 5 icmp &
mininet> h1 ping -c 3 h2
-c 5 表示抓够 5 个包后自动停止,& 让它在后台运行。
5.7 退出
mininet> quit
七、常用命令速查
| 命令 | 作用 |
|---|---|
sudo mn |
启动默认拓扑并进入交互模式 |
sudo mn --test pingall |
一键测试连通性 |
sudo mn --topo single,3 |
指定 1 交换机 + 3 主机 |
sudo mn --topo linear,4 |
指定 4 交换机线性拓扑 |
sudo mn --custom topo.py --topo mytopo |
使用自定义拓扑 |
nodes |
查看所有节点 |
net |
查看网络连接 |
h1 ping h2 |
在 h1 上 ping h2 |
iperf |
TCP 带宽测试 |
h1 tcpdump -i h1-eth0 -c 5 & |
在 h1 上后台抓包 |
exit / quit |
退出 Mininet |
sudo mn -c |
清理残留的 Mininet 进程 |
八、今日学习总结
| 项目 | 内容 |
|---|---|
| 环境搭建 | WSL2 + Ubuntu 24.04 + Mininet 2.3.1 + OVS |
| 基础实验 | default pingall、single-3 pingall、linear-4 pingall |
| 交互操作 | nodes、net、h1 ping h2、iperf |
| 核心收获 | 理解 Mininet 的工作原理,能够独立搭建虚拟网络并进行测试 |
| 遇到的问题 | Ubuntu 24.04 的 pep8 包改名、python 软链接缺失、OVS 未安装 |
| 待深入 | 明天安装 Ryu 控制器,实现第一个 SDN 实验(L2 Switch) |
参考资料
- Mininet Book — Mininet 官方中文教程
- Mininet GitHub — 源码与安装指南
- SDNLAB Mininet 教程 — SDN 实验入门
- Mininet 官方文档 — API 参考与示例
本文是「SDN 入门学习计划」Day 4 的学习笔记。
学习路线:Day 1 SDN 是什么 → Day 2 SDN 架构深入 → Day 3 OpenFlow 协议详解 → Day 4 Mininet 实验 → Day 5 网络入侵检测入门 → …