Od wielu lat w Onecie do balansowania ruchu używamy LVS, będącego najbardziej wydajnym softwareowym rozwiązaniem tego typu. W dużym skrócie jego działanie polega na wystawieniu wirtualnego adresu IP oraz portu i przekazywanie tak nadchodzącego ruchu sieciowego do faktycznie obsługujących go serwerów (tzw reali).

LVS nie wie nic na temat stanu serwerów do których przekazuje ruch, dlatego też do współpracy z nim zaprzęga się rozwiązania testujące. W zależności od ilości serwerów do przetestowania mogą być to zwykłe skrypty w shellu, Perlu lub innych językach programowania. Jeśli jednak tych serwerów są dziesiątki albo nawet setki, bardzo powoli następuje wypięcie niedziałającego poprawnie serwera. Zakładając, że skrypt testujący przeznacza kilka sekund na przetestowanie danego reala a pętla idzie iteracyjnie, wypięcie serwera z LVS może nastąpić po kilku lub kilkunastu minutach. W międzyczasie LVS, jako nieświadomy uszkodzenia jednego z serwerów do których przekazuje ruch (działa on na zupełnie innej warstwie sieciowej), uparcie kieruje tam połączenia. Objawia się to zwolnieniem ładowania strony lub pewnych elementów które tam występują (np obrazków).

Początkowo do sprawdzania poprawności działania serwerów używaliśmy duetu mon + heartbeat. Pierwszy z nich jest skryptem w Perlu, ułatwiającym testowanie reali. Heartbeat z kolei pozwala na przeniesienie adresów pomiędzy LVSami zapewniając failover w przypadku awarii jednego z nich (w szczególności tego, który aktualnie obsługuje ruch).
Mon zapewnia skalowalność odwrotną proporcjonalnie do funkcjonalności. Dlatego rozpoczęliśmy poszukiwanie aplikacji, która w krótszym czasie przetestuje serwery i skonfiguruje je na LVSie. Spośród aplikacji opensource wybór był niewielki, jedynie keepalived mógł sprostać naszym wymaganiom. Napisany w C zawiera implementację VRRP (do przenoszenia adresów wirtualnych pomiędzy LVSami) a także wydajny tester reali. Po jakimś czasie jego użytkowania stwierdziliśmy, że pewne błędy a także braki funkcjonalne motywują nas do dalszych poszukiwań. Niestety, poza keepalived nie było w świecie opensource innej, podobnie działającej, wydajnej aplikacji testującej serwery. Zrodził się pomysł napisania czegoś ”pod nas”. W związku z tym, że VRRP w keepalived działa wg nas zadowalająco potrzebowaliśmy napisać jedynie tester usług.

Założenia projektu

Początkowo powstał ogólny szkic programu. Zawierał on następujące kluczowe elementy:

  • Aplikacja podzielona będzie na 2 niezależnie działające moduły – tester usług oraz synchronizator zapisujący stan do LVS.
  • Możliwy będzie restart dowolnej z w/w aplikacji (w keepalived nie jest to bezproblemowe i powoduje wyczyszczenie konfiguracji LVSa).
  • Możliwe będzie przetestowanie poprawności składni konfiguracji testera i synchronizatora.
  • Aplikację da się rozszerzać poprzez ładowane dynamicznie moduły testujące.
  • Tester umożliwi zapis statystyk (czasów połączeń oraz odpowiedzi poszczególnych usług).
  • Możliwa będzie zmiana wagi dowolnego serwera lub jego wpięcie/wypięcie z LVS bez konieczności przeładowania całej konfiguracji.

Założenia zostały spełnione w całości, dodatkowo w trakcie implementacji dołożyliśmy inne, ważne dla nas elementy aplikacji.

Realizacja

Na początku powstała łatwiejsza część projektu czyli synchronizator. Tester rozwijał się bardzo powoli, do momentu, gdy w ramach praktyk studenckich w DreamLabie dołączył do mnie Bartek Ponurkiewicz, entuzjasta niskopoziomowego programowania w C. Po miesiącu wytężonej pracy, niejednokrotnie przeplatanej burzą mózgów różnych osób, zaczął działać spełniający nasze wymagania program. Zanim jednak ujrzał światło dzienne minął kolejny miesiąc w czasie którego to testowaliśmy go i usuwaliśmy napotkane w nim błędy.

Implementacja

Ze względu na błędy w keepalived nieco przekornie nazwaliśmy naszą aplikację surealived. Błędy te objawiają się po wielokrotnych przeładowaniach keepalived, skutkując np tym, że w LVS pozostają wpięte serwery, niejednokrotnie wyłączone lub niepoprawnie działające.
Jak wspomniałem wcześniej implementacja zawiera dwie aplikacje – surealived jako tester usług oraz ipvssync jako synchronizator zmian w LVS. Zmiany w testowanej przez surealived infrastrukturze usług są przekazywane poprzez pliki zmian do synchronizatora ipvssync.

By ponownie nie wynajdować koła skorzystaliśmy z gotowych już bibliotek takich jak:

  • libglib2 – do struktur danych – hashy, tablic, itp.,
  • libxml2 – do rozparsowania konfiguracji xml,
  • libssl — do obsługi połączeń SSLowanych.

Do wsparcia konfiguracji / kompilacji użyliśmy dynamicznie rozwijającego się cmake, ułatwiającego znacznie wykrycie wymaganego do budowy aplikacji oprogramowania.

Charakterystyka aplikacji

By nie rozwodzić się zbytnio w tabeli zebrałem najważniejsze cechy keepalived i surealived.

Zainteresowanych odsyłamy do strony projektu:
http://sourceforge.net/projects/surealived/

Zbigniew Kempczyński
Starszy Administrator Systemów Unix