Notatka. przeł.: Pierwsza część Ta seria była poświęcona wprowadzeniu możliwości Istio i zademonstrowaniu ich w działaniu. Teraz porozmawiamy o bardziej złożonych aspektach konfiguracji i wykorzystania tej siatki usług, a w szczególności o precyzyjnie dostrojonym routingu i zarządzaniu ruchem sieciowym.
Przypominamy również, że w artykule wykorzystano konfiguracje (manifesty dla Kubernetes i Istio) z repozytorium istio-mistrzostwo.
Zarządzanie ruchem
Dzięki Istio w klastrze pojawiają się nowe możliwości, które zapewniają:
Równoważenie obciążenia: prosty i spójny, oparty na skrótach;
Regeneracja po upadkach: przekroczenia limitu czasu, ponowne próby, wyłączniki automatyczne;
Wstawianie usterek: opóźnienia, odrzucone żądania itp.
W dalszej części artykułu możliwości te będą ilustrowane na przykładzie wybranej aplikacji, przy okazji wprowadzane będą nowe koncepcje. Pierwszą taką koncepcją będzie DestinationRules(tj. zasady dotyczące odbiorcy ruchu/żądań – ok. tł.), za pomocą którego uruchamiamy testy A/B.
Testy A/B: DestinationRules w praktyce
Testy A/B stosujemy w przypadku, gdy istnieją dwie wersje aplikacji (zwykle różnią się one wizualnie) i nie jesteśmy w 100% pewni, która z nich poprawi komfort użytkowania. Dlatego uruchamiamy obie wersje jednocześnie i zbieramy metryki.
Aby wdrożyć drugą wersję frontendu, wymaganą do zademonstrowania testów A/B, uruchom następującą komendę:
$ kubectl apply -f resource-manifests/kube/ab-testing/sa-frontend-green-deployment.yaml
deployment.extensions/sa-frontend-green created
Manifest wdrożenia wersji zielonej różni się w dwóch miejscach:
Obraz jest oparty na innym tagu - istio-green,
Strąki mają etykietę version: green.
Ponieważ oba wdrożenia mają etykietę app: sa-frontend,żądania kierowane przez usługę wirtualną sa-external-services Do obsługi sa-frontend, zostanie przekierowany do wszystkich swoich instancji, a obciążenie zostanie rozłożone algorytm okrężny, co doprowadzi do następującej sytuacji:
Nie znaleziono żądanych plików
Pliki te nie zostały znalezione, ponieważ mają różne nazwy w różnych wersjach aplikacji. Upewnijmy się co do tego:
Oznacza to, że index.html, żądając jednej wersji plików statycznych, może zostać przesłane przez moduł równoważenia obciążenia do podów mających inną wersję, gdzie z oczywistych powodów takie pliki nie istnieją. Dlatego aby aplikacja działała musimy ustawić ograniczenie: „ta sama wersja aplikacji, która obsługiwała plik Index.html, powinna obsługiwać kolejne żądania".
Osiągniemy to dzięki spójnemu równoważeniu obciążenia w oparciu o skróty (Spójne równoważenie obciążenia skrótu). W tym przypadku żądania od tego samego klienta są wysyłane do tej samej instancji zaplecza, dla którego używana jest predefiniowana właściwość - na przykład nagłówek HTTP. Zaimplementowano przy użyciu DestinationRules.
Regulamin miejsca docelowego
Później Usługa wirtualna wysłał żądanie do żądanej usługi, za pomocą DestinationRules możemy zdefiniować polityki, które będą stosowane do ruchu kierowanego do instancji tej usługi:
Zarządzanie ruchem za pomocą zasobów Istio
Operacja: Wpływ zasobów Istio na ruch sieciowy przedstawiono tutaj w łatwy do zrozumienia sposób. A konkretnie decyzję do której instancji wysłać żądanie podejmuje Envoy w skonfigurowanym w CRD Ingress Gateway.
Dzięki regułom docelowym możemy skonfigurować równoważenie obciążenia, aby używać spójnych skrótów i mieć pewność, że ta sama instancja usługi odpowiada temu samemu użytkownikowi. Poniższa konfiguracja pozwala to osiągnąć (Destinationrule-sa-frontend.yaml):
Operacja: Aby dodać różne wartości w nagłówku i przetestować wyniki bezpośrednio w przeglądarce, możesz użyć to rozszerzenie do Chrome (or z tym dla Firefoksa – ok. tłumacz.).
Generalnie DestinationRules ma więcej możliwości w obszarze równoważenia obciążenia - szczegóły znajdziesz w oficjalna dokumentacja.
Zanim dokładniej przestudiujemy VirtualService, usuńmy „zieloną wersję” aplikacji i odpowiadającą jej regułę kierunku ruchu, uruchamiając następujące polecenia:
Cieniowanie ("zastawianie") lub Odbicie lustrzane („odbicie lustrzane”) stosowane w przypadkach, gdy chcemy przetestować zmianę w produkcji bez wpływu na użytkowników końcowych: w tym celu duplikujemy („kopiujemy”) żądania do drugiej instancji, w której wprowadzono pożądane zmiany i sprawdzamy konsekwencje. Mówiąc najprościej, ma to miejsce wtedy, gdy Twój współpracownik wybiera najbardziej krytyczny problem i wysyła prośbę o ściągnięcie w postaci tak ogromnej bryły brudu, że nikt nie jest w stanie jej sprawdzić.
Aby przetestować ten scenariusz w działaniu, utwórzmy drugą instancję SA-Logic z błędami (buggy), uruchamiając następujące polecenie:
$ kubectl apply -f resource-manifests/kube/shadowing/sa-logic-service-buggy.yaml
deployment.extensions/sa-logic-buggy created
A teraz uruchommy polecenie, aby upewnić się, że wszystkie instancje z app=sa-logic Mają także etykiety z odpowiednimi wersjami:
Gospodarz (host) określa, że zasada ta ma zastosowanie jedynie w przypadkach, gdy trasa biegnie w stronę serwisu sa-logic;
Tytuły (name) podzbiory są używane podczas routingu do instancji podzbiorów;
Etykieta (label) definiuje pary klucz-wartość, które muszą pasować do instancji, aby stać się częścią podzbioru.
Zastosuj konfigurację za pomocą następującego polecenia:
$ kubectl apply -f resource-manifests/istio/shadowing/sa-logic-subsets-destinationrule.yaml
destinationrule.networking.istio.io/sa-logic created
Teraz, gdy podzbiory są już zdefiniowane, możemy przejść dalej i skonfigurować usługę VirtualService tak, aby stosowała reguły do żądań kierowanych do sa-logic, tak aby:
Nie ma tu potrzeby wyjaśniania, więc zobaczmy to w akcji:
$ kubectl apply -f resource-manifests/istio/shadowing/sa-logic-subsets-shadowing-vs.yaml
virtualservice.networking.istio.io/sa-logic created
Dodajmy obciążenie wywołując następującą komendę:
$ while true; do curl -v http://$EXTERNAL_IP/sentiment
-H "Content-type: application/json"
-d '{"sentence": "I love yogobella"}';
sleep .8; done
Przyjrzyjmy się wynikom w Grafanie, gdzie widać, że wersja z błędami (buggy) skutkuje niepowodzeniem w przypadku ~60% żądań, ale żadna z tych awarii nie ma wpływu na użytkowników końcowych, ponieważ odpowiada na nie działająca usługa.
Pomyślne odpowiedzi różnych wersji usługi sa-logic
Tutaj po raz pierwszy zobaczyliśmy, jak VirtualService jest stosowany wobec Posłów naszych usług: kiedy sa-web-app zwraca się z prośbą sa-logic, przechodzi przez usługę Sidecar Envoy, która — za pośrednictwem usługi VirtualService — jest skonfigurowana tak, aby kierować żądanie do podzbioru v1 i odzwierciedlać żądanie do podzbioru v2 usługi sa-logic.
Wiem, możesz już myśleć, że usługi wirtualne są proste. W następnej sekcji rozwiniemy tę kwestię, stwierdzając, że są one również naprawdę świetne.
Wdrożenia Kanaryjskie
Canary Deployment to proces wdrażania nowej wersji aplikacji dla małej liczby użytkowników. Służy do upewnienia się, że w wydaniu nie ma żadnych problemów i dopiero wtedy, mając już pewność co do jego jakości (wydania), rozpowszechnia się go wśród innych użytkowników.оwiększa publiczność.
Aby zademonstrować wdrożenia Canary, będziemy kontynuować pracę z podzbiorem buggy у sa-logic.
Nie traćmy czasu na drobnostki i od razu odsyłajmy 20% użytkowników do wersji z błędami (będzie to reprezentować nasz kanarekowy rollout), a pozostałe 80% do normalnej usługi. Aby to zrobić, użyj następującej usługi wirtualnej (sa-logic-subsets-canary-vs.yaml):
... i od razu zobaczymy, że niektóre żądania prowadzą do niepowodzeń:
$ while true; do
curl -i http://$EXTERNAL_IP/sentiment
-H "Content-type: application/json"
-d '{"sentence": "I love yogobella"}'
--silent -w "Time: %{time_total}s t Status: %{http_code}n"
-o /dev/null; sleep .1; done
Time: 0.153075s Status: 200
Time: 0.137581s Status: 200
Time: 0.139345s Status: 200
Time: 30.291806s Status: 500
Usługi wirtualne umożliwiają wdrażanie rozwiązań typu canary: w tym przypadku zawęziliśmy potencjalny wpływ problemów do 20% bazy użytkowników. Wspaniały! Teraz w każdym przypadku, gdy nie jesteśmy pewni naszego kodu (czyli zawsze...), możemy zastosować Mirroring i Canary Rollouts.
Przekroczenia limitu czasu i ponowne próby
Ale błędy nie zawsze kończą się w kodzie. Na liście z „8 błędnych przekonań na temat przetwarzania rozproszonego„Na pierwszym miejscu znajduje się błędne przekonanie, że „sieć jest niezawodna”. W rzeczywistości sieć nie niezawodne i z tego powodu potrzebujemy limitów czasu (przekroczenia limitu czasu) i ponawia próby (próby).
W celach demonstracyjnych będziemy nadal używać tej samej wersji problemu sa-logic (buggy), a my będziemy symulować zawodność sieci z przypadkowymi awariami.
Niech nasza usługa z błędami ma 1/3 szansy, że odpowiedź zajmie zbyt dużo czasu, 1/3 szansy, że zakończy się wewnętrznym błędem serwera i 1/3 szansy na pomyślne zwrócenie strony.
Aby złagodzić skutki takich problemów i poprawić życie użytkowników, możemy:
dodaj timeout, jeśli reakcja usługi trwa dłużej niż 8 sekund,
spróbuj ponownie, jeśli żądanie nie powiedzie się.
Limit czasu dla żądania jest ustawiony na 8 sekund;
Żądania są ponawiane 3 razy;
Każdą próbę uważa się za nieudaną, jeżeli czas odpowiedzi przekracza 3 sekundy.
Jest to optymalizacja, ponieważ użytkownik nie będzie musiał czekać dłużej niż 8 sekund, a w przypadku awarii podejmiemy trzy nowe próby uzyskania odpowiedzi, zwiększając szansę na pomyślną reakcję.
Zastosuj zaktualizowaną konfigurację za pomocą następującego polecenia:
I sprawdź na wykresach Grafana, czy liczba pomyślnych odpowiedzi wzrosła powyżej:
Ulepszenia statystyk pomyślnych odpowiedzi po dodaniu przekroczeń limitu czasu i ponownych prób
Zanim przejdziesz do następnej sekcji (a raczej do dalszej części artykułu, bo w tym nie będzie już praktycznych eksperymentów - ok. tł.), usuwać sa-logic-buggy i VirtualService, uruchamiając następujące polecenia:
Mówimy o dwóch ważnych wzorcach w architekturze mikrousług, które pozwalają na samoodzyskiwanie (samo leczenie) usługi.
Wyłącznik obwodu("wyłącznik obwodu") służy do kończenia żądań przychodzących do wystąpienia usługi uważanej za niezdrową i przywracania jej, podczas gdy żądania klientów są przekierowywane do prawidłowych wystąpień tej usługi (co zwiększa procent pomyślnych odpowiedzi). (Uwaga: Bardziej szczegółowy opis wzoru można znaleźć np. tutaj.)
Przegroda("przegroda") izoluje awarie usług od wpływu na cały system. Na przykład usługa B jest uszkodzona i inna usługa (klient usługi B) wysyła żądanie do usługi B, powodując wyczerpanie jej puli wątków i brak możliwości obsługi innych żądań (nawet jeśli nie pochodzą one z usługi B). (Uwaga: Bardziej szczegółowy opis wzoru można znaleźć np. tutaj.)
Pominę szczegóły implementacji tych wzorców, ponieważ łatwo je znaleźć oficjalna dokumentacja, a bardzo chcę też pokazać uwierzytelnianie i autoryzację, o czym będzie mowa w dalszej części artykułu.