• Willkommen im Linux Club - dem deutschsprachigen Supportforum für GNU/Linux. Registriere dich kostenlos, um alle Inhalte zu sehen und Fragen zu stellen.

Multipath Route Load Balancing

Hallo,
ich möchte mit dem folgenden Script Load Balancing machen. Der Ping (UDP) zu externen Seiten funtkioniert. Nur wenn ich eine Seite im Browser aufrufe dauert dies meist 20 Sekunden z.B. für google. Findet jemand einen Fehler im folgenden Script? Ich Markiere eingehende externe Verbindungen damit diese immer über das gleiche Interface laufen, z.b. für einen internen Webserver. Ausgehende Verbindungen werden über die Multipath-Route geregelt außer Sie wurden bereits markiert.

Das ganze ist mit VMware realisiert. Das IFWAN1 Interface ist im Bridge Mode und IFWAN2 im NAT Mode.
Das Gateway für IFWAN1 ist 192.168.2.1 und für IFWAN2 192.168.5.2. Es gibt scheinbar probleme bei TCP-Verbindungen. (z.B. bei HTTP)

Code:
#!/bin/bash

sysctl -w net.ipv4.ip_forward=1 > /dev/null
#WEIGHTS für Multipath-Route
WEIGHT1=1
WEIGHT2=1

#WAN 1
IFWAN1=eth1
IPWAN1=192.168.2.128
NWWAN1=192.168.2.0/24

#WAN 2
IFWAN2=eth2
IPWAN2=192.168.5.128
NWAN2=192.168.5.0/24

#LAN
IFLAN1=eth0
IPLAN1=192.168.3.1
NWLAN1=192.168.3.0/24

IPISP1=192.168.2.1
IPISP2=192.168.5.2


ip route del default

#Markierung 1
iptables -t mangle -N MARK-T1
iptables -t mangle -A MARK-T1 -j MARK --set-mark 1
iptables -t mangle -A MARK-T1 -j CONNMARK --save-mark

#Markierung 2
iptables -t mangle -N MARK-T2
iptables -t mangle -A MARK-T2 -j MARK --set-mark 2
iptables -t mangle -A MARK-T2 -j CONNMARK --save-mark

#Routing table für Tabelle T1
ip route add default dev $IFWAN1 via $IPISP1 table T1
ip route add $NWWAN1 dev $IFWAN1 table T1
ip route add $NWLAN1 dev $IFLAN1 table T1

#Routing table für Tabelle T2
ip route add default dev $IFWAN2 via $IPISP2 table T2
ip route add $NWWAN2 dev $IFWAN2 table T2
ip route add $NWLAN1 dev $IFLAN1 table T2

#Traffic der über IFWAN1 kommt soll mit 1 markiert werden, damit eingehender er immer über das gleiche Interface beantwortet wird
iptables -t mangle -A PREROUTING -i $IFWAN1 -j MARK-T1
#Traffic der über IFWAN2 kommt soll mit 2 markiert werden, damit eingehender er immer über das gleiche Interface beantwortet wird
iptables -t mangle -A PREROUTING -i $IFWAN2 -j MARK-T2

#bei bereits aufgebauten Verbindungen soll die Markierung wiederhergestellt werden
iptables -t mangle -A PREROUTING -i $IFLAN1 -m conntrack --ctstate ESTABLISHED,RELATED -j CONNMARK --restore-mark

#Regel damit Traffic mit Mark 1 immer in table T1 geht
ip rule add fwmark 1 table T1
#Regel damit Traffic mit Mark 2 immer in table T2 geht
ip rule add fwmark 2 table T2

#Multipath-Route für neue Verbindungen vom internen Netz (Load Balancing)
ip route add default scope global nexthop via $IPISP1 dev $IFWAN1 weight $WEIGHT1 nexthop via $IPISP2 dev $IFWAN2 weight $WEIGHT2

#NAT
iptables -t nat -A POSTROUTING -o $IFWAN1 -j MASQUERADE
iptables -t nat -A POSTROUTING -o $IFWAN2 -j MASQUERADE

Schonmal vielen Dank ;)

Grüße
 
Code:
Es gibt scheinbar probleme bei TCP-Verbindungen. (z.B. bei HTTP).
Die Marker setzt du auf Chains bevor auch nur ein Bit überhaupt auf den Gedanken gekommen ist den Weg über deine Leitung zu gehen. Mal abgesehen davon können sie den Weg (Route) nicht kennen, weil du Routen irgendwann gegen Ende anlegst.

