2019SDN大作业——负载均衡(咕咕咕队)

2019SDN大作业——负载均衡

一、小组成员及贡献比例

学号 姓名 贡献比例 分工
031702423
031702430 陈友昆
031702432
031702429
031702444

二、实验场景

1.负载均衡方法的原理以及目的:

​ 负载均衡(Load Balance)的意思是指将负载(工作任务)进行平衡、分摊到多个操作单元上进行运行,例如FTP服务器、Web服务器、企业核心应用服务器和其它主要任务服务器等,从而协同完成工作任务。如果存在根多的数据包同时通过网络连向一台服务器, 也就是网络的速度比网络所连接的设备速度快的情况下,负载均衡技术是解决这个问题的有效方式。负载均衡是一种扩展现有网络设备和服务器的带宽、增加吞吐量、加强网络数据处理能力、提高网络的灵活性和可用性的技术。

2.负载均衡场景:

拓扑结构如下所示:

在此拓扑结构中,h1是客户端,服务器端h2 ,h3,h4上各自有不同的服务。我们要实现一个负载均衡的北向程序,当h2,h1,h3向h1传输数据时,北向应用根据链路的使用状况动态的调整路由规则。例如:s1-s4链路带宽充足情况下应默认s4-s1的传输路径,当剩余带宽不足的情况下应动态调整路由,使链路负载达到平衡。

搭建拓扑的代码MyTopo.py如下所示:

from mininet.topo import Topo

class MyTopo( Topo ):

    def __init__( self ):

        # initilaize topology   
        Topo.__init__( self )

        # add hosts and switches
        host1 = self.addHost( 'h1' )
        host2 = self.addHost( 'h2' )
        host3 = self.addHost( 'h3' )
        host4 = self.addHost( 'h4' )
        switch1 = self.addSwitch( 's1' )
        switch2 = self.addSwitch( 's2' )
        switch3 = self.addSwitch( 's3' )
        switch4 = self.addSwitch( 's4' )
        

        # add links
        self.addLink(host1,switch1)
        self.addLink(switch1,switch2)
        self.addLink(switch1,switch3)
        self.addLink(switch1,switch4)

        self.addLink(switch2,switch4)
        self.addLink(switch3,switch4)

        self.addLink(switch4,host2)
        self.addLink(switch4,host3)
        self.addLink(switch4,host4)

topos = { 'mytopo': ( lambda: MyTopo() ) }

三、实验具体操作

