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

你可能感兴趣的:(2019 SDN大作业)