Mikroserwisy – Service Mesh z Istio

Dawid Wieczorek | Rozwój oprogramowania | 22.09.2021

Jednym z wyzwań dynamicznej architektury mikroserwisowej jest tworzenie i utrzymywanie połączeń pomiędzy jej elementami. Poszczególne serwisy mogą być dynamicznie dodawane, aktualizowane i usuwane, dodatkowo każdy z nich może być zeskalowany do wielu instancji, niekoniecznie w tej samej wersji aplikacji. Niewątpliwie poziom skomplikowania wymusza potrzebę posiadania mechanizmu, który pozwoli uprościć warstwę komunikacji i zdejmie z developerów większość ciężaru wiążącego się z pracą w tym środowisku. Jednym z takich mechanizmów jest Service Mesh, w którym wykorzystany jest tzw. wzorzec sidecar, czyli element proxy przypięty do każdego kontenera aplikacji. Razem proxy obsługują komunikację w klastrze Kubernetesa, tworząc siatkę. Mechanizm siatki pozwala na optymalizację wydajności sieci, ułatwia jej zabezpieczenie oraz umożliwia monitorowanie ruchu. W poprzednim artykule znajdziecie więcej szczegółów na temat Service Mesh, a w tym artykule bliżej przyjrzyjmy się Istio i możliwościom, jakie daje.

Czym jest Istio

Istio jest implementacją koncepcji Service Mesh, projektem open-source, stworzonym przez zespół Google i IBM we współpracy z zespołem Envoy z firmy Lyft. Istio wykorzystuje sprawdzone proxy Envoya, aby zapewnić korzyści oferowane przez takie podejście do warstwy sieci w klastrze. Główne zalety to: dodanie podstawowej konfiguracji, która dostarcza połączenie sieciowe, oraz zabezpieczenie i monitorowanie istniejących serwisów bez zmian w kodzie istniejących aplikacji.

Kubernetes – Istio: jak to działa razem?

Istio w ekosystemie Kubernetesa dzieli się na dwa komponenty: data plane i control plane.

Istio Service Mesh

Data plane to kolektywna nazwa dla wszystkich proxy Envoy, przez które przechodzi komunikacja w klastrze. Proxy przechwytują cały ruch sieciowy i nakładają na niego reguły dostarczone przez nas w konfiguracji. Niektóre z możliwości, jakie daje nam Istio z wykorzystaniem Envoya:

  • Szczegółowa kontrola ruchu sieciowego za pomocą zasad routingu dla HTTP, gRCP, WebSocket oraz pakietów TCP.
  • Odporność na problemy w funkcjonowaniu sieci, takie jak retry, failovers i circut breakery.
  • Zabezpieczenie sieci za pomocą polityk bezpieczeństwa oraz limitowanie obciążenia kontrolowane konfiguracyjnie.

Control plane (Istiod) to zestaw komponentów, które dynamicznie zarządzają działaniem naszego Service Mesh. Poszczególne komponenty są odpowiedzialne za:

  • Service discovery i load balancing (Istio utrzymuje tzw. service registry, dzięki któremu proxy Envoya mogą kierować ruchem i rozkładać obciążenie sieciowe na wiele instancji serwisów).
  • Konfigurację routingu z poziomu plików konfiguracyjnych, które są tłumaczone i następnie propagowane do niskopoziomowego API Envoya.
  • Obsługę bezpieczeństwa komunikacji wewnątrz klastra za pomocą mTSL oraz zarządzanie certyfikatami dla tejże komunikacji.

Co dostajemy prosto z pudełka

Instalację Istio możemy rozpocząć od wykorzystania jednego z przygotowanych profili konfiguracji, a następnie wprowadzać dodatkowe zmiany adekwatnie do naszych potrzeb.

Na początek najlepiej jest skorzystać z profilu domyślnego, który poza bazową konfiguracją control planeproxy dostarcza dodatkowo komponent istio-ingressgateway. Pozwala nam on na monitorowanie i kontrolę ruchu sieciowego wchodzącego do wewnątrz klastra Kubernetesa.

Istio

W bazowej instalacji, bez jakichkolwiek dodatkowych zmian, otrzymujemy w pakiecie możliwości monitorowania ruchu w klastrze, automatycznie zbierane są również metryki (takie jak liczba oraz czas zapytań i odpowiedzi). Jednocześnie możemy też śledzić każde zapytanie skierowane do klastra, jak również wykrywać problemy w komunikacji, takie jak wąskie gardła lub zwiększenie błędnych odpowiedzi z jednego z mikroserwisów.

Istio Service Mesh zarządzanie ruchem sieciowym