实现负载均衡的核心代码controller1.py如下所示:

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))
        h1h4body1 ='{"flow": [{"id": "1","match": {"ethernet-match":'   
                '{"ethernet-type": {"type": "2048"}},'
    '"ipv4-source":"10.0.0.1/32","ipv4-destination": "10.0.0.4/32"},'
                '"instructions": {"instruction": [{"order": "0",'
                '"apply-actions": {"action": [{"output-action": {'
                '"output-node-connector": "4"},"order": "0"}]}}]},'
                '"priority": "101","cookie": "1","table_id": "0"}]}'    
        mh1h4body1 ='{"flow": [{"id": "1","match": {"ethernet-match":'  
               '{"ethernet-type": {"type": "2048"}},'
    '"ipv4-source":"10.0.0.1/32","ipv4-destination": "10.0.0.4/32"},'
                '"instructions": {"instruction": [{"order": "0",'
                '"apply-actions": {"action": [{"output-action": {'
                '"output-node-connector": "4"},"order": "0"}]}}]},'
                '"priority": "102","cookie": "1","table_id": "0"}]}'
    h1h4body2 ='{"flow": [{"id": "5","match": {"ethernet-match":'   
               '{"ethernet-type": {"type": "2048"}},'
    '"ipv4-source":"10.0.0.1/32","ipv4-destination": "10.0.0.4/32"},'
                '"instructions": {"instruction": [{"order": "0",'
                '"apply-actions": {"action": [{"output-action": {'
                '"output-node-connector": "2"},"order": "0"}]}}]},'
                '"priority": "100","cookie": "5","table_id": "0"}]}'
    mh1h4body2 ='{"flow": [{"id": "5","match": {"ethernet-match":'  
               '{"ethernet-type": {"type": "2048"}},'
    '"ipv4-source":"10.0.0.1/32","ipv4-destination": "10.0.0.4/32"},'
                '"instructions": {"instruction": [{"order": "0",'
                '"apply-actions": {"action": [{"output-action": {'
                '"output-node-connector": "2"},"order": "0"}]}}]},'
                '"priority": "102","cookie": "5","table_id": "0"}]}'
    h1h4body3 ='{"flow": [{"id": "6","match": {"ethernet-match":'           
               '{"ethernet-type": {"type": "2048"}},'
    '"ipv4-source":"10.0.0.1/32","ipv4-destination": "10.0.0.4/32"},'
                '"instructions": {"instruction": [{"order": "0",'
                '"apply-actions": {"action": [{"output-action": {'
                '"output-node-connector": "3"},"order": "0"}]}}]},'
                '"priority": "99","cookie": "6","table_id": "0"}]}'
    mh1h4body3 ='{"flow": [{"id": "6","match": {"ethernet-match":'  
               '{"ethernet-type": {"type": "2048"}},'
    '"ipv4-source":"10.0.0.1/32","ipv4-destination": "10.0.0.4/32"},'
                '"instructions": {"instruction": [{"order": "0",'
                '"apply-actions": {"action": [{"output-action": {'
                '"output-node-connector": "3"},"order": "0"}]}}]},'
                '"priority": "102","cookie": "6","table_id": "0"}]}'        
        h1h2body1 ='{"flow": [{"id": "1","match": {"ethernet-match":'   
                '{"ethernet-type": {"type": "2048"}},'
    '"ipv4-source":"10.0.0.1/32","ipv4-destination": "10.0.0.2/32"},'
                '"instructions": {"instruction": [{"order": "0",'
                '"apply-actions": {"action": [{"output-action": {'
                '"output-node-connector": "4"},"order": "0"}]}}]},'
                '"priority": "101","cookie": "1","table_id": "0"}]}'    
        mh1h2body1 ='{"flow": [{"id": "1","match": {"ethernet-match":'  
               '{"ethernet-type": {"type": "2048"}},'
    '"ipv4-source":"10.0.0.1/32","ipv4-destination": "10.0.0.2/32"},'
                '"instructions": {"instruction": [{"order": "0",'
                '"apply-actions": {"action": [{"output-action": {'
                '"output-node-connector": "4"},"order": "0"}]}}]},'
                '"priority": "102","cookie": "1","table_id": "0"}]}'
    h1h2body2 ='{"flow": [{"id": "5","match": {"ethernet-match":'   
               '{"ethernet-type": {"type": "2048"}},'
    '"ipv4-source":"10.0.0.1/32","ipv4-destination": "10.0.0.2/32"},'
                '"instructions": {"instruction": [{"order": "0",'
                '"apply-actions": {"action": [{"output-action": {'
                '"output-node-connector": "2"},"order": "0"}]}}]},'
                '"priority": "100","cookie": "5","table_id": "0"}]}'
    mh1h2body2 ='{"flow": [{"id": "5","match": {"ethernet-match":'  
               '{"ethernet-type": {"type": "2048"}},'
    '"ipv4-source":"10.0.0.1/32","ipv4-destination": "10.0.0.2/32"},'
                '"instructions": {"instruction": [{"order": "0",'
                '"apply-actions": {"action": [{"output-action": {'
                '"output-node-connector": "2"},"order": "0"}]}}]},'
                '"priority": "102","cookie": "5","table_id": "0"}]}'
    h1h2body3 ='{"flow": [{"id": "6","match": {"ethernet-match":'           
               '{"ethernet-type": {"type": "2048"}},'
    '"ipv4-source":"10.0.0.1/32","ipv4-destination": "10.0.0.2/32"},'
                '"instructions": {"instruction": [{"order": "0",'
                '"apply-actions": {"action": [{"output-action": {'
                '"output-node-connector": "3"},"order": "0"}]}}]},'
                '"priority": "99","cookie": "6","table_id": "0"}]}'
    mh1h2body3 ='{"flow": [{"id": "6","match": {"ethernet-match":'  
               '{"ethernet-type": {"type": "2048"}},'
    '"ipv4-source":"10.0.0.1/32","ipv4-destination": "10.0.0.2/32"},'
                '"instructions": {"instruction": [{"order": "0",'
                '"apply-actions": {"action": [{"output-action": {'
                '"output-node-connector": "3"},"order": "0"}]}}]},'
                '"priority": "102","cookie": "6","table_id": "0"}]}'
        h1h3body1 ='{"flow": [{"id": "1","match": {"ethernet-match":'   
                '{"ethernet-type": {"type": "2048"}},'
    '"ipv4-source":"10.0.0.1/32","ipv4-destination": "10.0.0.3/32"},'
                '"instructions": {"instruction": [{"order": "0",'
                '"apply-actions": {"action": [{"output-action": {'
                '"output-node-connector": "4"},"order": "0"}]}}]},'
                '"priority": "101","cookie": "1","table_id": "0"}]}'    
        mh1h3body1 ='{"flow": [{"id": "1","match": {"ethernet-match":'  
               '{"ethernet-type": {"type": "2048"}},'
    '"ipv4-source":"10.0.0.1/32","ipv4-destination": "10.0.0.3/32"},'
                '"instructions": {"instruction": [{"order": "0",'
                '"apply-actions": {"action": [{"output-action": {'
                '"output-node-connector": "4"},"order": "0"}]}}]},'
                '"priority": "102","cookie": "1","table_id": "0"}]}'
    h1h3body2 ='{"flow": [{"id": "5","match": {"ethernet-match":'   
               '{"ethernet-type": {"type": "2048"}},'
    '"ipv4-source":"10.0.0.1/32","ipv4-destination": "10.0.0.3/32"},'
                '"instructions": {"instruction": [{"order": "0",'
                '"apply-actions": {"action": [{"output-action": {'
                '"output-node-connector": "2"},"order": "0"}]}}]},'
                '"priority": "100","cookie": "5","table_id": "0"}]}'
    mh1h3body2 ='{"flow": [{"id": "5","match": {"ethernet-match":'  
               '{"ethernet-type": {"type": "2048"}},'
    '"ipv4-source":"10.0.0.1/32","ipv4-destination": "10.0.0.3/32"},'
                '"instructions": {"instruction": [{"order": "0",'
                '"apply-actions": {"action": [{"output-action": {'
                '"output-node-connector": "2"},"order": "0"}]}}]},'
                '"priority": "102","cookie": "5","table_id": "0"}]}'
    h1h3body3 ='{"flow": [{"id": "6","match": {"ethernet-match":'           
               '{"ethernet-type": {"type": "2048"}},'
    '"ipv4-source":"10.0.0.1/32","ipv4-destination": "10.0.0.3/32"},'
                '"instructions": {"instruction": [{"order": "0",'
                '"apply-actions": {"action": [{"output-action": {'
                '"output-node-connector": "3"},"order": "0"}]}}]},'
                '"priority": "99","cookie": "6","table_id": "0"}]}'
    mh1h3body3 ='{"flow": [{"id": "6","match": {"ethernet-match":'  
               '{"ethernet-type": {"type": "2048"}},'
    '"ipv4-source":"10.0.0.1/32","ipv4-destination": "10.0.0.3/32"},'
                '"instructions": {"instruction": [{"order": "0",'
                '"apply-actions": {"action": [{"output-action": {'
                '"output-node-connector": "3"},"order": "0"}]}}]},'
                '"priority": "102","cookie": "6","table_id": "0"}]}'
        headers = {'Content-type': 'application/json'}
    num=0

        response, content = http.request(uri='http://127.0.0.1:8181/restconf/config/opendaylight-inventory:nodes/node/openflow:1/flow-node-inventory:table/0/flow/0', body=s1_2To1, method='PUT',headers=headers)   
        response, content = http.request(uri='http://127.0.0.1:8181/restconf/config/opendaylight-inventory:nodes/node/openflow:1/flow-node-inventory:table/0/flow/1', body=s1_3To1, method='PUT',headers=headers)
        response, content = http.request(uri='http://127.0.0.1:8181/restconf/config/opendaylight-inventory:nodes/node/openflow:3/flow-node-inventory:table/0/flow/0', body=s3_1, method='PUT',headers=headers)
        response, content = http.request(uri='http://127.0.0.1:8181/restconf/config/opendaylight-inventory:nodes/node/openflow:3/flow-node-inventory:table/0/flow/0', body=s3_2, 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/0', body=h2_to_s2_1, method='PUT',headers=headers)
        while num < 4 :
            s1_uri = 'http://127.0.0.1:8181/restconf/operational/opendaylight-inventory:nodes/node/openflow:1/node-connector/openflow:1:2'
            s2_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=s1_uri, method='GET')
            content = json.loads(content.decode())
            statistics = content['node-connector'][0]['opendaylight-port-statistics:flow-capable-node-connector-statistics']
            s1_bytes1 = statistics['bytes']['transmitted']
      
            time.sleep(0.5)
            response, content = http.request(uri=s1_uri, method='GET')
            content = json.loads(content.decode())
            statistics = content['node-connector'][0]['opendaylight-port-statistics:flow-capable-node-connector-statistics']
            s1_bytes2 = statistics['bytes']['transmitted']

            s1_speed=float(s1_bytes2-s1_bytes1)/0.5
            
            if s1_speed !=0 :
                print ('s1端口2速度:')
                print (s1_speed)
            
                if s1_speed < 1000 :
                    print(' s1端口2空闲,h1数据包改为往s1端口2通过')
                    response, content = http.request(uri='http://127.0.0.1:8181/restconf/config/opendaylight-inventory:nodes/node/openflow:1/flow-node-inventory:table/0/flow/2', body=h1_to_s1_2, method='PUT',headers=headers)
                    response, content = http.request(uri='http://127.0.0.1:8181/restconf/config/opendaylight-inventory:nodes/node/openflow:1/flow-node-inventory:table/0/flow/3', body=mh1_to_s1_2, method='PUT',headers=headers)
              
                else :
                    print(' s1端口2满载,h1数据包改为往s1端口3通过')
                    response, content = http.request(uri='http://127.0.0.1:8181/restconf/config/opendaylight-inventory:nodes/node/openflow:1/flow-node-inventory:table/0/flow/2', body=h1_to_s1_3, method='PUT',headers=headers)
                    response, content = http.request(uri='http://127.0.0.1:8181/restconf/config/opendaylight-inventory:nodes/node/openflow:1/flow-node-inventory:table/0/flow/3', body=mh1_to_s1_3, method='PUT',headers=headers)

    
            response, content = http.request(uri=s2_uri, method='GET')
            content = json.loads(content.decode())
            statistics = content['node-connector'][0]['opendaylight-port-statistics:flow-capable-node-connector-statistics']
            s2_bytes1 = statistics['bytes']['transmitted']
      
            time.sleep(0.5)
            response, content = http.request(uri=s2_uri, method='GET')
            content = json.loads(content.decode())
            statistics = content['node-connector'][0]['opendaylight-port-statistics:flow-capable-node-connector-statistics']
            s2_bytes2 = statistics['bytes']['transmitted']
            
            s2_speed=float(s2_bytes2-s2_bytes1)/0.5
        
            if s2_speed !=0 :
                print ('s2端口1速度:')
                print (s2_speed)
          
                if s2_speed < 1000 :
                    print(' s2端口1空闲,h3数据包改为往s2端口1通过')
                    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=h3_to_s2_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=mh3_to_s2_2, method='PUT',headers=headers)
               
                else :
                    print(' s2端口1满载,h3数据包改为往s2端口2通过')
                    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=mh3_to_s2_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=h3_to_s2_2, method='PUT',headers=headers)
