Loadbalancing/failover - zarządzanie wieloma łączami
Ostatnia zmiana: 2021-08-31 19:15

Wielu użytkowników posiada dołączonych kilka łącz internetowych do swoich routerów i chce zapewnić ich wykorzystanie lub chce zapewnić ciągły dostęp do internetu w przypadku awarii jednego z nich. W takich przypadkach z pomocą przyjdzie pakiet o nazwie mwan3.
Działanie mwan3 opiera się na monitorowaniu dostępności łącz przez sprawdzenie dostępności określonych celów (zwykle przez pingowanie). W domyślnej konfiguracji są to dnsy google i opendns; jeżeli zostanie wykryty brak pingów następuje przełączenie routingu na inne łącza według reguł zdefiniowanych w konfiguracji. Mwan3 potrafi zapewnić przełączenie ruchu na inne łącza w przypadku zaniku jednego z nich lub rozłożenie ruchu na kilka dostępnych, ale nie spowoduje sumowania przepustowości łącz dla komputera który pobiera coś w jednym wątku.

Dołączone łącza mogą być dowolnego typu: ethernetowe, modem adsl, dwa modemy komórkowy na USB czy łącza radiowe. Mwan3 wymaga utrzymania aktywności wszystkich połączeń, więc wymaga aby np. wspomniany modem był na stałe włączony i podłączony do sieci.

Poniższa konfiguracja prezentuje wykorzystanie dwóch łączy, choć oczywiście analogicznie można zestawić ich kilka jednocześnie. W przykładzie wykorzystano OpenWrt 19.07 oraz 21.02 na routerze z połączeniem kablowym (pierwsze połączenie z internetem oznaczone jako wan) oraz modemem Huawei E3372s-153 HiLink (drugie połączenie z internetem oznaczone jako wanb).

Konfiguracja łączy

Oba łącza muszą być zestawione i musi istnieć przez nie połączenie do internetu; dla ułatwienia nazwiemy je wan oraz wanb. Oba łącza muszą mieć ustawione inne metryki.

Typy połączeń nie mają większego znaczenia ale we własnym zakresie trzeba zatroszczyć się o ich prawidłową konfigurację. Mwan3 zarządza routingiem, nie uruchamia/nie wznawia połączeń, to nie jest jego zadanie. Na użytkowniku spoczywa więc całość procesu utrzymania aktywności łącz. Wszystkie połączenia muszą być aktywne (podniesione); mwan3 samodzielnie nie podnosi połączeń.

Interfejs wan

W tym przykładzie został wykorzystany port WAN routera do którego zostało doprowadzone łącze kablowe. Do domyślnej konfiguracji wystarczy dodać opcję metric:


    # uci set network.wan.metric=10
    # uci commit network

Interfejs wanb

Jako drugie połączenie został wykorzystany modem dołączony do portu USB. Ponieważ był to HiLink (pracujący jako karta sieciowa), jego konfiguracja sprowadza się do instalacji odpowiednich sterowników i tak samo ustawienia opcji metric:


    # opkg update
    # opkg install usb-modeswitch kmod-usb-net-cdc-ether
    # uci -q del network.wanb
    # uci set network.wanb=interface
    # uci set network.wanb.proto=dhcp
    # uci set network.wanb.ifname=eth1
    # uci set network.wanb.metric=20
    # uci commit network

Dla OpenWrt w wersji 21.02-rc2 lub późniejszych i wersji rozwojowych należy inaczej ustawić interfejs:


    # uci -q del network.wanb.ifname
    # uci set network.wanb.device=eth1
    # uci commit network

Tworzona jest tu sekcja wanb na interfejsie eth1 (nazwa interfejsu zależy od modelu routera - należy to sprawdzić), dostała ona unikalną wartość metric.
Nie wolno zapominać o odpowiednim uzupełnieniu firewalla. Ponieważ wanb ma być to traktowany jak zwykły wan to po prostu wystarczy dodać go do sekcji wan firewalla:


    # uci add_list firewall.@zone[1].network=wanb
    # uci commit firewall

(domyślnie strefa "@zone[1]" firewalla odnosi się do sekcji wan - jeżeli konfiguracja firewalla została zmieniona to należy dostosować polecenie)