Dodatkowo cały ruch sieciowy wewnątrz klastra jest automatycznie szyfrowany z użyciem mechanizmu mTLS, czyli wzajemnego uwierzytelniania mikroserwisów za pomocą certyfikatów X.509, których zarządzaniem również zajmuje się Istio.

Istio Service Mesh

Jak widać, sporo zyskujemy już przez samo użycie Istio, bez jakichkolwiek dodatkowych konfiguracji z naszej strony. Jednak przy niewielkim wysiłku wykorzystanie Istio otwiera przed nami bardzo dużo dodatkowych możliwości. Poniżej opiszę jedną z nich.

Przykład użycia Istio – zarządzanie ruchem sieciowym

Załóżmy, że pracujemy nad aplikacją złożoną z kilku aplikacji, której architekturę przedstawiono na poniższym schemacie.

Istio Mesh

W szczególności zwróćmy uwagę, że zainstalowano trzy wersje serwisu ‘review’, chociaż na ten moment wydaje się, że ruch sieciowy trafia tylko do wersji v1.

JPro 2021.09.22 obraz5 - Mikroserwisy – Service Mesh z Istio

Konfiguracja Istio potwierdza, że tylko wersja v1 może przyjmować zapytania z serwisu productpage. Załóżmy dodatkowo, że nieużywany na ten moment moduł ratings służy do  nowej funkcjonalności, dostępnej dopiero od v2 usługi reviews. Jeśli w ten sytuacji chcielibyśmy skierować część zapytań (w naszej konfiguracji 10%) do nowej wersji usługi (tzw. canary deployment), możemy to zrobić za pomocą niewielkiej modyfikacji istniejącej konfiguracji.

Istio Mesh

Efekt takiej zmiany na ruch sieciowy w naszej aplikacji wygląda następująco:

JPro 2021.09.22 obraz7 - Mikroserwisy – Service Mesh z Istio

Jak widać, około 10% ruchu do serwisu reviews trafia teraz do wersji v2, która prawidłowo komunikuje się z serwisem ratings. Kolejnymi krokami mogłyby być monitorowanie nowych usług i stopniowe manipulowanie wagami aż do ostatecznego całkowitego przejścia na nową wersję funkcjonalności.

Zwróćmy jednak uwagę, że ruch sieciowy w poprzednim przykładzie był kierowany do konkretnych wersji serwisu reviews losowo, tym samym nie mamy kontroli nad tym, pod jakim warunkiem lub dla jakiego użytkownika nowa funkcjonalność będzie dostępna.

W kolejnym przykładzie chcemy udostępnić dla użytkowników aplikacji możliwość wzięcia udziału w testowaniu nowej funkcjonalności. Wiąże się to z kierowaniem wybranej części ruchu sieciowego do nowej usługi na podstawie atrybutu zapytań HTTP. W realizacji tego zadania pomoże nam dodawanie niestandardowego headera do wszystkich zapytań (np. x-beta) i kierowanie ruchem na jego podstawie.

Istio

Taka prosta zmiana w naszej początkowej konfiguracji pozwala na zrealizowanie opisanego wymagania.

Alternatywnym podejściem do powyższej sytuacji, zmniejszającym ryzyko nieprawidłowego działania nowej funkcjonalności, jest wykorzystanie mechanizmu traffic mirroring. W tej konfiguracji decydujemy się kierować cały ruch sieciowy do stabilnej wersji v1, jednocześnie wysyłając kopię całego ruchu do wersji v2, która w tym momencie jest niedostępna dla użytkowników, ale możliwa jest analiza i testowanie niesprawdzonej wersji w środowisku produkcyjnym.

Poniższa konfiguracja umożliwia opisany wyżej traffic mirroring:

JPro 2021.09.22 obraz9 - Mikroserwisy – Service Mesh z Istio

W tej konfiguracji 100% ruchu jest skierowane do wersji v1, jednocześnie 100% ruchu jest też kierowane do v2, z tym że użytkownik otrzyma odpowiedź zawsze ze stabilnej wersji serwisu. Możemy oczywiście kontrolować ilość ruchu odbijanego w stronę v2 za pomocą parametru konfiguracji mirrorPercentage.

Istio Mesh

Podsumowanie

Istio to bardzo rozbudowane narzędzie, a opisane przykłady to tylko niewielka część jego dużo większych możliwości. I chociaż próg wejścia nie jest najmniejszy, to zdecydowanie jest warto ze względu na korzyści. Zdecydowanym ułatwieniem jest możliwość rozpoczęcia od domyślnej konfiguracji, która wymaga niewielu zmian w istniejącej aplikacji. Mam nadzieję, że ten artykuł zachęci was do wypróbowania Istio w waszych projektach.

Przeczytaj także: Mikroserwisy nowa jakość w międzynarodowych projektach IT