Mein Versuch es einfach zu erklären:
Du fährst 500km in den Osten, drehst dann rum, weil du eigentl. in den Westen willst, deinen Routenplaner aber bei der Oma, die 1000 KM südlich wohnt, auf dem Tisch liegt und es dir auch grade erst aufgefallen ist.
 
Hahaha lustiges Beispiel. Aber was wäre die Lösung. Ich will doch bevor ein Bit auf der Leitung ist, diesen Markieren, also wenn der Traffic von extern kommt. Ich glaube es ist dem OS egal wann die Routen angelegt werden. Ich denke es ist nur entscheidend in welcher Reihenfolge die iptable-Regeln stehen und die sind meiner Meinung nach in der richtigen Reihenfolge.

Hier mal die Config-Ausgabe:

ip route
Code:
192.168.5.0/24 dev eth2  proto kernel  scope link  src 192.168.5.128 
192.168.3.0/24 dev eth0  proto kernel  scope link  src 192.168.3.1 
192.168.2.0/24 dev eth1  proto kernel  scope link  src 192.168.2.110 
default 
	nexthop via 192.168.2.1  dev eth1 weight 1
	nexthop via 192.168.5.2  dev eth2 weight 1

ip rule
Code:
0:	from all lookup local 
32764:	from all fwmark 0x2 lookup T2 
32765:	from all fwmark 0x1 lookup T1 
32766:	from all lookup main 
32767:	from all lookup default

iptables mangle:
Code:
Chain PREROUTING (policy ACCEPT 108 packets, 12833 bytes)
target     prot opt in     out     source           destination         
MARK-T1    all  --  eth1   any     anywhere      anywhere            ctstate NEW 
MARK-T2    all  --  eth2   any     anywhere      anywhere            ctstate NEW 
CONNMARK   all  --  eth1   any     anywhere     anywhere            ctstate RELATED,ESTABLISHED CONNMARK restore 
CONNMARK   all  --  eth2   any     anywhere     anywhere            ctstate RELATED,ESTABLISHED CONNMARK restore 
CONNMARK   all  --  eth0   any     anywhere     anywhere            ctstate RELATED,ESTABLISHED CONNMARK restore 

Chain INPUT (policy ACCEPT 67 packets, 8349 bytes)
target     prot opt in     out     source               destination         

Chain FORWARD (policy ACCEPT 26 packets, 2330 bytes)
target     prot opt in     out     source               destination         

Chain OUTPUT (policy ACCEPT 14 packets, 1106 bytes)
target     prot opt in     out     source               destination         

Chain POSTROUTING (policy ACCEPT 40 packets, 3436 bytes)
 target     prot opt in     out     source               destination         

Chain MARK-T1 (1 references)
target     prot opt in     out     source               destination         
MARK       all  --  any    any     anywhere             anywhere            MARK set 0x1 
CONNMARK   all  --  any    any     anywhere             anywhere            CONNMARK save 

Chain MARK-T2 (1 references)
target     prot opt in     out     source               destination         
MARK       all  --  any    any     anywhere             anywhere            MARK set 0x2 
CONNMARK   all  --  any    any     anywhere             anywhere            CONNMARK save

iptables nat:
Code:
Chain PREROUTING (policy ACCEPT 68 packets, 9662 bytes)
target     prot opt in     out     source               destination         

Chain POSTROUTING (policy ACCEPT 2 packets, 168 bytes)
target     prot opt in     out     source               destination         
MASQUERADE  all  --  any    eth1    anywhere             anywhere            
MASQUERADE  all  --  any    eth2    anywhere             anywhere            

Chain OUTPUT (policy ACCEPT 9 packets, 686 bytes)
target     prot opt in     out     source               destination

ich find des sieht alles recht logisch aus oder nicht?
 
Gerade nochmal versucht, es scheint jetzt doch zu funktionieren. Des soll mal jemand verstehen. Muss jetzt los, werde es morgen nochmal testen und Bescheid geben ;)
 
Du verwechselst da etwas bzw. dir sind die Begrifflichkeiten nicht ganz geläufig. Kein Problem, ich gebe dir ein paar Beispiele.

