W poprzedniej Omówiliśmy podstawowe komponenty Service Mesh Istio, zapoznaliśmy się z systemem i odpowiedzieliśmy na najważniejsze pytania, które zazwyczaj pojawiają się na początku pracy z Istio. W tej części przyjrzymy się, jak zorganizować zbieranie informacji o śledzeniu w sieci.

Pierwszą myślą, która przychodzi wielu deweloperom i administratorom systemów na myśl przy słowach Service Mesh, jest śledzenie. I rzeczywiście, dodajemy do każdego węzła sieci specjalny serwer proxy, przez który przechodzi cały ruch TCP. Wydaje się, że teraz łatwo można przesyłać informacje o wszystkich interakcjach sieciowych. Niestety, w rzeczywistości pojawia się wiele niuansów, które należy uwzględnić. Przyjrzyjmy się im.
Mito numer jeden: możemy otrzymać dane o przejściach w sieci za darmo.
W rzeczywistości relatywnie za darmo możemy jedynie otrzymać połączone strzałkami węzły naszego systemu i ilość danych, która przechodzi między usługami (w zasadzie - tylko liczba bajtów w jednostce czasu). Jednak w większości przypadków nasze usługi komunikują się za pomocą jakiegoś protokołu warstwy aplikacji, takiego jak HTTP, gRPC, Redis itd. Oczywiście chcemy widzieć informacje o śledzeniu właśnie w tych protokołach, chcemy widzieć ilość zapytań, a nie ilość danych. Chcemy zrozumieć opóźnienia zapytań w naszym protokole. W końcu chcemy zobaczyć pełną drogę, jaką pokonuje zapytanie od wejścia do naszego systemu aż do uzyskania odpowiedzi przez użytkownika. Rozwiązanie tego problemu nie jest już takie proste.
Na początek przyjrzyjmy się, jak wygląda wysyłanie tracing spanów z perspektywy architektury w Istio. Jak pamiętamy z pierwszej części, Istio ma osobny komponent do zbierania telemetry, zwany Mixer. Jednak w bieżącej wersji 1.0.* wysyłka odbywa się bezpośrednio z serwerów proxy, a konkretnie z envoy proxy. Envoy proxy wspiera wysyłkę tracing spanów przez protokół zipkin „z pudełka”. Inne protokoły można podłączyć, ale tylko za pomocą wtyczki. Z Istio od razu otrzymujemy skonfigurowany envoy proxy, w którym wspierany jest tylko protokół zipkin. Jeśli chcemy używać na przykład protokołu Jaeger i wysyłać tracing spany przez UDP, będziemy musieli zbudować własny obraz istio-proxy. Wsparcie dla niestandardowych wtyczek dla istio-proxy jest dostępne, jednak wciąż jest w wersji alfa. Dlatego, jeśli chcemy obejść się bez wielu niestandardowych ustawień, krąg używanych technologii do przechowywania i odbierania tracing spanów się zmniejsza. Z podstawowych systemów aktualnie można użyć samego Zipkin lub Jaeger, ale wysyłać do nich wszystko w protokole zgodnym z zipkin (co jest znacznie mniej efektywne). Sam protokół zipkin zakłada wysyłanie wszystkich informacji tracingowych do kolektorów przez protokół HTTP, co jest dość kosztowne.
Jak już powiedziałem, chcemy śledzić protokoły warstwy aplikacji. Oznacza to, że serwery proxy, które stoją obok każdego serwisu, muszą rozumieć, jakie interakcje mają miejsce w danym momencie. Domyślnie Istio konfiguruje dla wszystkich portów typ plain TCP, co oznacza, że żadne trace nie będą wysyłane. Aby trace’y były wysyłane, trzeba, po pierwsze, włączyć tę opcję w głównym konfigu mesh, a co bardzo ważne, odpowiednio nazwać wszystkie porty w zasobach service kubernetes zgodnie z protokołem używanym w serwisie. Na przykład, w ten sposób:
apiVersion: v1
kind: Service
metadata:
name: nginx
spec:
ports:
- port: 80
targetPort: 80
name: http
selector:
app: nginxMożna również używać złożonych nazw, na przykład http-magic (Istio dostrzeże http i rozpozna ten port jako punkt końcowy http). Format jest taki: proto-extra.
Aby nie patcheć ogromnej ilości konfiguracji w celu określenia protokołu, można skorzystać z brudnego workarounda: przełatać komponent Pilot w momencie, gdy właściwie Ostatecznie, oczywiście, będzie trzeba zmienić tę logikę na standardową i przejść na konwencję nazewnictwa wszystkich portów.
Aby naprawdę zrozumieć, czy protokół jest prawidłowo zdefiniowany, musisz wejść do dowolnego z kontenerów sidecar z envoy proxy i wykonać zapytanie do portu interfejsu administracyjnego envoy pod adresem /config_dump. W uzyskanej konfiguracji trzeba sprawdzić pole operation dla odpowiedniej usługi. Jest ono używane w Istio jako identyfikator miejsca, dokąd kierowane jest zapytanie. Aby dostosować w Istio wartość tego parametru (będziemy go później widzieć w naszym systemie śledzenia), należy przy uruchamianiu kontenera sidecar wskazać flagę serviceCluster. Na przykład, można ją obliczać w ten sposób z zmiennych uzyskanych z downward API kubernetes:
--serviceCluster ${POD_NAMESPACE}.$(echo ${POD_NAME} | sed -e 's/-[a-z0-9]*-[a-z0-9]*$//g')
Dobrym przykładem na zrozumienie, jak działa śledzenie w envoy, jest .
Sam punkt końcowy do wysyłania tracing spanów również należy określić w flagach uruchamiania envoy proxy, na przykład: --zipkinAddress tracing-collector.tracing:9411
Mit numer dwa: możemy tanio uzyskać pełne ślady przepływu zapytań przez system prosto z pudełka.
Niestety, to nieprawda. Złożoność wdrożenia zależy od tego, w jaki sposób już zrealizowane jest interakcja usług. Dlaczego tak?
Chodzi o to, że aby istio-proxy mogło zrozumieć, które przychodzące zapytania do usługi odpowiadają wychodzącym z tej samej usługi, nie wystarczy po prostu przechwytywać cały ruch. Musisz mieć jakiś identyfikator powiązania. W HTTP envoy proxy używa specjalnych nagłówków, według których envoy rozumie, które konkretne zapytanie do usługi generuje konkretne zapytania do innych usług. Lista takich nagłówków:
- x-request-id,
- x-b3-traceid,
- x-b3-spanid,
- x-b3-parentspanid,
- x-b3-sampled,
- x-b3-flags,
- x-ot-span-context.
Jeśli masz jednolitą punkt, na przykład bazowego klienta, w którym można dodać taką logikę, to wszystko jest świetnie, musisz tylko poczekać na aktualizację tej biblioteki u wszystkich klientów. Ale jeśli masz bardzo heterogeniczny system i nie ma ujednolicenia w przechodzeniu z usług do usług w sieci, to najprawdopodobniej będzie to duży problem. Bez dodania podobnej logiki wszystkie informacje śledzenia będą jedynie "jednopoziomowe". To znaczy, dostaniemy wszystkie interakcje między usługami, ale nie będą one połączone w jedną sieć przepływową.
Podsumowanie
Istio oferuje wygodne narzędzie do zbierania informacji o tracingu w sieci, jednak należy mieć na uwadze, że wprowadzenie go wymaga dostosowania systemu i uwzględnienia specyfiki implementacji Istio. W efekcie należy rozwiązać dwa podstawowe zagadnienia: określenie protokołu warstwy aplikacji (który musi być obsługiwany przez envoy proxy) oraz skonfigurowanie przekazywania informacji o związku zapytań w usługach (za pomocą headerów, w przypadku protokołu HTTP). Gdy te kwestie zostaną rozwiązane, uzyskujemy potężne narzędzie, które pozwala na przejrzyste zbieranie informacji w sieci, nawet w bardzo heterogenicznych systemach napisanych w wielu różnych językach i frameworkach.
W następnym artykule o Service Mesh omówimy jeden z największych problemów Istio – duże zużycie pamięci RAM przez każdy kontener proxy sidecar i przedyskutujemy, jak można z nim walczyć.
Źródło: habr.com
