期末作业验收

SDN负载均衡实验

一.实验代码


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))
        #s2流表
        #h2工作时s2端口1流量空闲时下发的流表
        h2_to_s2_1 ='{"flow": [{"id": "0","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": "1"},"order": "0"}]}}]},'\
                    '"priority": "101","cookie": "1","table_id": "0"}]}'
        #h3工作时s2端口1流量空闲时下发的流表
        h3_to_s2_1 ='{"flow": [{"id": "1","match": {"ethernet-match":'\
                    '{"ethernet-type": {"type": "2048"}},'\
                    '"ipv4-source":"10.0.0.3/32","ipv4-destination": "10.0.0.1/32"},'\
                    '"instructions": {"instruction": [{"order": "0",'\
                    '"apply-actions": {"action": [{"output-action": {'\
                    '"output-node-connector": "1"},"order": "0"}]}}]},'\
                    '"priority": "101","cookie": "1","table_id": "0"}]}'
        mh3_to_s2_1 ='{"flow": [{"id": "1","match": {"ethernet-match":'\
                    '{"ethernet-type": {"type": "2048"}},'\
                    '"ipv4-source":"10.0.0.3/32","ipv4-destination": "10.0.0.1/32"},'\
                    '"instructions": {"instruction": [{"order": "0",'\
                    '"apply-actions": {"action": [{"output-action": {'\
                    '"output-node-connector": "1"},"order": "0"}]}}]},'\
                    '"priority": "100","cookie": "1","table_id": "0"}]}'
        #h3工作时s2端口1流量满载时下发的流表   
        h3_to_s2_2 ='{"flow": [{"id": "2","match": {"ethernet-match":'\
                    '{"ethernet-type": {"type": "2048"}},'\
                    '"ipv4-source":"10.0.0.3/32","ipv4-destination": "10.0.0.1/32"},'\
                    '"instructions": {"instruction": [{"order": "0",'\
                    '"apply-actions": {"action": [{"output-action": {'\
                    '"output-node-connector": "2"},"order": "0"}]}}]},'\
                    '"priority": "101","cookie": "1","table_id": "0"}]}'
        mh3_to_s2_2 ='{"flow": [{"id": "2","match": {"ethernet-match":'\
                    '{"ethernet-type": {"type": "2048"}},'\
                    '"ipv4-source":"10.0.0.3/32","ipv4-destination": "10.0.0.1/32"},'\
                    '"instructions": {"instruction": [{"order": "0",'\
                    '"apply-actions": {"action": [{"output-action": {'\
                    '"output-node-connector": "2"},"order": "0"}]}}]},'\
                    '"priority": "100","cookie": "1","table_id": "0"}]}'
        #s3流表
        s3_1='{"flow": [{"id": "0","match": {"ethernet-match":'\
            '{"ethernet-type": {"type": "2048"}},'\
            '"ipv4-source":"10.0.0.3/32","ipv4-destination": "10.0.0.1/32"},'\
            '"instructions": {"instruction": [{"order": "0",'\
            '"apply-actions": {"action": [{"output-action": {'\
            '"output-node-connector": "1"},"order": "0"}]}}]},'\
            '"priority": "101","cookie": "1","table_id": "0"}]}'
        s3_2='{"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": "2"},"order": "0"}]}}]},'\
            '"priority": "101","cookie": "2","table_id": "0"}]}'
        #s1流表
        s1_2To1='{"flow": [{"id": "0","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": "1"},"order": "0"}]}}]},'\
                '"priority": "101","cookie": "1","table_id": "0"}]}'
        s1_3To1='{"flow": [{"id": "1","match": {"ethernet-match":'\
                '{"ethernet-type": {"type": "2048"}},'\
                '"ipv4-source":"10.0.0.3/32","ipv4-destination": "10.0.0.1/32"},'\
                '"instructions": {"instruction": [{"order": "0",'\
                '"apply-actions": {"action": [{"output-action": {'\
                '"output-node-connector": "1"},"order": "0"}]}}]},'\
                '"priority": "101","cookie": "1","table_id": "0"}]}'
        #h1工作时s1端口2流量空闲时下发的流表
        h1_to_s1_2 ='{"flow": [{"id": "2","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": "101","cookie": "2","table_id": "0"}]}'
        mh1_to_s1_2 ='{"flow": [{"id": "3","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": "3","table_id": "0"}]}'
        #h1工作时s1端口2流量满载时下发的流表   
        h1_to_s1_3 ='{"flow": [{"id": "2","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": "101","cookie": "2","table_id": "0"}]}'
        mh1_to_s1_3 ='{"flow": [{"id": "3","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": "100","cookie": "3","table_id": "0"}]}'
        headers = {'Content-type': 'application/json'}
        num=0
        #下发流表,地址由ODL上获得
        #下发s1与s3的流表
        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)

        #s2调用h2到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/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'
            #获取s1端口2的流量
            response, content = http.request(uri=s1_uri, method='GET')
            content = json.loads(content)
            statistics = content['node-connector'][0]['opendaylight-port-statistics:flow-capable-node-connector-statistics']
            s1_bytes1 = statistics['bytes']['transmitted']
            #0.5秒后再次获取
            time.sleep(0.5)
            response, content = http.request(uri=s1_uri, method='GET')
            content = json.loads(content)
            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
                #在检测到s1端口2流量空闲时发的流表
                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)
                #在检测到s1端口2流量满载时发的流表
                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)

            #获取s2端口1的流量
            response, content = http.request(uri=s2_uri, method='GET')
            content = json.loads(content)
            statistics = content['node-connector'][0]['opendaylight-port-statistics:flow-capable-node-connector-statistics']
            s2_bytes1 = statistics['bytes']['transmitted']
            #0.5秒后再次获取
            time.sleep(0.5)
            response, content = http.request(uri=s2_uri, method='GET')
            content = json.loads(content)
            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
                #在检测到s2端口1流量空闲时发的流表
                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)
                #在检测到s2端口1流量满载时发的流表
                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()