Multipath:

Der Begriff kommt aus dem Storagebereich, SAN (Storage Area Network). Multipath hat also etwas mit Festplatten-Freigaben über ein Netzwerk zu tun.

Beispiel:
Ein Storagesystem stellt eine Festplatte über das Netzwerk bereit. Dabei werden mehrere Pfade verwendet die anhand ihrer LUN (Logical Unit Number) eindeutig identifiziert werden können.

http://www.sourceware.org/lvm2/wiki/MultipathUsageGuide


Du möchtest aber einen Redundanten Netzzugang realisieren. Den Redundaten Netzzugang nennt man auch Multihomed oder Multigateway.

Du verwendest kein Load Balancing (Lastausgleich bzw. Lastverteilung), weil du, anhand deiner Regeln, ein Gateway einem Netz fest zuordnest. Beim Load Balancing werden die Verbindungen aber gleichmäßig auf beide Gateways aufgeteilt und eine Überlastung eines einzelnen Gateways verhindert.

http://blog.khax.net/2009/12/01/multi-gateway-balancing-with-iptables/
http://www.pmoghadam.com/homepage/HTML/Round-robin-load-balancing-NAT.html
 
Ok, auf http://lartc.org beschreiben Sie die Route mit weights auch als Multipath-Route.
you now set up the default route to be a multipath route
Aber Multihomed hab ich auch schon gehört. Naja wie auch immer des jetzt richtig heißt, ich markier ja eigentlich nur die Verbindungen die ich von extern bekomme, also z.B. wenn einer von außen auf den Webserver zugreift. Heißt wenn eine neue Verbindung über eth1 oder eth2 reinkommt wird diese bei eth1 mit 1 und bei eth2 mit 2 markiert. (hier wird erst noch auf table MARK-T1 und T2 verwiesen aber diese markieren ja den Traffic) Bei bereits bestehenden Verbindungen wird die Markierung restored, weil bei http (TCP) sollte der Traffic immer über das gleiche externe Interface beantwortet werden. Wenn z.B. einer von außen eine Verbindung über eth1 aufbaut, soll er mit 1 markiert werden. Jetzt kommt der Traffic vom internen Netz (Webserver) über eth0 zurück, dann soll die Markierung restored werden, damit der Traffic wieder über eth1 zurück geht.

Code:
target     prot opt in     out     source           destination  
MARK-T1    all  --  eth1   any     anywhere      anywhere            ctstate NEW
MARK-T2    all  --  eth2   any     anywhere      anywhere            ctstate NEW
CONNMARK   all  --  eth1   any     anywhere     anywhere            ctstate RELATED,ESTABLISHED CONNMARK restore
CONNMARK   all  --  eth2   any     anywhere     anywhere            ctstate RELATED,ESTABLISHED CONNMARK restore
CONNMARK   all  --  eth0   any     anywhere     anywhere            ctstate RELATED,ESTABLISHED CONNMARK restore

Die rules zeigen, dass nur markierter Traffic in Routing-table T1 und T2 geleitet werden:
Code:
32764:   from all fwmark 0x2 lookup T2
32765:   from all fwmark 0x1 lookup T1

Wenn ich aber von innen eine Verbindung aufbaue kommt der Traffic in eth0 rein, hier würde also zunächt von den iptable-rules nur diese zutreffen. (in eth0)
Code:
target     prot opt in     out     source           destination  
CONNMARK   all  --  eth0   any     anywhere     anywhere            ctstate RELATED,ESTABLISHED CONNMARK restore

Da es sich aber um cstate NEW handelt bei einer neuen Verbindung trifft diese nicht zu, also keine Markierung und somit landet der Traffic in der main-Routing table, dort wo die "Multipath/homed/gateway" :p hinterlegt ist. ;)


Falls ich irgendwie mit meinen Behauptungen falsch liege, lasse ich mich gerne von dir belehren.

Vielen Dank.

Grüße
 
Bin nicht geflüchtet, aber war berufl. eine Woche in Hamburg und kann daher erst jetzt antworten.#

HItmaN schrieb:
Bei bereits bestehenden Verbindungen wird die Markierung restored, weil bei http (TCP) sollte der Traffic immer über das gleiche externe Interface beantwortet werden. Wenn z.B. einer von außen eine Verbindung über eth1 aufbaut, soll er mit 1 markiert werden. Jetzt kommt der Traffic vom internen Netz (Webserver) über eth0 zurück, dann soll die Markierung restored werden, damit der Traffic wieder über eth1 zurück geht.

