Python 交换机负载平衡动态主机拓扑

Python 交换机负载平衡动态主机拓扑,python,load-balancing,mininet,openflow,Python,Load Balancing,Mininet,Openflow,下面是在mininet中设置网络的代码,其中每个主机将运行一个客户端程序,即通过hx.cmd'python pyexample.py',每个服务器将运行一个客户端将连接到的服务器程序 首先,我已将所有主机连接到交换机,其中一些是服务器,一些是主机。当主机/客户端/服务器的数量不固定时,如何让此交换机充当负载平衡器 第二,在多个客户端向单个服务器发送请求的情况下,如何让客户端和服务器相互连接并将结果返回给单个客户端 #!/usr/bin/python from mininet.topo impo

下面是在mininet中设置网络的代码,其中每个主机将运行一个客户端程序,即通过hx.cmd'python pyexample.py',每个服务器将运行一个客户端将连接到的服务器程序

首先,我已将所有主机连接到交换机,其中一些是服务器,一些是主机。当主机/客户端/服务器的数量不固定时,如何让此交换机充当负载平衡器

第二,在多个客户端向单个服务器发送请求的情况下,如何让客户端和服务器相互连接并将结果返回给单个客户端

#!/usr/bin/python

from mininet.topo import Topo
from mininet.net import Mininet
from mininet.util import dumpNodeConnections
from mininet.log import setLogLevel

import math

# num_hosts = number of servers + clients
# network with n hosts connected to one switch
class NetworkTopology(Topo, num_hosts, num_servers):
    clients = []
    servers = []

    def build(self, n=num_hosts):
        # Switch controlled to act as load balancer
        # TODO: Write controller
        switch = self.addSwitch('s1')

        # Generate 0..n-1 hosts - n = num_hosts
        for h in range(n):
            s = 0
            while s < num_servers:
                # Add server to the topology
                server = self.addHost('server%s' % (s+1))
                self.addLink(server, switch)
                servers.append(server)
            else:
                # Add client to the topology
                client = self.addHost('client%s' % ((h-s)+1))
                self.addLink(host, switch)
                clients.append(client)


def runTest(num_hosts, num_servers, num_levels, num_base_reports):
    topo = NetworkTopology(num_hosts, num_servers)


# Main function
if __name__ == '__main__':
    setLogLevel('info')

    num_base_reports = 100
    num_levels = math.log(num_base_reports, 10) # log to base 10
    num_hosts = round(4**(math.log(num_base_reports-1, 10)))
    num_servers = round(2**(math.log(num_base_reports-1, 10)))

    runTest(num_hosts, num_servers num_levels, num_base_reports)
客户端线程:

客户:


正如你所知,在SDN中发生了一些新的事情;对数据平面和控制平面分离!因此,您必须使用控制器在网络中构建负载平衡功能。SDN控制器和交换机使用OpenFlow或其他南向API相互连接。网络功能,如防火墙、本机、负载平衡和其他功能将在控制器软件上实现

控制器有很多选择,比如ONOS、OpenDaylight、泛光灯、RYU等等。如果用python编写代码很容易,那么您最好选择,因为前面提到的其他控制器都是基于java的

您可以在RYU controller的顶部找到实现简单循环负载平衡应用程序的示例代码:

您应该在第131行和该块中添加代码:

您必须将代码添加到第131行之后和以下elif块中:

elif ip.proto == 0x06: # Resolve TCP
例如,类似这样的事情:

elif ip.proto == 0x06: # Resolve TCP

                if pkt_tcp.src_port == 3000: # Ignore packets from server when creating rule
                    return

                ip_src = ip.src

                # if ip of client has been learned (flow installed), no need to process
                # helps with burst of traffic that creates duplicate flows
                if ip_src in self.ip_to_mac:
                    return

                out_port = self.net.servers[self.rr_counter].port
                mac_dest = self.net.servers[self.rr_counter].mac


                ip.dst = self.net.lb_ip

                # Forward Received TCP Packet to the selected Server
                p = packet.Packet()
                p.add_protocol(ethernet.ethernet(dst=mac_dest, src=src, ethertype=ether_types.ETH_TYPE_IP))
                p.add_protocol(ip)
                p.add_protocol(pkt_tcp)

                self.send_packet(p, msg, datapath, out_port)

                # Add Flow Entry
                match = datapath.ofproto_parser.OFPMatch(in_port=msg.in_port, dl_type=0x0800,
                                                         nw_proto=0x06, nw_src=ip_src, nw_dst=self.net.lb_ip)
                actions = [parser.OFPActionSetDlDst(mac_dest), parser.OFPActionOutput(out_port)]
                self.add_flow(match, actions)

                # Insert reverse flow
                match = datapath.ofproto_parser.OFPMatch(in_port=out_port, dl_type=0x0800,
                                                         nw_proto=0x06, nw_src=self.net.lb_ip, nw_dst=ip_src)
                actions = [parser.OFPActionSetDlSrc(self.net.lb_mac), parser.OFPActionOutput(msg.in_port)]
                self.add_flow(match, actions)

                # Update ARP table
                self.ip_to_mac.update({ip_src: src})

                # Update RR counter
                self.rr_counter = (self.rr_counter + 1) % self.net.servers_num
