Keepalived to otwarte oprogramowanie używane w systemach Linux do zapewniania wysokiej dostępności i równoważenia obciążenia dla serwerów i usług. Jest to narzędzie, które umożliwia tworzenie klasterów o wysokiej dostępności poprzez monitorowanie stanu zdrowia serwerów i dynamiczne przekierowywanie ruchu między nimi w przypadku awarii lub problemów z dostępnością. Keepalived zapewnia implementację zarówno wersji 2, jak i wersji 3 protokołu służącego do przełączania awaryjnego HA – Virtual Router Redundancy Protocol (VRRP).
Keepalived – czyli wysoka dostępność serwerów i usług
Keepalived został stworzony przez Alex Shemyakin, który jest głównym twórcą i programistą tego projektu. Jest to projekt open-source, co oznacza, że jest dostępny publicznie i może być używany oraz rozwijany przez społeczność programistów i użytkowników. Dzięki społeczności otwartego oprogramowania, Keepalived jest ciągle rozwijany i udoskonalany, a także dostosowywany do różnorodnych potrzeb i scenariuszy.
Podstawowe cechy Keepalived
- Monitorowanie stanu serwerów: Keepalived ciągle monitoruje stan zdrowia serwerów w klastrze. Może to obejmować sprawdzanie dostępności serwerów poprzez ping lub inne protokoły, a także monitorowanie usług działających na serwerach, takich jak serwery WWW czy bazy danych.
- Równoważenie obciążenia: Keepalived automatycznie dystrybuuje ruch od użytkowników do zdrowych serwerów w celu równoważenia obciążenia. To pozwala uniknąć nadmiernego obciążenia pojedynczego serwera, co może prowadzić do spadku wydajności lub awarii.
- Przekierowywanie w przypadku awarii: Jeśli któryś z serwerów zostanie uznany za niedostępny, Keepalived automatycznie przenosi ruch na zdrowy serwer, aby zapewnić ciągłość usług. Dzięki temu awaria jednego serwera nie prowadzi do przerwy w dostępie do usług.
- Virtual IP (VIP): Keepalived może również zarządzać wirtualnym adresem IP, który jest używany przez użytkowników do łączenia się z usługą. W przypadku awarii serwera, Keepalived przypisuje ten wirtualny adres IP do zdrowego serwera, minimalizując przerwy w dostępie.
- Konfigurowalność: Keepalived oferuje szeroki zakres opcji konfiguracyjnych, które pozwalają dostosować zachowanie klastra do indywidualnych potrzeb i scenariuszy.
Keepalived jest często stosowany w środowiskach, gdzie dostępność i niezawodność są kluczowe, takich jak serwery WWW, serwery poczty, serwery baz danych i inne usługi. Dzięki niemu można zapewnić, że awarie sprzętu lub oprogramowania nie wpłyną negatywnie na dostępność usług, co jest niezwykle istotne w dzisiejszym środowisku cyfrowym.
Założenia scenariuszy testowych
Wykorzystamy Keepalived do utrzymania wysokiej dostępności dwóch serwerów www (Nginx). Naszym celem jest zapewnienie dostępności strony internetowej, nawet wtedy, gdy jeden z serwerów przestanie działać. Do tego celu wykorzystamy trzy adresy IP:
- 10.225.38.46: Ten adres będzie używany jako główny serwer
primary
- 10.225.38.57: Ten adres będzie używany jako pomocniczy serwer
secondary
- 10.225.38.38: Ten adres będzie wirtualnym adresem IP (
virtual IP
), który będzie przypisany do aktywnego serwera.
Zakładamy że na obydwu serwerach mamy następujący stan:
- aktualny system (Debian/Ubuntu)
- włączona synchronizacja czasu (chronyd lub ntpd)
- ustawiony stały adres IP
Aby osiągnąć cel, zainstalujemy Keepalived, który będzie monitorował stan zdrowia serwerów i w razie potrzeby przejmie kontrolę nad adresem virtual IP, aby utrzymać dostępność usługi. Gdy główny serwer przestanie działać, Keepalived automatycznie przeniesie adres virtual IP na pomocniczy serwer, aby kontynuować dostarczanie usługi.
Powyższy zamysł przetestujemy za pomoc dwóch scenariuszy:
- Scenariusz 1 – prosta konfiguracja Keepalived bez monitorowania stanu usługi Nginx.
- Scenariusz 2 – konfiguracja rozbudowana o dodatkowe monitorowanie stanu usługi Nginx.
Scenariusz 1
1.1 Konfiguracja serwera Primary:
#ustawiamy hostname hostnamectl set-hostname primary #instalujemy nginx oraz keepalived apt install keepalived nginx #ustawiamy na domyślnej stronie nazwę hosta echo $(hostname) > /var/www/html/index.nginx-debian.html #tworzymy plik konfiguracyjny mkdir /etc/haproxy/ vim /etc/keepalived/keepalived.conf
zawartość:
vrrp_instance MY_KEEPALIVED1 { # Definicja instancji VRRP o nazwie MY_KEEPALIVED1 state MASTER # Tryb pracy: MASTER lub BACKUP interface ens3 # Określa interfejs, na którym działać będzie instancja VRRP virtual_router_id 1 # Unikalny numer identyfikacyjny wirtualnego routera priority 11 # Priorytet tego węzła (wyższa wartość oznacza wyższy priorytet) # Adresy virtual IP zarządzane przez Keepalived virtual_ipaddress { 10.225.38.38 } }
Sprawdzamy status
systemctl restart nginx systemctl restart keepalived systemctl status nginx systemctl status keepalived
sprawdzamy czy na naszym interfejsie pojawiło się virtualne IP
ubuntu@primary:~$ ip a | grep ens3 2: ens3: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc fq_codel state UP group default qlen 1000 inet 10.225.38.46/24 metric 100 brd 10.225.38.255 scope global ens3 inet 10.225.38.38/32 scope global ens3
1.2 Konfiguracja serwera Secondary:
#ustawiamy hostname hostnamectl set-hostname secondary #instalujemy nginx oraz keepalived apt install keepalived nginx #ustawiamy na domyślnej stronie nazwę hosta echo $(hostname) > /var/www/html/index.nginx-debian.html #tworzymy plik konfiguracyjny mkdir /etc/haproxy/ vim /etc/keepalived/keepalived.conf
zawartość
vrrp_instance MY_KEEPALIVED1 { # Definicja instancji VRRP o nazwie MY_KEEPALIVED1 state BACKUP # Tryb pracy: MASTER lub BACKUP interface ens3 # Określa interfejs, na którym działać będzie instancja VRRP virtual_router_id 1 # Unikalny numer identyfikacyjny wirtualnego routera priority 10 # Priorytet tego węzła (wyższa wartość oznacza wyższy priorytet) # Adresy virtual IP zarządzane przez Keepalived virtual_ipaddress { 10.225.38.38 } }
musimy zmienić priority
na niższą wartość oraz ustawiamy state
na BACKUP
uruchamiamy i sprawdzamy status
systemctl restart nginx systemctl restart keepalived systemctl status nginx systemctl status keepalived
Sprawdzamy czy na naszym drugim serwerze pojawiło się virtual IP:
ubuntu@secondary:~$ ip a | grep ens3 2: ens3: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc fq_codel state UP group default qlen 1000 inet 10.225.38.57/24 metric 100 brd 10.225.38.255 scope global ens3
W sytuacji kiedy oba serwery działają poprawnie nie powinno go być.
1.3 Testy
W ramach testów zasymulujemy awarię pierwszego serwera primary
i sprawdzimy czy Keepalived przeniesie virtual IP
na server secondary
. W pierwszej kolejności z naszego hosta sprawdzimy dostępność strony www na adresie virtual IP
:
kamil@legion:~$ curl 10.225.38.38 primary
Teraz zasymulujmy awarię serwera primary
:
ubuntu@primary:~# sudo systemctl stop keepalived
Sprawdzamy czy keepalived przeniósł virtual IP
na serwer secondary
:
ubuntu@secondary:~$ ip a | grep ens3 2: ens3: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc fq_codel state UP group default qlen 1000 inet 10.225.38.57/24 metric 100 brd 10.225.38.255 scope global ens3 inet 10.225.38.38/32 scope global ens3
Ostatnią rzeczą którą sprawdzimy to dostępność strony www z naszego hosta
kamil@legion:~$ curl 10.225.38.38 secondary
Strona www jest cały czas dostępna pod adresem ustawionym jako virtual IP
ale tym razem ruch został przekierowany na serwer secondary
. Natomiast w tym prostym scenariuszu w przypadku awarii samego Nginxa, virtual IP
nie zostanie przeniesiony. Scenariusz zabezpiecza tylko przed następującymi awariami:
- Całkowita awaria serwera
- Awaria samego daemona keepalived
- Awaria karty sieciowej
W Scenariuszu drugim dodamy sprawdzanie stanu serwera Nginx aby zabezpieczyć się także przed tą potencjalną awarią.
Scenariusz 2
Rozbudujemy konfigurację keepalived o dodatkowe monitorowanie stanu usługi Nginx.
2.1 Konfiguracja serwera Primary:
# Plik konfiguracyjny Keepalived # Globalne definicje global_defs { router_id nginx # Unikalna nazwa dla tego węzła Keepalived } # Skrypt monitorujący stan NGINX vrrp_script check_nginx { script "/bin/check_nginx.sh" # Ścieżka do skryptu monitorującego interval 2 # Interwał sprawdzania w sekundach weight 50 # Waga skryptu (wyższa waga oznacza większą ważność) } # Instancja Keepalived vrrp_instance MY_KEEPALIVED1 { state MASTER # Tryb pracy: MASTER lub BACKUP interface ens3 # Interfejs sieciowy, na którym działa Keepalived virtual_router_id 1 # Unikalny numer identyfikacyjny instancji VRRP priority 11 # Priorytet tego węzła (wyższa wartość oznacza wyższy priorytet) # Adresy virtual IP zarządzane przez Keepalived virtual_ipaddress { 10.225.38.38 } # Śledzenie stanu NGINX za pomocą skryptu track_script { check_nginx # Śledzenie skryptu check_nginx } }
tworzymy skrypt monitorujący stan daemona Nginx
vim /bin/check_nginx.sh
zawartość:
#!/bin/sh if [ -z "`pidof nginx`" ]; then exit 1 fi
nadajemy uprawnienia dla skryptu oraz restartujemy keepalived
chmod 755 /bin/check_nginx.sh systemctl restart keepalived
2.2 Konfiguracja serwera Secondary:
# Plik konfiguracyjny Keepalived # Globalne definicje global_defs { router_id nginx # Unikalna nazwa dla tego węzła Keepalived } # Skrypt monitorujący stan NGINX vrrp_script check_nginx { script "/bin/check_nginx.sh" # Ścieżka do skryptu monitorującego interval 2 # Interwał sprawdzania w sekundach weight 50 # Waga skryptu (wyższa waga oznacza większą ważność) } # Instancja Keepalived vrrp_instance MY_KEEPALIVED1 { state BACKUP # Tryb pracy: MASTER lub BACKUP interface ens3 # Interfejs sieciowy, na którym działa Keepalived virtual_router_id 1 # Unikalny numer identyfikacyjny instancji VRRP priority 10 # Priorytet tego węzła (wyższa wartość oznacza wyższy priorytet) # Adresy virtual IP zarządzane przez Keepalived virtual_ipaddress { 10.225.38.38 } # Śledzenie stanu NGINX za pomocą skryptu track_script { check_nginx # Śledzenie skryptu check_nginx } }
tworzymy skrypt monitorujący stan daemona Nginx
vim /bin/check_nginx.sh
zawartość:
#!/bin/sh if [ -z "`pidof nginx`" ]; then exit 1 fi
nadajemy uprawnienia dla skryptu oraz restartujemy keepalived
chmod 755 /bin/check_nginx.sh systemctl restart keepalived
2.3 Test
W pierwszej kolejności z naszego hosta sprawdzamy dostępność strony www
kamil@legion:~$ curl 10.225.38.38 primary
Teraz zasymulujmy awarię daemona Nginx na serwerze primary
:
ubuntu@primary:~# sudo systemctl stop nginx
Sprawdzamy czy keepalived przeniósł virtual IP
na serwer secondary
oraz czy strona www w dalszym ciągu działa.
root@secondary:~# ip a | grep ens3 2: ens3: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc fq_codel state UP group default qlen 1000 inet 10.225.38.57/24 metric 100 brd 10.225.38.255 scope global ens3 inet 10.225.38.38/32 scope global ens3
kamil@legion:~$ curl 10.225.38.38 secondary
UWAGI
1. Bezpieczeństwo
W celu zwiększenia bezpieczeństwa możemy włączyć autentykację pomiędzy węzłami w klastrze Keepalived.
Głównym celem opcji „authentication” jest zapewnienie, że tylko węzły z prawidłowymi poświadczeniami (hasłami) mogą komunikować się ze sobą w celu monitorowania stanu i obsługi klastra Keepalived.
W tym celu musimy dodać w pliku konfiguracyjnym wpis konfiguracyjny „authentication”:
authentication { auth_type PASS auth_pass your_password }
auth_type
Określa typ autentykacji. W przykładzie powyżej użyto autentykacji opartej na haśle (PASS), ale Keepalived obsługuje również inne metody autentykacji, takie jak SHA256, MD5, itp. Wybór metody zależy od preferencji i wymagań bezpieczeństwa.auth_pass
Jest to właściwe hasło lub klucz autentykacyjny, który musi być wspólny dla wszystkich węzłów w klastrze. To hasło lub klucz jest wykorzystywane do uwierzytelnienia węzłów w trakcie wymiany informacji i monitorowania stanu.
2. Firewall
Jeśli mamy włączony firewall musimy dodać reguły przepuszczające ruch VRRP. W przypadku UFW:
# Na sererze primary ufw allow to 10.225.38.57 comment 'VRRP' ufw allow from 10.225.38.57 comment 'VRRP' # Na serwerze secondary ufw allow to 10.225.38.46 comment 'VRRP' ufw allow from 10.225.38.46 comment 'VRRP'
3. IPVS
W przypadku konfiguracji Keepalived do równoważenia obciążenia z wykorzystaniem protokołu IPVS (IP Virtual Server), konieczne może być ręczne załadowanie modułu ip_vs na serwerze. Moduł ten umożliwia jądro Linux obsługę mechanizmu równoważenia obciążenia IPVS. Na obydwu serverach ładujemy moduł:
echo "modprobe ip_vs" >> /etc/modules modprobe ip_vs
4. tcpdump
Ruch sieciowy VRRP możemy obserowować za pomocą narzędzia tcpdump:
tcpdump -v -i ens3 host 10.225.38.57
5. Szybkie środowisko testowe
W cel przygotowania szybkiego środowiska testowego na naszym komputerze z Ubuntu możemy użyć Multipass’a. Multipass to narzędzie w systemie Ubuntu, które umożliwia szybkie i łatwe tworzenie oraz zarządzanie wirtualnymi maszynami w środowisku Linux na komputerze osobistym.
snap install multipass multipass launch --name=primary multipass launch --name=secondary