Mininet-基本使用

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 连接:

1
vncviewer :5900

默认用户是 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

之后用:

1
ssh -X xxx@xxx

连接后, 就能够启用服务器上的 GUI 应用了, 比如:

1
sudo -E wireshark &

基本使用

Mininet 的命令行工具为 mn.

每次用 sudo mn 启动网络时, 它仅仅创建一个临时的网络拓扑, 在退出后会清理. 也可以手动清理所有遗留组件:

1
sudo mn -c

默认情况下, mn 的 topology 是一个 switch 连接两个 hosts. 测试两个主机间的宽带可用:

1
sudo mn --test iperf

创建一个 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

包括主机和交换机:

1
mininet> nodes

显示网络中的所有 net

1
mininet> net

查看 nodes 的所有信息

1
mininet> dump

ping 测试

比如让一台 host 去 ping 另一台:

1
mininet> h2 ping h3

测试所有节点间的联通:

1
mininet> pingall

运行 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."

# Add hosts and switches
leftHost = self.addHost( 'h1' )
rightHost = self.addHost( 'h2' )
leftSwitch = self.addSwitch( 's3' )
rightSwitch = self.addSwitch( 's4' )

# Add links
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 等:

1
sudo mn -v debug

产生 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 代码, 如:

1
mininet> py dir(s1)

比如关闭交换机 s1 和主机 h1 之间的 link:

1
mininet> link s1 h1 down

若开启则:

1
mininet> link s1 h1 up

为 nodes 打开终端调试

这里要注意两点:

  1. 用 ssh 连接时启用 -X (Enable X11 forwarding) 选项
  2. 调用 mn 时启用 -x 选项
1
2
ssh -X mininet@xxxxx
sudo mn -x

之后:

1
mininet> h1 xterm

可能会遇到报错:

此时在启用时加上 -E 选项 (听说是环境变量没读到, 参考 stackoverflow).

1
2
3
sudo -E mn -x
...
mininet> h1 xterm


Mininet-基本使用
http://example.com/2024/10/23/Mininet-基本使用/
作者
Jie
发布于
2024年10月23日
许可协议