二.实验场景
1226437-20180126151901490-831609494.png
服务器h2 h3上各自有不同的服务,h1是客户端。实现一个负载均衡的北向程序,当h2和h3向h1传输数据时,北向应用根据链路的使用状况动态的调整路由规则。
主要思路:过一定的时间后,下发新的流表,使得流量流向另一个交换机,从而实现负载均衡。类似于轮询法。

三.视频演示
1.打开ODL
1226437-20180126164100475-1976886475.jpg
2.查看创建的拓扑
1226437-20180126164144131-674019897.jpg
3.查看拥塞情况
1226437-20180126164212053-1167438677.jpg
4.调用负载均衡
1226437-20180126164238537-549899117.jpg
5.调用后的结果
1226437-20180126164259100-316092970.jpg

三.小组分工
负责查找相关资料分析各路由和服务器间的链接关系,编写和修改python代码,在实现过程中与组员一起修改下发流表的代码。

四.课程总结
1.了解了SDN的定义和发展。SDN与传统网络的区别和SDN的特点以及为什么需要SDN。软件定义网络(Software Defined Network, SDN ),是Emulex网络一种新型网络创新架构,是网络虚拟化的一种实现方式,其核心技术OpenFlow通过将网络设备控制面与数据面分离开来,从而实现了网络流量的灵活控制,使网络作为管道变得更加智能。
2.在mininet上创建简单拓扑并验证其正确性。运用Floodligth查看创建的拓扑及其链接结构。Mininet是由一些虚拟的终端节点(end-hosts)、交换机、路由器连接而成的一个网络仿真器,它采用轻量级的虚拟化技术使得系统可以和真实网络相媲美。
3.对Openflow流表的使用。多级流表将数据包的处理逻辑划分为多个子逻辑,并由多张流表分别来匹配和处理,从而使得数据包的处理变成了一条流水线。单流表是无法满足复杂的业务逻辑要求的。
4.利用字符界面下发流表,通过测试联通性,来验证openflow的hardtime机制。运用OVS命令查看流表。
5.学习了ODL控制器的使用及在ODL上下发流表。
6.用Wireshark抓包验证实验的正确性。
7.用Postman通过ODL的北向接口下发流表。
8.对负载均衡的定义及实现有了掌握,了解了负载均衡的几个基本算法,对较简单的负载均衡场景可以实现。

转载于:https://www.cnblogs.com/one-piece-zero/p/8351098.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值