Jeżeli mamy więcej interfejsów należy analogicznie zrobić podobną konfigurację dla nich wszystkich. Należy pamiętać że OpenWrt sam z siebie wykorzystuje nazwy wan_4, wan_6 i wan6 do własnych celów, więc należy posłużyć się innymi.

Po wykonaniu czynności konfiguracyjnych trzeba wykonać restart routera:


    # reboot

Sprawdzenie połączeń

Po ustawieniu wanów należy sprawdzić czy mamy dostęp do internetu przez tak ustawione połączenia. Posługujemy się poleceniem ping ze wskazaniem konkretnego, fizycznego interfejsu:


    # ping -c3 -I eth0.2 google.com
PING google.com (194.9.25.49): 56 data bytes
64 bytes from 194.9.25.49: seq=0 ttl=58 time=6.908 ms
64 bytes from 194.9.25.49: seq=1 ttl=58 time=6.677 ms
64 bytes from 194.9.25.49: seq=2 ttl=58 time=9.343 ms

--- google.com ping statistics ---
3 packets transmitted, 3 packets received, 0% packet loss
round-trip min/avg/max = 6.677/7.642/9.343 ms



    # ping -c3 -I eth1 google.com
PING google.com (194.9.25.44): 56 data bytes
64 bytes from 194.9.25.44: seq=0 ttl=57 time=123.040 ms
64 bytes from 194.9.25.44: seq=1 ttl=57 time=22.740 ms
64 bytes from 194.9.25.44: seq=2 ttl=57 time=22.493 ms

--- google.com ping statistics ---
3 packets transmitted, 3 packets received, 0% packet loss
round-trip min/avg/max = 22.493/56.091/123.040 ms

W tym przykładzie eth0.2 i eth1 to wspomniane interfejsy, można je znaleźć wykonując polecenia ifstatus wan; ifstatus wanb (interfejsy odszukujemy w l3_device).
Jeżeli pingi działają można przejść do dalszej konfiguracji. Jeżeli nie - należy ponownie sprawdzić wany, bez tego dalsza konfiguracja jest pozbawiona sensu.

Instalacja

Po prostu trzeba zainstalować odpowiedni pakiet


    # opkg update
    # opkg install mwan3

Jeżeli mamy środowisko graficzne LuCI to dostępna jest także odpowiednia aplikacja do niego:


    # opkg install luci-app-mwan3

Choć oczywiście do dalszej konfiguracji nie jest ona niezbędna.

Konfiguracja

Konfiguracja zawarta jest w pliku /etc/config/mwan3 i zawiera już kilka niezbędnych elementów dla obu łączy:

  • definicje interfejsów (config interface): zawiera informacje o włączeniu interfejsu, listę celów ping, ilość pingów i timeouty sprawdzania łącza, domyślnie dla wan i wanb (ipv4) oraz wan6 i wanb6 (ipv6)
  • definicje ważności łączy (config member): zawiera informacje o "wagach" łączy, o czym będzie za chwilę
  • definicje polityk (config policy): zawiera informacje o kombinacjach wykorzystania łączy
  • definicje reguł (config rule) które definiują zasady wykorzystania polityk przez określony ruch. Musi zawierać co najmniej jedną polityką domyślną która będzie umieszczona na końcu wszystkich reguł
Jeżeli mamy tylko dwa łącza to cała konfiguracja sprowadza się do włączenia ich w konfiguracji mwan3:


    # uci set mwan3.wan.enabled=1
    # uci set mwan3.wanb.enabled=1
    # uci commit mwan3
    # reboot

Wykonujemy restart urządzenia i sprawdzamy status połączeń:


    # mwan3 interfaces
    Interface status:
        interface wan is online 00h:00m:12s, uptime 00h:07m:25s and tracking is active
        interface wan6 is offline and tracking is down
        interface wanb is online 00h:00m:05s, uptime 00h:07m:27s and tracking is active
        interface wanb6 is offline and tracking is down

Jeżeli oba interfejsy są aktywne to jest to cała konfiguracja, choć oczywiście można dalej przystosować konfigurację do własnych potrzeb. Dla większej ilości łączy należy samodzielnie stworzyć nowe sekcje interface, member i policy. Nazwy reguł i polityk mają ograniczoną długość (do 15 znaków), więc należy unikać opisowych oznaczeń.

