Cloud Native Applications – migracja aplikacji do chmury.

Cloud Native Applications

To dość popularne hasło, które pojawia się bardzo często przy dyskusjach związanych z chmurami. Co dokładnie kryje się pod tą definicją oraz jaka jest charakterystyka takich aplikacji, postaram się przybliżyć w dalszej części.

Trudne początki

Oczywiście, jak tylko uda już wam się przekonać zwierzchników do tego, że chmura jest najlepsza, że napędzi wasz biznes itp. itd., staniecie przed decyzją od czego zacząć? Które środowisko jako pierwsze zacząć przenosić. Jest to bardzo ważny moment, który może zaważyć o powodzeniu całego przedsięwzięcia. Założenie, że migracja do chmury to po prostu przeniesienie wirtualnych maszyn może być na tyle trafne jak założenie, że świnie całkiem przyzwoicie latają (RFC1925):

With sufficient thrust, pigs fly just fine. However, this is not necessarily a good idea. It is hard to be sure where they are going to land, and it could be dangerous sitting under them as they fly overhead.
Podobnie może być z waszą aplikacją, jest bardzo duże prawdopodobieństwa, że po przeniesieniu 1:1 będzie nadal działać w lepszym bądź gorszym skutkiem. Pytanie tylko, czy będzie w stanie wykorzystać możliwości jakie oferuje chmura, oraz czy będzie to korzystne kosztowo.

Tradycyjne aplikacje

Przyjrzyjmy się bliżej typowej architekturze aplikacji, często mówi się o tzw. architekturze 3-tier, w której jest warstwa webowa, czyli ten frontend który widzi klient no i warstwa aplikacyjna oraz warstwa bazodanowa. Czasem warstwa web i aplikacyjna realizowane są przez ten sam zestaw serwerów.
Oczywiście na brzegu bardzo często stoi jakichś loadbalancer, który “rozrzuca” ruch na wszystkie nody aplikacji. Dodatkowo niektóre aplikacje wymagają aby połączenia klientów przyklejane były do jednego noda na cały cykl trwania sesji (tzw. “persistent sticky”). Potrzeba taka pojawia się często przy serwisach sprzedażowych, gdzie np. mamy do czynienia z koszykiem zakupowym, bądź kilkustronicowymi formularzami, które klient musi wypełnić. Taki mechanizm dość łatwo rozwiązuje kwestie zapamiętanie tego co wprowadził klient, z drugiej strony jednak generuje sporo problemów np. z skalowalnością aplikacji, ponieważ informacje z danej sesji są tylko na jednym nodzie.

Sticky Session to zło!

Przyjmijmy założenie (mowa oczywiście o aplikacji już uruchomionej w chmurze), że w normalnym cyklu pracy mamy 3 nody aplikacyjne, które obsługują klientów.

W momencie kiedy dochodzi do wzrostu obciążenia, wtedy automatycznie (np. przy wykorzystaniu AutoScaling grupy w AWS) powoływane są nowe nody i dodawane do loadbalancera. Oczywiście każdy nowy klient zostanie skierowany na nowy serwer i tam obsłużony, co jednak z bieżącymi sesjami? Te nadal będą realizowane z lepszym bądź gorszym skutkiem na dotychczasowych serwerach ponieważ, zostali tam “przyklejeni”. W takiej sytuacji nie dojdzie do równomiernego rozłożenia ruchu, każdy klient będzie odczuwał inną “jakość” w działaniu aplikacji.

Kiedy ruch będzie spadał i nie będzie już wymagał tak dużej ilości nodów pojawia się kolejny problem. Który serwer z terminować jeśli na każdym są klienci? Zgaszenie któregokolwiek sprawi zerwanie sesji klientów do niego przypiętych, za czym idzie utracie danych z jego sesji.

Pytanie czy klient który wypełniał od 10 minut formularz na ubezpieczenie szybki swojego kochanego smartfona zrobi to jeszcze raz jak nagle dostanie ekran początkowy? Nie sądzę! Właśnie firma traci kolejnego klienta.

Zatem jeśli aplikacja działa w oparciu o persistent sticky z pewnością będzie miała problemy z dynamicznym skalowaniem się. Poza tym tego typu aplikacja będzie mało odporna na awarie (bo te zawsze były i będą). Pada np. jedno DC, padają nody, znikają dane o sesjach klientów. I klient znów ląduje na pierwszej stronie formularza…