Ok. Damit der ausgehende Traffic über das selbe Interface wandert, wo er rein gekommen ist benötigst du max. eine zusätzliche Chain. Da du zwei zusätzl. Chains (MARK-1 und MARK-2) verwendest, machst du es dir selber unnötig kompliziert, vor allem wenn noch die Load Balancing Regeln hinzu kommen.

Du kannst es übersichtl. und auch evtl. leicht verständl. machen, wenn du dein, sorry, Mischmasch Script strukturierst, besser noch aufsplitest in ein IP-Tables Script und ein Script, welches die Routen setzt.

IP-Tables Script:
Code:
#!/bin/bash

IFWAN1=eth1
IFWAN2=eth2
IFLAN1=eth0


# Chains flushen und eigene loeschen
iptables -t mangle -F OUTPUT
iptables -t mangle -F PREROUTING
iptables -t mangle -F balance-mark
iptables -t mangle -X balance-mark

# eigene chains anlegen
iptables -t mangle -N balance-mark
iptables -t mangle -A balance-mark -m connmark ! --mark 0 -j RETURN
iptables -t mangle -A balance-mark -m state --state ESTABLISHED,RELATED -j RETURN
iptables -t mangle -A balance-mark -i $IFWAN1 -j CONNMARK --set-mark 1
iptables -t mangle -A balance-mark -i $IFWAN2 -j CONNMARK --set-mark 2

# Neue ausgehende Verbindungen
iptables -t mangle -A PREROUTING -m state --state NEW -j balance-mark
iptables -t mangle -A OUTPUT -m state --state NEW -j balance-mark

# Wahl der Route und speichern der Markierung
iptables -t mangle -A PREROUTING -m connmark ! --mark 0 -j CONNMARK --restore-mark
iptables -t mangle -A OUTPUT -m connmark ! --mark 0 -j CONNMARK --restore-mark

Routing Script:
Code:
#!/bin/bash

# Gewichtung
WEIGHT1=1
WEIGHT2=1

#WAN 1
IFWAN1=eth1
IPWAN1=192.168.2.128
NWWAN1=192.168.2.0/24

#WAN 2
IFWAN2=eth2
IPWAN2=192.168.5.128
NWAN2=192.168.5.0/24

#LAN
IFLAN1=eth0
IPLAN1=192.168.3.1
NWLAN1=192.168.3.0/24

ip route del default table main
ip route del default table T1
ip route del default table T2

ip rule del fwmark 1
ip rule del fwmark 2

ip rule add fwmark 1 table T1
ip rule add fwmark 2 table T2
ip route add default via $IPWAN1 table T1
ip route add default via $IPWAN2 table T2
ip route add default via $IPLAN1 table main
ip route flusch cache

Ich habe in beiden Scripten bewusst ein paar "Lücken" gelassen (z.B. DestIP des Webservers, bei den Routen: welches Netz und welches Interface gehört mit welcher Tabelle zusammen). Du sollst die grauen Zellen ja auch ein wenig belasten und du kannst gleichzeitig testen, ob dir evtl. noch etwas unklar ist. ;)
 
Hi spoensche,

vielen Dank für deine Antwort, ich hatte in letzter Zeit auch viel zu tun, daher kann ich es erst heute Abend ausprobieren. Ich versteh glaub schon was du mit deinen iptable-Regeln machen willst, aber warum machst du das einmal auf Prerouting und danach nochmal auf Output?

Code:
iptables -t mangle -A PREROUTING -m state --state NEW -j balance-mark
iptables -t mangle -A OUTPUT -m state --state NEW -j balance-mark

iptables -t mangle -A PREROUTING -m connmark ! --mark 0 -j CONNMARK --restore-mark
iptables -t mangle -A OUTPUT -m connmark ! --mark 0 -j CONNMARK --restore-mark


Ich habe eigentlich die 2 extra Chains angelegt, weil ich dort das -save-mark mache. Laut Manpage würd ich sagen, dass ich das brauche.
Copy the packet mark (nfmark) to the connection mark (ctmark) using the given masks.
Gut man könnte es sicher auch direkt in die balance chains reinmachen oder?

