作业地址
https://edu.cnblogs.com/campus/fzu/SoftwareDefinedNetworking2017/homework/1585
项目地址
https://github.com/laizhiping/final-exam-sdn
队伍
没有队名可以取了吗
实验分工
赖志平:控制流表下发,负载均衡策略实现,实验的统筹与指导实现
陈家进:拓扑搭建、视频剪辑
陈甘霖:流表设计和修正和视频录制
陈敏辉:测试与纰漏修改,ReadMe说明
实验场景
![](https://i-blog.csdnimg.cn/blog_migrate/4eb60f5dac81788ef81a4e3763245cb9.png)
服务器h2 ,h3,h4上各自有不同的服务,h1是客户端。实现一个负载均衡的北向程序,当h2,h1,h3向h1传输数据时,北向应用根据链路的使用状况动态的调整路由规则。例如:s1-s4链路带宽充足情况下应默认s4-s1的传输路径,当剩余带宽不足的情况下应动态调整路由,使链路负载达到平衡。
实验步骤
实现思路:
当拓扑中的s4的1端口的流量超过给定的阈值时,启用2,3端口,将流量进行分流,实现负载均衡,具体的实现方法是通过下发不同优先级的流表,改变数据流和数据包的走向,减轻1端口的负载,从而实现网络带宽的扩展。
- 首先利用python脚本建出拓扑结构,代码 戳这里
- 对s4设计不同优先级的流表,供均衡时调用,部分流表代码如下
#s4的1口流量满载时h2发的数据包,2,3端口出的流表项优先级高
h2_to_s4_2 ='{"flow": [{"id": "42","match": {"ethernet-match":'\
'{"ethernet-type": {"type": "2048"}},'\
'"ipv4-source":"10.0.0.2/32","ipv4-destination": "10.0.0.1/32"},'\
'"instructions": {"instruction": [{"order": "0",'\
'"apply-actions": {"action": [{"output-action": {'\
'"output-node-connector": "2"},"order": "0"}]}}]},'\
'"priority": "112","cookie": "1","table_id": "0"}]}'
h2_to_s4_3 ='{"flow": [{"id": "43","match": {"ethernet-match":'\
'{"ethernet-type": {"type": "2048"}},'\
'"ipv4-source":"10.0.0.2/32","ipv4-destination": "10.0.0.1/32"},'\
'"instructions": {"instruction": [{"order": "0",'\
'"apply-actions": {"action": [{"output-action": {'\
'"output-node-connector": "3"},"order": "0"}]}}]},'\
'"priority": "110","cookie": "1","table_id": "0"}]}'
3.设计一个循环,不断检测s4的端口1流量大小,一旦超过一定值就启用负载均衡策略,下发更高优先级的流表,实现分流,拓展带宽,实现代码如下:
while(True):
#获取s4端口1的流量
uri = 'http://127.0.0.1:8181/restconf/operational/opendaylight-inventory:nodes/node/openflow:4/node-connector/openflow:4:1'
response, content = http.request(uri=uri, method='GET')
content = json.loads(content)
statistics = content['node-connector'][0]['opendaylight-port-statistics:flow-capable-node-connector-statistics']
bytes1 = statistics['bytes']['transmitted']
#1秒后再次获取
time.sleep(1)
response, content = http.request(uri=uri, method='GET')
content = json.loads(content)
statistics = content['node-connector'][0]['opendaylight-port-statistics:flow-capable-node-connector-statistics']
bytes2 = statistics['bytes']['transmitted']
#在检测到s4的1口流量空闲时发的流表
speed=float(bytes2-bytes1)/1
if speed !=0 :#获取有效的速度
if speed < 1000 :
print 'speed =',speed,', s2端口1空闲,数据包往1口通过'
#下发默认的流表
response, content = http.request(uri='http://127.0.0.1:8181/restconf/config/opendaylight-inventory:nodes/node/openflow:4/flow-node-inventory:table/0/flow/41', body=h2_to_s4_1, method='PUT',headers=headers)
response, content = http.request(uri='http://127.0.0.1:8181/restconf/config/opendaylight-inventory:nodes/node/openflow:4/flow-node-inventory:table/0/flow/51', body=h3_to_s4_1, method='PUT',headers=headers)
response, content = http.request(uri='http://127.0.0.1:8181/restconf/config/opendaylight-inventory:nodes/node/openflow:4/flow-node-inventory:table/0/flow/61', body=h4_to_s4_1, method='PUT',headers=headers)
#在检测到s2的1口流量满载时下发新的流表
else :
print 'speed =',speed,', s2端口1满载,数据包改为往2口和3口通过'
#h2数据包的流表
response, content = http.request(uri='http://127.0.0.1:8181/restconf/config/opendaylight-inventory:nodes/node/openflow:4/flow-node-inventory:table/0/flow/41', body=lh2_to_s4_1, method='PUT',headers=headers)
response, content = http.request(uri='http://127.0.0.1:8181/restconf/config/opendaylight-inventory:nodes/node/openflow:4/flow-node-inventory:table/0/flow/42', body=h2_to_s4_2, method='PUT',headers=headers)
response, content = http.request(uri='http://127.0.0.1:8181/restconf/config/opendaylight-inventory:nodes/node/openflow:4/flow-node-inventory:table/0/flow/43', body=h2_to_s4_3, method='PUT',headers=headers)
#h3数据包的流表
response, content = http.request(uri='http://127.0.0.1:8181/restconf/config/opendaylight-inventory:nodes/node/openflow:4/flow-node-inventory:table/0/flow/52', body=h3_to_s4_2, method='PUT',headers=headers)
response, content = http.request(uri='http://127.0.0.1:8181/restconf/config/opendaylight-inventory:nodes/node/openflow:4/flow-node-inventory:table/0/flow/53', body=h3_to_s4_3, method='PUT',headers=headers)
#h4数据包的流表
response, content = http.request(uri='http://127.0.0.1:8181/restconf/config/opendaylight-inventory:nodes/node/openflow:4/flow-node-inventory:table/0/flow/62', body=h4_to_s4_2, method='PUT',headers=headers)
response, content = http.request(uri='http://127.0.0.1:8181/restconf/config/opendaylight-inventory:nodes/node/openflow:4/flow-node-inventory:table/0/flow/63', body=h4_to_s4_3, method='PUT',headers=headers)
实验总结及课程心得
本次实验,我主要负责是流表下发代码部分的编写以及整个实验的统筹,实验中遇到很多问题,比如部分主机ping不通,带宽异常还有各种分不清是电脑问题还是程序等,对于我们这些初步涉及SDN的人来说,难度还是较大,好在还是在老师和同学的帮助下初步解决了这些问题,并且实现了一个比较简陋的sdn负载均衡场景的模拟实现。这个实验课下来,也对SDN有了一个比较初步地了解,也学会了一些SDN的工具及控制方式等。此外,理论课也介绍了SDN的一些知识,让我们更加理解了SDN。不过让我觉得比较不足的是SDN这门课还略显年轻,各种工具的bug也是相对比较多,学习的途径相对较少,网上的资料也比较少,而且网络本身过程性比较强,出问题也比较难发现问题所在,所以自主学习一个小问题总是能够困扰很久。所以学习这门课的时候更多地就要依赖老师和助教,出现问题经常半夜问老师和助教,老师和助教也是也是很热心的解答,真的是十分感谢,虽然现在不是网络方向,但是学习这门课也是开拓了视野,日后会从事这一领域也不一定。总而言之,这门课也算画上了一个句号,还是要和老师和助教及帮助过同学说声谢谢。