为期一周的odl训练营终于结束了,本来有很多话想要写下来的,等真正开始写的时候却又不知道写些啥了。大概先介绍一下这次训练营吧,这次活动主要是由思科负责,思科,BAT,运营商等牵头举办的,请来了odl的开发团队来给我们讲解odl。这次活动真心是太nice了,几个odl开发团队的老外特别nice,各种问题都耐心解答,思科的support team也非常nice,全程陪同,每天根据我们的反馈不断进行调整,连最后一天马拉松比赛我们通宵的时候他们也有人陪同,还有中饭,下午茶,晚饭,真心是贴心到家了。满分无商量。
这次培训主要讲解如何在odl中开发一个plugin,其实这些东西在社区都可以获取到,不过有人带着你step-by-step上手更快点。北向提供RESTful api,南向协议为netconf,大部分都和我们以前开发相同,不同之处在于南向协议不是openflow而是netconf,这个是思科主导的一套网管协议,南向连接运行netconf的思科的路由器,而不是openFlow的网络设备。其实从狭义来说这个并不是sdn,主要因为我们之前认同的sdn南向都是跑的是openFlow的协议,所以这个应该算做是广义的sdn。南向协议不是openFlow意味着无法根据流的粒度去控制流表,而只能通过netconf提供的静态流表,ACL等管理接口进行配置。这点在刚开始的时候有些不适应。
这次比赛我们组获得了第二名,这个出乎意料之外,感觉有挺多组做的东西都挺好的,或许我们做的更对odl开发团队人员的胃口,可惜的是峰哥有事没能参加最后的颁奖,缺少一个合照。
以下来点干货,讲讲我们组这次做的东西。华丽分割线开启。
本来想着走训练过程讲解的过程开发一个odl的plugin,首先根据md-sal开发yang,然后是java代码,然后南向对接netconf,北向提供RESTful api,北向app调用这些api进行下一步开发。后来为了省事,只是调用odl团队给的示例项目中的RESTful api去实现,因为接口足够我们的需求了。
由于连接netconf路由器无法走流表,所以只能由静态流表控制转发,并且静态流表只能由控制器触发更改,本身无法主动进行修改,所以我们的想法是做一个快速重路由,这个想法是由队友清华的克尧提供的,果然清华的都是大神,实践证明了我们的idea还是很赞的。总的来说,我们一共做了三块东西:1.快速重路由;2.路由计算不是用Dijkstra而是SPFA;3.做了个ui拓扑展现界面。
1. 快速冲路由(FRR)
上面三个图展示了快速重路由的过程,首先是最优的路径,注意最优路径可以不是最短路,但是权重需要自己定义,在此我们为了简化,只是采取距离作为权重。当R6上的一个interface down掉以后,控制器感知后主动下发第二条路径。
以下是流程图:
主要包括六个步骤:
- 一开始控制器根据cdp(cdp是思科的链路状态协议,相当于openFlow里的lldp)构建全局拓扑。
- 全局最优路径计算,包括一开始的最短路,以及断掉某条边的的最短路,通过python的字典dict格式保存。key为边号,value为最短路径的list,刚开始的最短路的key为0,这个边号不会被使用。
- 下发一开始的最短路。下发的RESTful api可以自己写plugin,然后提供,也可以直接调用思科项目中的api,我们就直接调用后者了,减少工作量。
- 轮循调用cdp获取是否发生拓扑改变。此步骤我们发现无论是1秒钟10次和3秒钟1次对最后的结果影响都差不多,基本上都要丢掉6-8个包,所以瓶颈不在于此,而应该是从app到odl到router中间封装的三层,如果不是调用api,而是写一个plugin,收敛应该会更快。而且由于实验环境的不稳定,频繁调用容易出问题,所以最后采用1秒钟调用2次的策略。
- 一旦获取到某条链路断掉了(此处我们采用命令行在路由上down掉某个interface模拟),控制器立刻下发对应的字典中的最短路径,path=dict[断掉edge号码]。
- 下发path。
2. SPFA
计算最短路径是不是采用dijkstra而是用spfa,具体就是保存一个最小堆,每次弹出堆顶元素,堆的计算方式是走过的路径最短值,这样不用像dijkstra两层循环O(|V|^2)的时间复杂度,而是O(E) 。在图不是特别稠密(两个点之间出现多条路径)情况下,spfa是占优的。具体算法过程可以查看相应文档。
3. UI界面
此部分做了一个拓扑展示,主要就是一开始的拓扑,以及发生变化后的新的拓扑。此部分花了一个小时调用python的networkx和matplotlib两个库搞定。采用一个线程控制一个UI界面。
为了简化层面,我们的FRR只能适用于断掉一条链路的情况,另外由于实验环境的不稳定,起6个路由内存跑满了,所以我们只是采用3个路由去模拟。
以下是触发的拓扑,首先是全图,然后0-2链路断掉,自动发现,弹出第二个界面。
Done。华丽分割线。
其实想法比较简单,实现也比较简答,不过由于第一次写python代码,花了不少时间,加上连续代码太长时间,大脑真心转不动,代码约写越挫,到后来我都看不懂了>_<。妈蛋,不过好歹也算写过python代码了,项目的总体代码量在500行左右,如果好好精简,去掉注释之类的,估计200行能搞定了。稍微有点遗憾的是因为没涉及plugin编写,所以这一块流程还是没熟悉到,只能以后再练练了。
此次训练营和比赛,对我来说,硬伤是英语,全程都是英语,真心不能荒废啊。过程中和小伙伴交流学到不少,果然需要多多交流才能茁壮成长,哈哈。
关于比赛开发再多说一句,一开始还是不要把需求想太复杂,先开发出第一个版本,再进行版本迭代会好很多,否则一开始就定很复杂的需求,下手写代码会比较棘手。还有一定要有面向对象的思想,降低耦合性,无论多简单的需求,别啥逻辑都写一块去了,因为往往迭代版本会加入新的,如果耦合性太高,改代码就改崩溃了。
最后,说几句衷心的感谢,感谢队友清华的张克尧,中国电信研究院的王峰,以及思科的Tim徐提供的大力的帮助和支持。感谢百度,思科,odl团队提供的此次培训机会,也衷心希望以后odl越办越好。
说明:
装载请注明出处:http://vinllen.com/odlxun-lian-ying-ji-hei-ke-ma-la-song-bi-sai-zong-jie/