Wan6 i wanb6 są domyślnie wyłączone, dlatego pokazują się jako offline.

Jak sprawdzić działanie? Wchodzimy np. na adres http://twojeip.wp.pl/, sprawdzamy jaki mamy adres IP a potem odłączamy kabel od wanu i czekamy parę sekund - po odświeżeniu w przeglądarce powinien być adres z drugiego łącza. Można tak samo posłużyć się pingami. Należy pamiętać że mwan3 nie utrzymuje połączenia w ramach tej samej sesji, co może oznaczać ze po prostu trzeba przerwać pingi i ponownie uruchomić polecenie żeby zobaczyć fakt przełączenia na drugie łącze.

Uzupełnienie konfiguracji

Serwery DNS

Konieczne jest wymuszenie adresów dnsów na wanach na inne, niezależne od naszych dostawców internetu. Wystarczy ustawić np. na serwery google:


    # uci set network.wan.dns='8.8.8.8 8.8.4.4'
    # uci set network.wan.peerdns=0
    # uci set network.wanb.dns='8.8.8.8 8.8.4.4'
    # uci set network.wanb.peerdns=0
    # uci commit network
    # reboot

Lub inne, ważne żeby były osiągalne z dowolnego łącza które mamy.

Loadbalancing i failover

Pod tymi pojęciami kryją się dwa sposoby działania mwan3: odpowiednio - rozłożenie ruchu na aktywne łącza i przełączanie ruchu na inne łącza w przypadku zaniku jednego z nich. Mwan3 realizuje oba zagadnienia jednocześnie, choć można to oczywiście zmienić po swojemu. W domyślnej konfiguracji podział łącza wygląda następująco (przy używaniu domyślnej polityki balanced):


    # mwan3 policies
    Current ipv4 policies:
    balanced:
        wanb (40%)
        wan (60%)
    wan_only:
        wan (100%)
    wan_wanb:
        wan (100%)
    wanb_only:
        wanb (100%)
    wanb_wan:
        wanb (100%)



    # mwan3 rules
    Active ipv4 user rules:
                8 480 S https tcp -- * * 0.0.0.0/0 0.0.0.0/0 multiport dports 443
            93 7186 - balanced all -- * * 0.0.0.0/0 0.0.0.0/0

Mamy podział wan/wanb w stosunku 60:40 i taki podział wykorzystania pasma będzie mwan3 starał się utrzymać. Można to zmienić przez modyfikację opcji weight w sekcjach member konfiguracji. Zdefiniowana domyślna reguła (default_rule_v4) korzysta z polityki balanced. Polityka ta używa m.in. dwóch definicji (member) o nazwach wan_m1_w3 i wanb_m1_w2. Zmieniając w nich opcję weight można więc odpowiednio tym sterować, np:

  • ustawienie łączy 50:50 (oba łącza będą wykorzystywane po równo)


    # uci set mwan3.wan_m1_w3.weight='3'
    # uci set mwan3.wanb_m1_w2.weight='3'
    # uci commit mwan3
    # mwan3 restart
    # mwan3 policies
    Current ipv4 policies:
    balanced:
        wanb (50%)
        wan (50%)
...


  • ustawienie łączy 99:1 (łącze wan jest "lepsze" i ono będzie w dużej mierze wykorzystywane - coś w rodzaju failover)


    # uci set mwan3.wan_m1_w3.weight='99'
    # uci set mwan3.wanb_m1_w2.weight='1'
    # uci commit mwan3
    # mwan3 restart
    # mwan3 policies
    Current ipv4 policies:
    balanced:
        wanb (1%)
        wan (99%)
    wan_only:
        wan (100%)
    wan_wanb:
        wan (100%)
    wanb_only:
        wanb (100%)
    wanb_wan:
        wanb (100%)


Domyślnie konfiguracja określa pięć polityk:

  • balanced: loadbalancer, wan i wanb wykorzystywane są na podstawie zdefiniowanych metryk
  • wan_only: pozwala na korzystanie tylko z łącza wan
  • wan_wanb: failover, podstawowym łączem jest wan, jeżeli nie ma połączenia następuje przełączenie na wanb
  • wanb_only: pozwala na korzystanie tylko z łącza wanb
  • wanb_wan: failover, podstawowym łączem jest wanb, jeżeli nie ma połączenia następuje przełączenie na wan