Grüße
 
HltmaN schrieb:
Hi spoensche,

vielen Dank für deine Antwort, ich hatte in letzter Zeit auch viel zu tun, daher kann ich es erst heute Abend ausprobieren. Ich versteh glaub schon was du mit deinen iptable-Regeln machen willst, aber warum machst du das einmal auf Prerouting und danach nochmal auf Output?

Die Pakete laufen wie folgt durch den Kernel:
PREROUTING -> FORWARD -> POSTROUTING -> OUTPUT

D.h. Alle neu initierten Verbindungen, die geroutet werden sollen, wandern in die Chain balance-mark und werden dann anhand des Interfaces mit einer Marke versehen.

Um sicher zu gehen, dass auch alle Pakete bearbeitet worden sind, schicke ich alle neu initierten Verbindungen die wir ins LAN weiterleiten erneut in die Chain balance-mark.


HltmaN schrieb:
Ich habe eigentlich die 2 extra Chains angelegt, weil ich dort das -save-mark mache. Laut Manpage würd ich sagen, dass ich das brauche.
Copy the packet mark (nfmark) to the connection mark (ctmark) using the given masks.
Gut man könnte es sicher auch direkt in die balance chains reinmachen oder?

Eine Chain ist dafür völlig ausreichend. Du kannst ja anhand des Interfaces, den entsprechenden Marker setzen.
 
Hallo spoensche,

danke für deine Hilfe ;) ich bin jetzt gerade in Indonesien und die wollen hier einen Load Balancer mit einem Modem und einer DSL Leitung. Ich denke mit einem Modem funktioniert die Multipath-Route nicht mehr, weil man sich ja eigentlich einwählen muss. Naja kenn mich mit Modems nicht so aus aber hast du vielleicht eine Idee wie das gehen könnte?

Grüße ;)
 
Dein genanntes Load Balancer Szenario ist für die gegebenheiten vor Ort nicht geeignet, weil es darauf ausgelegt ist, den Traffic auf zwei Anschlüsse zu verteilen, damit ein Anschluss nicht dauernd unter Vollast steht.

Für das Szenario vor Ort benötigst du aber einen Proxy (z.B. Nginx), der den Traffic gleichmäßig auf mehrere Server verteilt, damit zum einen die Server gleichmäßig belastet und nicht überlastet sind und zum anderen die Performance der Anwendung (die auf den Servern läuft) gewährleistet ist.
 
Ok hab ich mir schon fast gedacht :( versteh jetzt nicht ganz wie du das mit dem proxy meinst. Ist dann an dem einem Server das Modem und an dem anderen die DSL-Leitung angeschlossen? Ich möchte eignetlich die interne Last nach außen verteilen oder was meinst du mit Anwendungen auf dem Server? Sorry hab noch nicht so den durchblick ;)

Grüße
 
HItmaN schrieb:
Sorry hab noch nicht so den durchblick ;)

Kein Grund sich zu entscchuldigen, man kann ja nicht alles wissen. Betonung liegt auf noch. Jeder hat mal klein angefangen.

HltmaN schrieb:
Ok hab ich mir schon fast gedacht :( versteh jetzt nicht ganz wie du das mit dem proxy meinst. Ist dann an dem einem Server das Modem und an dem anderen die DSL-Leitung angeschlossen? Ich möchte eignetlich die interne Last nach außen verteilen oder was meinst du mit Anwendungen auf dem Server?

Erläutere mir mal bitte, was du mit "die Last nach aussen verteilen." meinst.

Erklärung der Lastverteilung in sehr kurzer Form:

Mit der Lastverteilung des Traffics auf mehrere Server, soll z.B. die Überlastung eines Servers verhindert und somit die Verfügbarkeit zu gewährleisten. Gleichzeitig wird auch die Performance verbessert, weil u.a. die Antworzeiten der Server schneller sind. Die Verteilung erfolgt anhand von mathematischen Regeln, wie z.B. Statistik oder das Distributionsgesetz.


Zeichnung für einen Proxy (z.B. Nginx) der die Lastverteilung regelt.
----------------- ------------------
| DSL | ---------------------| Proxy | ----------------------------- Webserver 1
|---------------- ------------------
|--------------------------- Webserver 2l

Welche Art von Lastverteilung man verwendet ist vom Anwendungsfall abhängig.
 
Oben