odl = OdlUtil('127.0.0.1', '8181')
odl.install_flow()

具体操作步骤:

(1)在创建拓扑前,先打开opendaylight控制器:

(2)执行MyTopo.py脚本,创建拓扑,并查看拓扑结构:

(3)测试主机之间的连通性:

(4)使用iperf命令测试带宽,查看拥塞状况:

(5)调用负载均衡程序controller1.py,并执行:

(6)调用负载均衡后的结果如下所示:

(7)查看交换机s1、s2、s3、s4的流表项:

四、实验感悟:

陈友昆:通过本学期SDN的课程学习,让我收获了很多新的知识,尤其是通过SDN的实践课,我更是掌握了不少新的技术,比如miniet的使用、如何编写py脚本创建具体的拓扑结构、opendaylight控制器、ryu控制器的基本原理及使用方法、p4语言的使用等等,从每次安装时的焦头烂额,到完成实验任务的喜悦与自豪,让我有了很大的成就感。在学习SDN这门课之前,我对网络编程真的是一窍不通,但通过这学期的学习,虽然我对SDN的掌握还不够完全和深入,但是我对它有了一个总体的清晰的框架,为我日后的学习提供了很大的帮助。

五、视频及代码链接:

猜你喜欢

转载自www.cnblogs.com/chenyoukun/p/12156176.html