Domyślną polityką jest balanced; zmieniając politykę w regule default_rule_v4 można sterować zachowaniem przełączenia ruchu. Chcąc uzyskać więc np. failover zamiast omówionego wcześniej loadbalancera można wykonać:


    # uci set mwan3.default_rule_v4.use_policy='wan_wanb'
    # uci commit mwan3
    # mwan3 restart

Głównym łączem będzie wan, po wykryciu awarii łącza nastąpi przełączenie ruchu na wanb. Jeżeli pojawią się ponownie odpowiedzi na pingi na łączu wan nastąpi automatycznie przełączenie na pierwsze łącze.

Wymuszenie ruchu przez określone łącze

Domyślna konfiguracja zawiera przykłady wymuszenia dla ruchu https z wykorzystaniem polityki balanced. Można dodać dowolną ilość własnych reguł; jako przykład podano wymuszenie całego ruchu z komputera o adresie 192.168.1.100 przez łącze wanb:


    # uci set mwan3.host100=rule
    # uci set mwan3.host100.sticky='1'
    # uci set mwan3.host100.src_ip=192.168.1.100
    # uci set mwan3.host100.proto='tcp'
    # uci set mwan3.host100.use_policy='wanb_only'
    # uci commit mwan3
    # mwan3 restart

Dodajemy regułę aby komputer o adresie 192.168.1.100 korzystał z polityki wanb_only w której zdefiniowane jest wykorzystanie tylko łącza wanb jako źródła internetu. Powyższa reguła powinna być przed regułą domyślną, czyli w konfiguracji trzeba przenieść sekcję default_rule_v4 na sam koniec pliku /etc/config/mwan3 żeby wyglądało to tak:


    ...

    config rule 'host100'
        option sticky '1'
        option src_ip '192.168.1.100'
        option proto 'tcp'
        option use_policy 'wanb_only'

    config rule 'default_rule_v4'
        option dest_ip '0.0.0.0/0'
        option family 'ipv4'
        option use_policy 'balanced'

Po dodaniu oczywiście oczywiście wykonujemy restart mwan3. Aktywne reguły pokazuje polecenie mwan3 rules:


    Active ipv4 user rules:
            25 1500 S https tcp -- * * 0.0.0.0/0 0.0.0.0/0 multiport dports 443
                0 0 S host100 tcp -- * * 192.168.1.100 0.0.0.0/0
            59 8392 - balanced all -- * * 0.0.0.0/0 0.0.0.0/0

Upewniamy się że domyślna reguła jest na samym końcu.

Kolejny przykład - kierujemy ruch na określoną witrynę (w tym przypadku: speedtest.net) przez łącze wanb. Dodajemy kolejną regułę w pliku /etc/config/mwan3 przed default_rule_v4:


    ...
    config rule 'speedtest'
        option sticky '1'
        option ipset 'speedtest'
        option proto 'all'
        option use_policy 'wanb_only'
    ...

Następnie dodajemy do firewalla (/etc/config/firewall) odpowiednią sekcję ipset


    config ipset
        option enabled '1'
        option name 'speedtest'
        option storage 'hash'
        option family 'ipv4'
        option match 'src_ip'

oraz instalujemy pełną wersję dnsmasq z wsparciem dla ipset i konfigurujemy go odpowiednio:


    # opkg update
    # opkg remove dnsmasq
    # opkg install dnsmasq-full
    # uci add_list dhcp.@dnsmasq[0].ipset='/speedtest.net/speedtest'
    # uci commit
    # /etc/init.d/dnsmasq restart
    # /etc/init.d/mwan3 restart

Jeżeli korzystamy z nazw domenowych to musimy pamiętać o konieczności restartu komputera lub wyczyszczenia cache dns w przypadku Windowsa.

Szeroki opis możliwości konfiguracyjnych mwan3 dostępny jest na wiki openwrt, tam też można znaleźć opis parametrów konfiguracyjnych reguł.