HAProxy (High Availability Proxy) to otwarte oprogramowanie dostarczające usługę load-balancing’u, a także high-availability. W prosty sposób umożliwia równoważenie obciążenia, a także przekierowanie ruchu sieciowego pomiędzy wieloma serwerami backendowymi.
HAProxy oferuje również funkcje kontroli zdrowia serwerów backendowych, które monitorują stan serwerów i automatycznie wykluczają uszkodzone lub niedostępne serwery z puli dostępnych serwerów. Pozwala to zapewnić wysoką dostępność, a także odporność na awarie serwerów.
Jest to popularne narzędzie stosowane w środowiskach sieciowych do zapewnienia wydajności, niezawodności, a także skalowalności aplikacji internetowych. W poniższej instrukcji przechodzimy proces instalacji i konfiguracji HAProxy. Zaczynamy od konfiguracji load balancingu, następnie zajmujemy się HA.
Promocja na kursy z Cyberbezpieczeństwa!
Zapisy przyjmujemy do 13 listopada do 23:59! . Skorzystaj z promocji: https://asdevops.pl/nis2-promocja/
Środowisko testowe
- Virtualbox
- AlmaLinux – 4 maszyny wirtualne (2 load balancery, 2 serwery backend – apache2)
W celach testowych utworzyłem cztery maszyny wirtualne za pomocą virtualbox.
Dwie z nich będą pełnić rolę load balancera (Master/Backup). Pozostałe maszyny to serwery backendowe, na których jest postawiony apache2. Serwery serwują prostą stronę www.
Poniżej diagram środowiska testowego:
Co potrzebujemy?
dwie instancje pod load balancera (HAProxy)
Przykładowo
LB1 Master / 192.168.1.15
LB2 Backup / 192.168.1.49
dwie instancje pod serwer www (apache2)
host2 / 192.168.1.51
host3 / 192.168.1.156
Szybka instalacja apache2 na serwerach backend
Do testów użyjemy prostej statycznej strony www. Komendy wykonujemy na obu serwerach.
- Zaktualizuj pakiety, wykonując następujące polecenie:
sudo dnf update
- Następnie zainstaluj pakiet Apache2
sudo dnf install httpd
- uruchom usługę Apache
sudo systemctl start httpd
- Upewnij się, że usługa uruchomi się przy starcie systemu
sudo systemctl enable httpd
- Następnie sprawdź status usługi
sudo systemctl status httpd
Jeżeli wszystko jest w porządku, to po wpisaniu adresu IP serwera do paska przeglądarki powinniśmy otrzymać domyślną stronę testową Apache. Możemy stworzyć własną stronę html. Wystarczy w katalogu /var/www/html umieścić plik index.html.
nano /var/www/html/index.html
Przykładowo:
<!DOCTYPE html>
<html>
<head><title>Moja strona</title></head>
<body><p>Witaj na mojej stronie!</p></body>
</html>
Jeżeli w systemie jest uruchomiony firewall, musisz zezwolić na przychodzący ruch HTTP (port 80). Możesz użyć następującego polecenia, aby zezwolić na ruch HTTP przy użyciu firewalld:
sudo firewall-cmd --permanent --add-service=http
sudo firewall-cmd --reload
Instalacja i konfiguracja HAProxy
Mamy przygotowane testowe środowisko backendowe. Przejdziemy teraz proces instalacji, a także konfiguracji HAProxy. Instalację jak również konfigurację wykonaj na obu serwerach przeznaczonych do roli Load Balancera. W moim przypadku jest to LB1, a także LB2. Taka konfiguracja potrzebna nam będzie później do zapewnienia high-availability.
- Zaktualizuj listę pakietów
sudo dnf update
- Następnie zainstaluj pakiet HAProxy
sudo dnf install haproxy
- Uruchamiamy usługę:
systemctl start haproxy
- Sprawdź wersję HAProxy, aby upewnić się, że został poprawnie zainstalowany
haproxy -v
lub
sudo systemctl status haproxy
Etap 1 – Konfiguracja Load Balancingu
Równoważenie obciążenia polega na dystrybucji żądań klientów pomiędzy wiele serwerów backendowych w celu zoptymalizowania wykorzystania zasobów i zapewnienia wydajności aplikacji. HAProxy działa jako punkt wejścia dla ruchu sieciowego i analizuje przychodzące żądania, aby przekierować je do odpowiednich serwerów backendowych.
HAProxy monitoruje również stan serwerów backendowych i automatycznie wyklucza uszkodzone lub niedostępne serwery z puli dostępnych serwerów. W ten sposób zapewnia wysoką dostępność i odporność na awarie.
W moim scenariuszu konfiguracja HAProxy rozdziela ruch przychodzący na dwa serwery backendowe.
Zaczynamy!
- Otwórz plik konfiguracyjny HAProxy przy użyciu edytora tekstu:
sudo nano /etc/haproxy/haproxy.cfg
Sekcja „global” w pliku konfiguracyjnym zawiera ogólne ustawienia dotyczące działania.
global
daemon
maxconn 4096
Sekcja „default” w pliku konfiguracyjnym zawiera domyślne ustawienia dotyczące zachowania proxy.
defaults
log global
mode http
option httplog
option dontlognull
timeout connect 5000
timeout client 50000
timeout server 50000
Wyjaśnienia
daemon: Powoduje uruchomienie HAProxy jako demon.
mode: Określa tryb pracy HAProxy. W tym przykładzie używany jest tryb HTTP.
option httplog: Włącza logowanie ruchu HTTP.
timeout connect: Określa maksymalny czas oczekiwania na nawiązanie połączenia.
timeout client i timeout server: Określają maksymalny czas oczekiwania na odpowiedź od klienta i serwera.
Teraz najważniejsze
Skonfiguruj sekcję „frontend”, która określa sposób obsługi połączeń przychodzących. Poniżej znajduje się przykład konfiguracji, która nasłuchuje na porcie 80 i przekierowuje ruch do sekcji „backend”:
(screen niżej)
frontend www
bind *:80
default_backend wwwback
W tym samym pliku skonfiguruj sekcję „backend”, która definiuje serwery docelowe. Tutaj jest przykład konfiguracji z dwoma serwerami. Ale nie ma problemu dołożyć kolejne.
HAProxy oferuje różne algorytmy równoważenia obciążenia, ja do testów wybrałem roundrobin. Algorytm ten przekierowuje żądania klientów do serwerów backendowych w kolejności, rotując je wokół puli serwerów. Dostępne są również opcje Least Connections oraz Least Response Time
backend wwwback
balance roundrobin
server host2 192.168.1.51:80 check
server host3 192.168.1.156:80 check
Zamień 192.168.1.51 i 192.168.1.156 na rzeczywiste adresy IP swoich serwerów backendowych.
Zapisz zmiany, a następnie wyjdź z edytora tekstu. Sprawdź składnię pliku konfiguracyjnego, aby upewnić się, że nie ma błędów. Jeśli nie ma błędów, powinieneś zobaczyć komunikat „Configuration file is valid”.
sudo haproxy -c -f /etc/haproxy/haproxy.cfg
Zrestartuj usługę HAProxy, aby zastosować zmiany w konfiguracji:
sudo systemctl restart haproxy
Finalnie sprawdź status usługi haproxy
sudo systemctl status haproxy
Wykonaj tą samą konfigurację na drugim Load Balance’rze.
Jeżeli teraz odpalimy sobie adres IP pierwszego lub drugiego load balancera, otrzymamy statyczną treść z serwera backend. Działa! Spróbuj wyłączyć jeden z serwerów a potem obydwa.
Po odświeżeniu strony, ruch leci już z drugiego serwera
Konfiguracja Keepalived
Konfiguracja Keepalived pozwala na utrzymanie wysokiej dostępności Load Balancer’ów poprzez monitorowanie i automatyczne przełączanie między węzłami.
W kontekście Keepalived, demon nazywany „VRRP” (Virtual Router Redundancy Protocol) działa na dwóch lub więcej serwerach, które tworzą grupę wysokiej dostępności. Każdy serwer w grupie ma przypisaną rolę podobną do mastera lub backupu. Głównym celem VRRP jest zapewnienie, że tylko jeden serwer w grupie jest aktywny jako master, a reszta działa jako backup.
Demon VRRP monitoruje status serwerów w grupie, wysyłając regularne komunikaty VRRP (tzw. „hello messages”) między serwerami. W ramach tych komunikatów serwery informują się nawzajem o swoim stanie i dostępności. Jeśli demon VRRP przestaje otrzymywać odpowiedzi od mastera (np. z powodu awarii sprzętu lub problemów sieciowych), to demon backupu może przejąć rolę mastera i kontynuować obsługę ruchu sieciowego. Ta dynamiczna zmiana roli odbywa się w celu zapewnienia ciągłości usług.
1. Zainstaluj Keepalived na każdym Load Balance’rze
sudo dnf install keepalived
2. Otwórz plik konfiguracyjny Keepalived przy użyciu edytora tekstu
sudo nano /etc/keepalived/keepalived.conf
3. Następnie wprowadź następującą konfigurację
LB1 | LB2 |
vrrp_script chk_haproxy { script „killall -0 haproxy” interval 2 weight 2 } vrrp_instance VI_1 { interface enp0s3 state MASTER virtual_router_id 51 priority 101 virtual_ipaddress{ 192.168.0.99 } track_script { chk_haproxy } } | vrrp_script chk_haproxy { script „killall -0 haproxy” interval 2 weight 2 } vrrp_instance VI_1 { interface enp0s3 state BACKUP virtual_router_id 51 priority 100 virtual_ipaddress { 192.168.0.99 } track_script { chk_haproxy } } |
Opis konfiguracji:
script „killall -0 haproxy” # weryfikacja czy pid istnieje
interval 2 # interwał czasowy sprawdzania (w tym przypadku 2 sekundy)
weight 2 # dodanie punktów jeżeli wszystko ok
interface enp0s3 # interfejs który jest monitorowany, sprawdzamy za pomocą ip a
state # rola serwera – MASTER jako główny, BACKUP – zapasowy
virtual_router_id 51 # identyfikator trasy
virtual_ipaddress # wirtualny IP pod którym usługi są dostępne, służy do kierowania ruchu do serwera
Po skonfigurowaniu Keepalived, węzły będą monitorowane, a w przypadku awarii węzła MASTER, stan wysokiej dostępności zostanie przełączony na węzeł BACKUP. Virtual IP (adres IP wirtualny) zostanie przeniesiony na nowego węzła, zapewniając ciągłość działania usług.
4. Zapisz pliki konfiguracyjne na obu węzłach i zrestartuj usługę Keepalived
sudo systemctl restart keepalived
5. Następnie sprawdź status usługi Keepalived.
sudo systemctl status keepalived
Aby upewnić się, że klastry komunikują się między sobą wykonaj komendę:
tcpdump -i <podłączony interfejs (u mnie enp0s3)> vrrp -c 10 -v
Sprawdź nowy interfejs:
ip a
Podsumowanie – HAProxy
W początkowym etapie wykonaliśmy konfigurację Load Balancera, który odpowiada za równoważenie obciążenia ruchu sieciowego pomiędzy serwerami backendowymi.
Dzięki temu w przypadku awarii, brak zasilania czy właśnie zwiększonego ruchu, HAProxy automatycznie przełączy ruch na drugi lub kolejny serwer backendowy.
Kolejnym etapem było zapewnienie wysokiej dostępności właśnie dla Load Balancerów. Nic nam z farmy serwerów, jeżeli nie będziemy mieć dostępnej maszyny odpowiedzialnej za przekierowanie ruchu. Dlatego duplikujemy również serwery pełniące role Load Balancera.
Scenariusze testowe:
- Przy działającej usłudze Load Balancera, wyłącz jeden z serwerów backend. Efektem tego będzie automatyczne przełączenie na kolejny z dostępnych serwerów.
- Wyłącz jeden z Load Balancerów. Efektem poprawnie skonfigurowanych serwerów jest chwilowy dłuższy czas oczekiwania na treść, ale po ok 5 sekundach (wartość do ustawienia), kierowanie ruchem przejmuje serwer zapasowy.