2019 SDN大作业:负载均衡
1.小组成员
031702526 周华 031702514 严喜 031702533 吕瑞峰 031702542 林小棠
2.拓扑搭建
拓扑图
拓扑脚本:
from mininet.topo import Topo class MyTopo( Topo ): "Simple topology example." def __init__( self ): "Create custom topo." # Initialize topology Topo.__init__( self ) # add hosts and switches host1 = self.addHost( 'h1' ) host2 = self.addHost( 'h2' ) host3 = self.addHost( 'h3' ) switch1 = self.addSwitch( 's1' ) switch2 = self.addSwitch( 's2' ) switch3 = self.addSwitch( 's3' ) # add links self.addLink(host1,switch1) self.addLink(switch1,switch2) self.addLink(switch1,switch3) self.addLink(switch2,host2) self.addLink(switch2,host3) self.addLink(switch2,switch3) topos = { 'mytopo': ( lambda: MyTopo() ) }
负载均衡代码:
# -*- coding: utf-8 -*- import httplib2 import time import json class OdlUtil: url = '' def __init__(self, host, port): self.url = 'http://' + host + ':' + str(port) def install_flow(self, container_name='default',username="admin", password="admin"): http = httplib2.Http() http.add_credentials(username, password) headers = {'Accept': 'application/json'} flow_name = 'flow_' + str(int(time.time()*1000)) #s3流表 s3_h3_to_h1='{"flow": [{"id": "0","match": {"ethernet-match": '\ '{"ethernet-type": {"type": "0x0800"}},'\ '"ipv4-source": "10.0.0.3/32",'\ '"ipv4-destination": "10.0.0.1/32"},'\ '"instructions": {"instruction": [{"order": "0",'\ '"apply-actions": {"action": [{"order": "0","output-action": {'\ '"output-node-connector": "1"}}]}}]},'\ '"priority": "100","table_id": "0"}]}' #s1流表 s1_h2_to_h1='{"flow": [{"id": "0","match": {"ethernet-match": '\ '{"ethernet-type": {"type": "0x0800"}},'\ '"ipv4-source": "10.0.0.2/32",'\ '"ipv4-destination": "10.0.0.1/32"},'\ '"instructions": {"instruction": [{"order": "0",'\ '"apply-actions": {"action": [{"order": "0","output-action": {'\ '"output-node-connector": "1"}}]}}]},'\ '"priority": "100","table_id": "0"}]}' s1_h3_to_h1='{"flow": [{"id": "0","match": {"ethernet-match": '\ '{"ethernet-type": {"type": "0x0800"}},'\ '"ipv4-source": "10.0.0.3/32",'\ '"ipv4-destination": "10.0.0.1/32"},'\ '"instructions": {"instruction": [{"order": "0",'\ '"apply-actions": {"action": [{"order": "0","output-action": {'\ '"output-node-connector": "1"}}]}}]},'\ '"priority": "100","table_id": "0"}]}' #s2流表 #h2工作下发的流表 s2_h2_to_h1='{"flow": [{"id": "0","match": {"ethernet-match": '\ '{"ethernet-type": {"type": "0x0800"}},'\ '"ipv4-source": "10.0.0.2/32",'\ '"ipv4-destination": "10.0.0.1/32"},'\ '"instructions": {"instruction": [{"order": "0",'\ '"apply-actions": {"action": [{"order": "0","output-action": {'\ '"output-node-connector": "1"}}]}}]},'\ '"priority": "100","table_id": "0"}]}' #h3工作时s2端口1空闲下发的流表 s2_h3_to_h1_1='{"flow": [{"id": "1","match": {"ethernet-match": '\ '{"ethernet-type": {"type": "0x0800"}},'\ '"ipv4-source": "10.0.0.3/32",'\ '"ipv4-destination": "10.0.0.1/32"},'\ '"instructions": {"instruction": [{"order": "0",'\ '"apply-actions": {"action": [{"order": "0","output-action": {'\ '"output-node-connector": "1"}}]}}]},'\ '"priority": "101","table_id": "0"}]}' s2_h3_to_h1_4='{"flow": [{"id": "2","match": {"ethernet-match": '\ '{"ethernet-type": {"type": "0x0800"}},'\ '"ipv4-source": "10.0.0.3/32",'\ '"ipv4-destination": "10.0.0.1/32"},'\ '"instructions": {"instruction": [{"order": "0",'\ '"apply-actions": {"action": [{"order": "0","output-action": {'\ '"output-node-connector": "4"}}]}}]},'\ '"priority": "100","table_id": "0"}]}' #h3工作时s2端口1满载下发的流表 s2_mh3_to_h1_1='{"flow": [{"id": "1","match": {"ethernet-match": '\ '{"ethernet-type": {"type": "0x0800"}},'\ '"ipv4-source": "10.0.0.3/32",'\ '"ipv4-destination": "10.0.0.1/32"},'\ '"instructions": {"instruction": [{"order": "0",'\ '"apply-actions": {"action": [{"order": "0","output-action": {'\ '"output-node-connector": "1"}}]}}]},'\ '"priority": "100","table_id": "0"}]}' s2_mh3_to_h1_4='{"flow": [{"id": "2","match": {"ethernet-match": '\ '{"ethernet-type": {"type": "0x0800"}},'\ '"ipv4-source": "10.0.0.3/32",'\ '"ipv4-destination": "10.0.0.1/32"},'\ '"instructions": {"instruction": [{"order": "0",'\ '"apply-actions": {"action": [{"order": "0","output-action": {'\ '"output-node-connector": "4"}}]}}]},'\ '"priority": "101","table_id": "0"}]}' headers = {'Content-type': 'application/json'} #下发s1的流表 response, content = http.request(uri='http://127.0.0.1:8181/restconf/config/opendaylight-inventory:nodes/node/opflow:1/flow-node-inventory:table/0/flow/0', body=s1_h2_to_h1, method='PUT',headers=headers) response, content = http.request(uri='http://127.0.0.1:8181/restconf/config/opendaylight-inventory:nodes/node/opflow:1/flow-node-inventory:table/0/flow/1', body=s1_h3_to_h1, method='PUT',headers=headers) #下发s3的流表 response, content = http.request(uri='http://127.0.0.1:8181/restconf/config/opendaylight-inventory:nodes/node/opflow:3/flow-node-inventory:table/0/flow/0', body=s3_h3_to_h1, method='PUT',headers=headers) #下发s2的流表(h2到h1) response, content = http.request(uri='http://127.0.0.1:8181/restconf/config/opendaylight-inventory:nodes/node/opflow:2/flow-node-inventory:table/0/flow/0', body=s2_h2_to_h1, method='PUT',headers=headers) while True: #获取s2端口1的流量 uri = 'http://127.0.0.1:8181/restconf/operational/opendaylight-inventory:nodes/node/openflow:2/node-connector/openflow:2: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_port1 = statistics['bytes']['transmitted'] #获取s2端口4的流量 uri = 'http://127.0.0.1:8181/restconf/operational/opendaylight-inventory:nodes/node/openflow:2/node-connector/openflow:2:4' 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_port4 = statistics['bytes']['transmitted'] #2秒后再次获取 time.sleep(2) uri = 'http://127.0.0.1:8181/restconf/operational/opendaylight-inventory:nodes/node/openflow:2/node-connector/openflow:2: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_port1 = statistics['bytes']['transmitted'] uri = 'http://127.0.0.1:8181/restconf/operational/opendaylight-inventory:nodes/node/openflow:2/node-connector/openflow:2:4' 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_port4 = statistics['bytes']['transmitted'] #输出s2端口1和端口4的速度 speed1=float(bytes2_port1-bytes1_port1)/2 speed2=float(bytes2_port4-bytes1_port4)/2 #在检测到s2的1口流量空闲时发的流表 if speed1 !=0 :#获取有效的速度 print('s2端口1速度:%.3lf byte/s' % speed1) print('s2端口4速度:%.3lf byte/s' % speed2) if speed1 < 2000 : print('当前s2端口1处于空闲状态,h3数据包通往s1') response, content = http.request(uri='http://127.0.0.1:8181/restconf/config/opendaylight-inventory:nodes/node/openflow:2/flow-node-inventory:table/0/flow/1', body=s2_h3_to_h1_1, method='PUT',headers=headers) response, content = http.request(uri='http://127.0.0.1:8181/restconf/config/opendaylight-inventory:nodes/node/openflow:2/flow-node-inventory:table/0/flow/2', body=s2_h3_to_h1_4, method='PUT',headers=headers) #在检测到s2的1口流量满载时发的流表 else : print('当前s2端口1处于满载状态,h3数据包通往s3') response, content = http.request(uri='http://127.0.0.1:8181/restconf/config/opendaylight-inventory:nodes/node/openflow:2/flow-node-inventory:table/0/flow/1', body=s2_mh3_to_h1_1, method='PUT',headers=headers) response, content = http.request(uri='http://127.0.0.1:8181/restconf/config/opendaylight-inventory:nodes/node/openflow:2/flow-node-inventory:table/0/flow/2', body=s2_mh3_to_h1_1, method='PUT',headers=headers) odl = OdlUtil('127.0.0.1', '8181') odl.install_flow()
3.场景
服务器h2 h3上各自有不同的服务,h1是客户端。实现一个负载均衡的北向程序,当h2和h3向h1传输数据时,北向应用根据链路的使用状况动态的调整路由规则。 例如:当h2向h1使用s1-s2链路达到满负荷状态下,h3向h1的传输路径应该动态的调整为s3所在路径,而当h2停止向h1传输数据时,h3应调整回s1-s2路径。
4.作业演示视频
https://pan.baidu.com/s/1KSnN1I4LLhqwd8U7Vc6deA
来源:https://www.cnblogs.com/ruifeng1/p/12155863.html