RYU3.16 GUI安装与Topology模块分析
2015-04-21 by muzi最近很多SDN研究人员问起如何安装RYU的GUI,网上也有一些教程。但是由于RYU版本问题,导致安装没有成功。本片博文将介绍RYU3.16版本下如何安装GUI,以及对RYU拓扑模块进行简单分析。
安装GUI
Linton的博客已经有详细介绍,我在这里将一些可能出现问题的地方再提醒一次。
第一步:依赖安装及修改代码
建议查看Linton的博客,比较简单,不赘述。
第二步:运行相关组建
-
运行RYU相关APP
ryu-manager --verbose --observe-links app/simple_switch_13.py ryu.topology.switches ryu.app.rest_topology ryu.app.ofctl_rest
运行截图如下:
-
运行controller.py文件
进入到gui目录,运行controller.py文件。
python controller.py
-
访问页面
打开浏览器,访问http://127.0.0.1:8000页面。查看到connected to 127.0.0.1:8080信息则为连接成功。
Note that: 如果没有显示connected to 127.0.0.1:8000等信息,而显示Disconnected, 那么需要重新启动RYU的相关APP,再刷新网页,重新链接。运行controller.py的终端不需要动。
若连接成功,启动mininet与控制器连接,则可发现网页逐步在显示网络拓扑,点击交换机图标可查看详细信息。
众多网友表示3.19+版本无法成功使用GUI,可参考:RYU3.20 GUI DOC 进行安装使用。
TOPOLOGY源码分析
有一个小伙伴已经在我之前发布了详细的代码介绍,我不再赘述,大家有兴趣的可以前往查看:Ryu拓扑发现原理分析
在topology目录中,switches.py最重要。在switches.py文件中,核心的类是class Switches。
在Switches类中,我们仅仅需要关注几个重要的函数即可将大体的拓扑发现逻辑理清。
-
__init__()
初始化函数初始化了一些重要的内容,如dps,ports,links等。并将lldp_loop和link_loop这两个函数加入线程(协程)。
-
packet_in_handler()
此函数用于解析LLDP报文,从而提取出对应的信息,得到link信息。
-
lldp_loop()
调用了send_lldp_packet()函数,循环发送LLDP报文的函数。
-
link_loop()
实时检测link事件,及时发现拓扑变化,生产对应的event,并通过send_event_to_observers提供和观察者。
使用Switches模块
在实验过程中,实验人员往往需要得到网络拓扑的信息,不仅仅是dpid,link,port这些零散的元素,而是一张图。这张图往往由邻接矩阵或关联矩阵。所以一下的内容将介绍如何将dpid,link等信息转化成邻接矩阵和关联矩阵,以便后续的算路算法使用。
在你开发的模块中,将Switches作为context加载,并在__init__函数中将其赋值给某一变量。
_CONTEXTS = {'switches': switches.Switches }
def __init__(self, *args, **kwargs):
super(yourapp, self).__init__(*args, **kwargs)
self.switches = kwargs['switches']
self.threads = []
self.threads.extend([hub.spawn(self._link_monitor),])
self.threads用于保存线程。将_link_monitor函数作为执行体,加入线程执行。函数简单定义如下:
def _link_monitor(self):
while(self.is_active):
if self.links != self.dp_tracker.links.keys():
self.dps = self.dp_tracker.dps
self.links = self.dp_tracker.links.keys()
hub.sleep(1)
从_link_monitor函数中可以获取到dps,links等数据。这些数据需要整理存储,以便使用,get_graph函数就是用于将数据存储在图中的函数:定义函数get_graph,函数返回值是两张图,其中图graph_cap记录两个交换机之间的链路能力,图graph_port则记录的是从src到dst的源端口,目的端口信息保存在图的对称节点上。详细代码如下:
def get_graph(self):
graph_cap = {}
graph_port = {}
for dpid in self.dps.keys():
for link in self.links:
if link.src.dpid == dpid:
graph_cap.setdefault(dpid, {})
graph_port.setdefault(dpid, {})
neighbor = link.dst.dpid
capacity = link.dst.curr_speed
graph_cap[dpid][neighbor] = capacity
graph_port[dpid][neighbor] = link.src.port_no
return graph_cap, graph_port
至此,网络拓扑图生成完毕。在运行最短路径或者其他的路径计算算法时,可使用get_graph返回的数据。
总结
一直以来做实验并不需要可视化拓扑界面,直到最近发现许多研究者频繁提问,才想起来尝试这个实验。但事实上,我觉得Switches模块的使用是一个更重要的内容。很多情况下,我们需要的是原始的数据,而不是展示出来的界面。本文内容比较简单,希望能帮助到一些SDN学习者。