别忘了在课堂上添加lb服务器、Mac服务器和IP服务器

在这方面可以帮助您的其他资源:


你可以根据你的观点来匹配协议和端口吗?我将在各自的主机上执行一个Java客户端和服务器程序,以便使用套接字连接相互通信。请将代码发送给我好吗?我需要这些代码来传达我对您使用的套接字的想法。请参阅更新的OP-我添加了客户端和服务器代码,以及每个客户端连接到服务器时调用的客户端线程。它是一个基本的套接字连接您使用的库默认使用TCP协议,根据您的代码,它使用的是端口3000。因此,您的匹配将是:|从客户端到服务器->eth_类型:0x800 IPv4协议:TCP dst_端口:3000 |从服务器到客户端->eth_类型:0x800 IPv4协议:TCP src_端口:3000 |您还可以添加其他字段来完成匹配,例如,src_ip,dst_ip等等。我将把您在答案中提供的示例循环链接中的这些匹配放在哪里?另外,在我的Java应用程序中,我想我会连接到负载平衡器?如果是的话,我会怎么做?最后,如何将示例负载平衡器连接到我的mininet topo?你能为其他人更新答案吗?
public class Client
{
    protected static final int PORT = 3000;

    public Client() {
    }

    public static void main(String[] args) {
        try {
            Socket sock = new Socket("127.0.0.1", PORT);

            // Output Stream (sending to server)
            OutputStream os = sock.getOutputStream();
            PrintWriter pw = new PrintWriter(os, true);

            // Input Stream (receiving from server)
            InputStream is = sock.getInputStream();
            BufferedReader br = new BufferedReader(new InputStreamReader(is));

            String request, response;
            while(true) {
                request = "MyRequest!";
                pw.println(request);
                if((response = br.readLine()) != null) {
                    System.out.println(response);
                    break;
                }
            }

        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}
elif ip.proto == 0x06: # Resolve TCP
elif ip.proto == 0x06: # Resolve TCP

                if pkt_tcp.src_port == 3000: # Ignore packets from server when creating rule
                    return

                ip_src = ip.src

                # if ip of client has been learned (flow installed), no need to process
                # helps with burst of traffic that creates duplicate flows
                if ip_src in self.ip_to_mac:
                    return

                out_port = self.net.servers[self.rr_counter].port
                mac_dest = self.net.servers[self.rr_counter].mac


                ip.dst = self.net.lb_ip

                # Forward Received TCP Packet to the selected Server
                p = packet.Packet()
                p.add_protocol(ethernet.ethernet(dst=mac_dest, src=src, ethertype=ether_types.ETH_TYPE_IP))
                p.add_protocol(ip)
                p.add_protocol(pkt_tcp)

                self.send_packet(p, msg, datapath, out_port)

                # Add Flow Entry
                match = datapath.ofproto_parser.OFPMatch(in_port=msg.in_port, dl_type=0x0800,
                                                         nw_proto=0x06, nw_src=ip_src, nw_dst=self.net.lb_ip)
                actions = [parser.OFPActionSetDlDst(mac_dest), parser.OFPActionOutput(out_port)]
                self.add_flow(match, actions)

                # Insert reverse flow
                match = datapath.ofproto_parser.OFPMatch(in_port=out_port, dl_type=0x0800,
                                                         nw_proto=0x06, nw_src=self.net.lb_ip, nw_dst=ip_src)
                actions = [parser.OFPActionSetDlSrc(self.net.lb_mac), parser.OFPActionOutput(msg.in_port)]
                self.add_flow(match, actions)

                # Update ARP table
                self.ip_to_mac.update({ip_src: src})

                # Update RR counter
                self.rr_counter = (self.rr_counter + 1) % self.net.servers_num