初衷
写这篇文章的目的是:之前完全照搬 SDN 指导书上的各个命令。即便事后有整理理论知识,但也不免严重遗忘、变得模糊。
有点像以为使用记忆的方法就能掌握编程那样荒谬。
先从实验入手往往容易造成的这样巨大的问题:得知其然而不知其所以然。
这算是挑战性课程给我们的一个比较大的教训。虽然过去自己在捣腾东西的时候,已经体会到了局部。但是这次挑战性课程的容量以及时间对我们的压力,让我对它有了更深的理解。
尤其是实验室还一直催着我们向前,但是在不断前行的时候,我发现自己的地基没有打好,所以这才匆匆的回头重新打地基。
比如很多环境的配置可能配一遍之后,以后再也记不得当初是怎么配的了。
当然这只是举个例子。因为环境往往只需要搭建,最多只需要把当时配置的过程记录下来,而不需要记入到脑中。也因此这里也不再赘述环境的配置。(其实有些配环境的部分也是有方法技巧的)
但是我们做的这个实验,除了最开始的搭建部分后面的很多地方,其实在未来还会反复的使用。实验指导书给出了一个例子。但是不过脑子地、照抄的话,是没办法实现举一反三,实现真正的学习的。
实验环境
Linux
当初并没有重视 VMWare Tools,也觉得它不太可靠(某人因为它死了进程)。所以就用云把需要的文件全部同步过去、用 Git 把需要的代码也拷过去。这样就能完全在 Linux 环境下进行正常的开发了……
然而 VCode 经常在 Linux 里面崩溃,且在虚拟机中运行也不流畅。
所以最后决定把文件移除到需要的时候再直接复制进去……
也能避免虚拟机的存储空间不足的情况。
// 不过至少这个过程也让我更熟练地使用Linux,包括各种异常的处理。
OVS
这一个实验不需要过分深究,用此明白Mininet的原理即可。所以这里就不再复现。
一般来说,通过 Mininet 启动的交换机都是 OVS.
也就是说,在安装 Mininet 的时候,默认已经把 OVS 这个开源程序安装上了,在用 Mininet 启动网络的时候,OVS 进程也跟着启动了,所以,在本机的命令行下是可以直接调ovs-ofctl和ovs-vsctl等OVS的专属命令的。
不过 OVS 还可以查看流表什么的…… (之后再回来看看……)
minint
由于拓扑的脚本还是放在原来的仓库下面:(自己要熟练地找自己存放的目录)
1 | cd ~/SDN-dev/Code |
ODL
1 | sudo SDN-dev/karaf-0.8.2/bin/karaf |
各个部分的关系
OVS 用于模拟真实的交换机;
Mininet 用于搭建虚拟网络拓扑,模拟 SDN 转发设备层。
OpenDayliht 则作为控制器层,对 Mininet 搭建的网络进行拓扑展示和控制管理
最开始通过 mininet 建立网络拓扑,并连接到控制器的 ip 地址上。
然后打开 ODL,以及http://localhost:8181/index.html,(默认用戶名与密码均为admin)即可可视化拓扑。
但是此时显示的一般只是交换机,只有在 mininet 终端中 pingall 之后才会 reload 之后才会显示主机,没有 ping 通的就不会显示。
实验
mininet
Mininet仅为SDN网络的基础设施,明白其简单命令及其具有的功能即可,在需要的时候可以查阅文档等。
常见命令
进入 mininet 的终端之后可以用对应的命令进行拓扑的创建和修改。
进入/退出 命令:
1 | user@ubuntu:~$ sudo mn --controller=remote,ip=192.168.15.23,port=6653 // 产生默认拓扑,指向远端控制器 |
mn如果没有参数(默认创建的拓扑):