Idąc dalej skoro serwer aplikacyjny przechowuje zestaw informacji, których nie posiadają inne to warto by było aby mógłbyć przenoszony np. przy wykorzystaniu vMotion. W tradycyjnym modelu Aplikacja i Serwer są ściśle ze sobą powiązane, dlatego oczekiwane jest jak najpewniejsze i stabilniejsze działanie serwera aplikacyjnego. Pomijając już kwestię tego co każdy sieciowiec może powiedzieć o rozciąganiu sieci L2 i problemach z tym związanymi, to sam fakt przenoszenia maszyn nie jest procesem z natury zbyt szybkim.

To jak to robić “po nowemu”

Aplikacje Cloud Native budowane są w zupełnie inny sposób. Przede wszystkim są “statelessowe”, ale w takim znaczeniu, że nie mamy tutaj przyklejania sesji użytkowników. Między innymi dzięki temu nie potrzebujemy wyuzdanych loadbalancerów, a jedynie prostych urządzeń pracujących w warstwie czwartej. Każdy request ze strony klienta jest wrzucany losowo na dowolnego noda, który współdzieli stany sesji z pozostałymi. Jest kilka dostępnych mechanizmów do współdzielenia takich informacji. W zależności od potrzeby może to być np. baza danych, Memcache lub jakichś zewnętrzny storage. Głównie chodzi oto, aby wszystko co istotne znajdowało się poza nodami aplikacji i było współdzielone.

W tradycyjnym modelu Aplikacja i Serwer są ściśle ze sobą powiązane, dlatego dąży się przede wszystkim do tego aby infrastruktura była bardzo stabilnym środowiskiem, które zapewnia wszelkie mechanizmy (jak np. vMotion) mające utrzymywać przy życiu serwery.

W podejściu Cloud Native, zakłada się, że infrastruktura może ulegać awariom. Dlatego w modelu tym dostarcza się mechanizmy wspomagające projektowanie aplikacji tak aby radziły sobie z tymi awariami. Głównym celem jest niezawodność aplikacji, a nie infrastruktury. Dodatkowo podejście takie daje duży benefit w postaci elastyczności. Dzięki temu, że aplikacja nie jest przywiązana do serwera, środowisko można bardzo łatwo skalować w górę i w dół, bez żadnych skutków ubocznych wpływających na klientów. Co na koniec też wpływa na koszty. Działając w modelu pay per use bardzo ważne jest aby korzystać tylko z tego co jest niezbędne.

Patrząc trochę już w sumie w teraźniejszość połączoną z niedaleką przyszłością, kolejnym korkiem na drodze ewolucji jest mikrosegmentacja, kontenery. Pomijając wszystkie inne udogodnienia tych rozwiązań dają one również elastyczność i skalowalność i w sumie jeszcze większą niezależność od tego na czym są uruchomione.

Podsumowując

Skoro już decydujecie się na krok pójścia w rozwiązania chmurowe zastanówcie się i uważnie przyjrzyjcie architekturze aplikacji która będziecie chcieli tam przenieść. Na ile będzie możliwe dostosowanie jej do nowych realiów.

Jeśli z kolei bierzecie się za tworzenie nowej aplikacji to już na starcie warto przyjąć założenia modelu Cloud Native.

Aplikacja działająca w modelu Cloud Native charakteryzuje przede wszystkim tym, że:

  • Nie wykorzystuje żadnych mechanizmów sticky.
  • Nie ma potrzeby jakiegokolwiek migrowania maszyn.
  • Stan sesji klientów jest współdzielony między wszystkimi nodami aplikacji.
  • Jest odporna na różne awarie infrastruktury.
  • Łatwo się skaluje.
    Temat, zwłaszcza migracji nie jest łatwy, ale może przynieść sporo korzyści jak np.:
  • wsparcie dla procesów continue update, continue delivery
  • szybka możliwość dostarczania to lepsza konkurencyjność w biznesie (przecież klient nie będzie czekał)
  • brak problemów z migracjami serwerów w szczególności na dużych odległościach.
  • łatwe skalowanie aplikacji w rozproszonych DCs.
    …a to tylko niektóre z nich.


Zbuduje swoje bezpieczne środowisko AWS.