2019 SDN大作业

2019 SDN大作业:负载均衡

1.小组成员与分工

学号 姓名 分工 贡献比例
031702526 周华 ppt制作 20%
031702514 严喜 写博客 20%
031702533 吕瑞峰 写代码 30%
031702542 林小棠 视频录制、ppt演示、写代码 30%

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
posted @ 2020-01-06 18:38  焰心无泪  阅读(246)  评论(1编辑  收藏  举报