Mininet 官网
Mininet Github 地址
介绍
Mininet 可以在 Linux 内核上高效模拟真实的网络环境, 并可以用简单的命令构建复杂的网络拓扑, 常用于 SDN 的研究.
下载
虚拟机
最简单的方式是使用官方打包好的虚拟机镜像, 不仅含 mininet, 还有 OpenFlow 及其工具集. 这里搭配 QUMU/KVM 做示例:
会得到一个压缩包, 将其解压后:
1 2 3 4
| . ├── mininet-2.3.0-210211-ubuntu-20.04.1-legacy-server-amd64.ovf ├── mininet-2.3.0-210211-ubuntu-20.04.1-legacy-server-amd64-ovf.zip └── mininet-vm-x86_64.vmdk
|
对于 QEMU/KVM, 可以运行:
1
| qemu-system-x86_64 -m 2048 mininet-vm-x86_64.vmdk -net nic,model=virtio -net user,net=192.168.101.0/24,hostfwd=tcp::8022-:22
|
来启动 VNC 连接:
之后可用 vncviewer
连接:
默认用户是 mininet
, 密码 mininet
.
若用 VirtualBox, 则直接把 .ovf
文件导入即可:
1
| VBoxManage import mininet-2.3.0-210211-ubuntu-20.04.1-legacy-server-amd64.ovf
|
之后打开 VirtualBox 就能看到了.
配置 X server
在 Ubuntu 上安装如:
1 2
| sudo apt-get update sudo apt install xauth x11-apps
|
xauth
用于管理 X11 认证
x11-apps
提供测试应用如 xeyes
, xclock
之后用:
连接后, 就能够启用服务器上的 GUI 应用了, 比如:
基本使用
Mininet 的命令行工具为 mn
.
每次用 sudo mn
启动网络时, 它仅仅创建一个临时的网络拓扑, 在退出后会清理. 也可以手动清理所有遗留组件:
默认情况下, mn
的 topology 是一个 switch 连接两个 hosts. 测试两个主机间的宽带可用:
创建一个 network
1
| sudo mn --switch ovs --controller ref --topo tree,depth=2,fanout=8 --test pingall
|
--switch ovs
, 指定交换机类型为 ovs (Open vSwitch, 一个高性能, 可编程的虚拟交换机)
--controller ref
, 指定 ref
(一个默认的控制器实现) 作为 SDN 控制器
--topo tree,depth=2,fanout=8
, 指定网络的拓扑结构, 这里指定为树形, 深度为 2, 每个非叶节点连接 8 个子节点 (一共 64 hosts 以及 9 各 switches)
--test pingall
, 会让所有虚拟主机互相发送 ping 命令, 测试相互之间是否连通 (不加这个能直接进入交互)
与 network 交互
显示网络中的所有 nodes
包括主机和交换机:
显示网络中的所有 net
查看 nodes 的所有信息
ping 测试
比如让一台 host 去 ping 另一台:
测试所有节点间的联通:
运行 Linux 命令
比如开启一个 http server, 让另一台 host 访问:
1 2 3
| mininet> h2 ifconfig -a mininet> h2 python -m SimpleHTTPServer 80 >& /tmp/http.log & mininet> h3 wget -O - h2
|
定制 network
可以用 python 编写特定的 network:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32
| """Custom topology example: topo-2sw-2host.py
Two directly connected switches plus a host for each switch:
host --- switch --- switch --- host
Adding the 'topos' dict with a key/value pair to generate our newly defined topology enables one to pass in '--topo=mytopo' from the command line. """
from mininet.topo import Topo
class MyTopo( Topo ): "Simple topology example."
def build( self ): "Create custom topo."
leftHost = self.addHost( 'h1' ) rightHost = self.addHost( 'h2' ) leftSwitch = self.addSwitch( 's3' ) rightSwitch = self.addSwitch( 's4' )
self.addLink( leftHost, leftSwitch ) self.addLink( leftSwitch, rightSwitch ) self.addLink( rightSwitch, rightHost )
topos = { 'mytopo': ( lambda: MyTopo() ) }
|
然后:
1
| sudo mn --custom topo-2sw-2host.py --topo mytopo --test pingall
|
指定 network topology
用 --topo
加上参数即可:
1
| sudo mn --test pingall --topo linear,4
|
设置链路信息
用 --link
加上参数:
1
| sudo mn --link tc,bw=10,delay=10ms
|
tc
指使用 Traffic Control 机制来模拟链路特性
bw=10
设置 bandwidth 为 10Mbps
delay=10ms
在链路中引入 10ms 的延迟
此时:
1 2 3
| mininet> iperf ... mininet> h1 ping -c10 h2
|
会发现 iperf
的输出为 10Mbps 左右, RTT (Round Trip Time) 大概为 40ms. (因为有两条 link, 每个 link 10ms, 来回是 40ms)
改变输出详细程度
用 -v
(verbose) 指定, 默认 verbosity level 是 info
, 可以指定为 debug
, warning
, output
等:
产生 readable 的 mac 地址
默认情况下, mininet 启用的 hosts 是随机分配的 MAC 地址, 比如:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
| sudo mn ... mininet> h1 ifconfig h1-eth0: flags=4163<UP,BROADCAST,RUNNING,MULTICAST> mtu 1500 inet 10.0.0.1 netmask 255.0.0.0 broadcast 10.255.255.255 ether f6:e6:11:d5:91:b2 txqueuelen 1000 (Ethernet) RX packets 0 bytes 0 (0.0 B) RX errors 0 dropped 0 overruns 0 frame 0 TX packets 0 bytes 0 (0.0 B) TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0
lo: flags=73<UP,LOOPBACK,RUNNING> mtu 65536 inet 127.0.0.1 netmask 255.0.0.0 loop txqueuelen 1000 (Local Loopback) RX packets 0 bytes 0 (0.0 B) RX errors 0 dropped 0 overruns 0 frame 0 TX packets 0 bytes 0 (0.0 B) TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0
|
如果启用 --mac
地址, 则能产生比较好读的 MAC 地址, 需要先确保 openvswitch-switch
是启用的:
1
| sudo service openvswitch-switch start
|
之后:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
| sudo mn --mac ... mininet> h1 ifconfig h1-eth0: flags=4163<UP,BROADCAST,RUNNING,MULTICAST> mtu 1500 inet 10.0.0.1 netmask 255.0.0.0 broadcast 10.255.255.255 ether 00:00:00:00:00:01 txqueuelen 1000 (Ethernet) RX packets 0 bytes 0 (0.0 B) RX errors 0 dropped 0 overruns 0 frame 0 TX packets 0 bytes 0 (0.0 B) TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0
lo: flags=73<UP,LOOPBACK,RUNNING> mtu 65536 inet 127.0.0.1 netmask 255.0.0.0 loop txqueuelen 1000 (Local Loopback) RX packets 0 bytes 0 (0.0 B) RX errors 0 dropped 0 overruns 0 frame 0 TX packets 0 bytes 0 (0.0 B) TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0
|
使用 Python Interpreter
在 Mininet CLI 交互中, 可以用 py
来运行 python 代码, 如:
开启或关闭 link
比如关闭交换机 s1
和主机 h1
之间的 link:
1
| mininet> link s1 h1 down
|
若开启则:
为 nodes 打开终端调试
这里要注意两点:
- 用 ssh 连接时启用
-X
(Enable X11 forwarding) 选项
- 调用
mn
时启用 -x
选项
1 2
| ssh -X mininet@xxxxx sudo mn -x
|
之后:
可能会遇到报错:
此时在启用时加上 -E
选项 (听说是环境变量没读到, 参考 stackoverflow).
1 2 3
| sudo -E mn -x ... mininet> h1 xterm
|