常用命令参数
--controller:可以用于添加控制器。
一般连接远程控制器可以使用--controller=remote,ip=xxx.xx.xx.xx,port=6653。(注意没有空格…)
--custom:后面跟自己编写的拓扑Python脚本的路径。
--topo:可以选择linear、minimal、single、tree等多种模式,模式后面可以加参数,如命令mn --topo single,2就相当于mn.(mn 默认的方式)
--mac:添加此选项可以让主机的MAC地址有规律,即00:00:00:00:00:01依次排列
--link:在Python脚本中有对链路贷款、时延约束的情况下可以添加–link=tc
-c:清理创建的网络拓扑,在结束Mininet后使用命令mn -c清理是一个好习惯
--topo=linear,5 相当于五个交换机串联,每个交换机都挂一个主机。
1 | sudo mn --topo=linear,5 --controller=remote,ip=127.0.0.1,port=6653 |
--topo=tree,5 像二叉树,主机是叶子结点。
1 | sudo mn --topo=tree,3 --controller=remote,ip=127.0.0.1,port=6653 |
…
(其他的以后再玩玩)
下面在 minin 的命令行的图片是以下面的拓扑为例的。
全局命令:
1 | mininet> help //显示可以使用的命令 |
对单个网络设备的配置:
1 | mininet> s1 ifconfig //查看交换机 s1 上的网络信息 |
更多命令参数可以参考如下网址自主学习:
https://blog.csdn.net/u014015972/article/details/51133292
用 Python 建立拓扑
以一个基本框架展开。
myTopo.py
1 | #encoding=UTF-8 |
此脚本生成的是一个字典,字典的键mytopo就是在运行 mininet 的时候输入的参数--topo,这里命名可以自定义。
故在执行这个脚本的时候,mn 后需要的额外添加的参数是:--custom=myTopo.py --topo=mytopo
--custom=后面接脚本的目录(+名称),--topo加入的就是这个字典的键。
字典的值是上面我们动手创建的 mininet.topo 里的 Topo 类的实例的名称,在创建实例对象的时候自定义。
// 这个lambda没有任何参数迫使我查了一下它的原型:
1 lambda [arg1[, arg2, ... argN]]: expression
实例的创建,只需要继承 Topo 类,然后在 __init__()方法中写写内容即可。
内容一般包括:初始化,网络设备的创建,网络设备的互联。
- 初始化用的是类方法
Topo.__init__(self) - 主机和交换机的创建的方法是
self.addHost('hostname'),self.addSwitch('switchname') - 连接都使用
self.addLink(equipment1, equipment2),还有一些可选的参数。
下面是自己写的一个 Python 脚本:
1 | from mininet.topo import Topo |
在 ODL 里显示如下:

官方网站:Python mininet
http://mininet.org/api/annotated.html
ODL
Mininet 连接 OpenDaylight控制器 的方式就是之前提到的 controller=remote,ip...的方式,
自建复杂的拓扑时,交换机中是没有流表的,使用控制器之后利用其一些组件(Lswitch)其会自动学习与下发流表。
安装的 feature (e.g. Nodes, Topology)有些会体现在网⻚ http://localhost:/index.html (ODL所在的系统)上,其实这像服务器。
通过 Wireshark 抓包获取 ODL 和 mininet 的通信信息
一图解 OF
一些条目的具体信息详见笔记……
这个实验其实很局限,只是通过对 Control 和 OpenFlow 交换机通信抓包,这其实只是 OF 的一个非常小的部分……
实验步骤
实验步骤也很简单……
先打开 Wireshark 监听Lookback接口(因为我的 ODL 和 mininet 都是在虚拟机里的)
然后建立 ODL 和 mininet 的连接,即可抓到包。

但是流量包里面还是有很多东西可以探索:
可窥见最开始它们是通过 TCP 协议三次握手连接的。
前三个 OFPT_HELLO 都是相似的,Transaction ID 是递增的。
使用的是 OF 1.4

接下来是三个 OFPT_HELLO 应该是其中一个发给另一个的,使用的是 OF 1.3

之后进行的是 REQUEST 和 REPLY, 应该在进行各种确认。
同时也发现它们开始统一使用 OF 1.3(这应该是 OFPT_HELLO 的成果)
之后还有各种包(OFPT_PACKET_IN,OFPT_PACKET_OUT),可惜 OF 这部分理论学习不够,什么时候具体看 OF 协议的时候再回来看看。
