Service Mesh: co każdy Software Engineer powinien wiedzieć o najmodniejszej technologii

Przyp. tłum.: Service mesh — zjawisko, które wciąż nie ma ustalonego tłumaczenia na język polski (ponad 2 lata temu zaproponowaliśmy „siatkę dla usług”, a nieco później niektórzy koledzy zaczęli promować termin „sito usługowe”). Ciągłe rozmowy na temat tej technologii doprowadziły do sytuacji, w której marketing i aspekty techniczne zbyt mocno się splatają. Ten znakomity materiał od jednego z autorów oryginalnego terminu ma na celu wprowadzenie jasności dla inżynierów i nie tylko.

Service Mesh: co każdy Software Engineer powinien wiedzieć o najmodniejszej technologii
Komiks od Sebastian Caceres

Wprowadzenie

Jeśli jesteś inżynierem oprogramowania pracującym w obszarze systemów backendowych, termin „service mesh” prawdopodobnie już na stałe zagościł w Twojej świadomości w ciągu ostatnich kilku lat. Dzięki dziwnemu zbiegu okoliczności, to wyrażenie zdobywa coraz większą popularność w branży, a związany z nim hype oraz propozycje reklamowe narastają jak śnieżna kula tocząca się z górki, nie dając żadnych oznak spowolnienia.

Service mesh narodziło się w mętnej, tendencyjnej wodzie ekosystemu cloud native. Niestety, oznacza to, że znaczna część związanej z nią debaty waha się od „mało znaczących rozmów” do — jeśli użyć technicznego terminu — jawnej bzdury. Ale jeśli odfiltrować cały hałas, można dostrzec, że service mesh ma całkiem realną, konkretną i ważną funkcję.

W tej publikacji postaram się właśnie to zrobić: przedstawić szczere, głębokie, skierowane do inżynierów przewodnik po service mesh. Zamierzam odpowiedzieć nie tylko na pytanie: „Co to jest?”, — ale także „Dlaczego?”, a także „Dlaczego teraz?”. Na koniec spróbuję nakreślić, dlaczego (moim zdaniem) ta technologia wywołała taki szalony hype, co samo w sobie jest ciekawą historią.

Kim jestem?

Cześć wszystkim! Nazywam się William Morgan. Jestem jednym z twórców Linkerd — pierwszego projektu service mesh oraz projektu, który jest odpowiedzialny za powstanie terminu service mesh jako takiego (przepraszam, chłopaki!). (Przykład tłum.: A propos, na początku powstania tego terminu, ponad 2,5 roku temu, tłumaczyliśmy wczesny materiał tego samego autora zatytułowany „Czym jest service mesh i dlaczego go potrzebuję [dla aplikacji w chmurze z mikroserwisami]?».) Również kieruję Buoyant — startupem, który tworzy fantastyczne rzeczy związane z service mesh, takie jak Linkerd i Dive.

Prawdopodobnie domyślasz się, że mam dość stronnicze i subiektywne zdanie na ten temat. Postaram się jednak zminimalizować subiektywność (z wyjątkiem jednej sekcji: „Dlaczego tak dużo mówi się o service mesh?”, w której podzielę się swoimi stronniczymi pomysłami). Dołożę również wszelkich starań, aby uczynić ten przewodnik jak najbardziej obiektywnym. W konkretnych przykładach będę w przeważającej części opierał się na doświadczeniach Linkerd, wskazując na znane mi różnice (jeśli takie istnieją) w implementacji innych typów service mesh.

Dobra, czas przejść do apetycznych szczegółów.

Czym jest service mesh?

Mimo całego szumu, strukturalnie service mesh jest dość prosta. To po prostu zestaw proxy przestrzeni użytkownika, rozmieszczonych „blisko” usług (później trochę porozmawiamy o tym, co oznacza „blisko”), oraz zestaw procesów zarządzających. Proxy zbiorczo nazywane są data plane, a procesy zarządzające określane są jako control plane. Data plane przechwytuje wywołania między usługami i wykonuje z nimi „różne rzeczy”; control plane odpowiednio koordynuje zachowanie proxy i zapewnia dostęp dla ciebie, tj. operatora, do API, umożliwiając manipulację siecią i pomiar jej jako całości.

Service Mesh: co każdy Software Engineer powinien wiedzieć o najmodniejszej technologii

Czym są te proxy? To TCP proxy klasy „Layer 7-aware” (tj. „uwzględniające” 7. warstwę modelu OSI) jak HAProxy i NGINX. Możesz wybrać proxy według własnych preferencji; Linkerd wykorzystuje proxy napisane w Rust, skromnie nazwanego linkerd-proxy. Zostało ono stworzone specjalnie dla service mesh. Inne sieci mesh preferują inne proxy (Envoy jest częstym wyborem). Niemniej jednak, wybór proxy to tylko kwestia implementacji.

Czym zajmują się te serwery proxy? Oczywiście, przekazują wywołania do usług i z nich (ściśle mówiąc, pełnią funkcję proxy i reverse proxy, obsługując zarówno przychodzące, jak i wychodzące wywołania). Realizują również zestaw funkcji, koncentrując się na wywołaniach między usługami. Ta koncentracja na ruchu między usługami odróżnia proxy service mesh od np. bram API lub proxy wejściowych (te ostatnie koncentrują się na wywołaniach przychodzących do klastra z zewnętrznego świata). (Przyp. tłum.: porównanie istniejących kontrolerów Ingress dla Kubernetes, z których wiele korzysta już z wymienionego Envoy, zobacz w w tym artykule.)

Zatem, jeśli chodzi o data plane, mamy to za sobą. Control plane jest prostsze: to zestaw komponentów, które zapewniają całą mechanikę potrzebną data plane do pracy w skoordynowany sposób, w tym wykrywanie usług, wydawanie certyfikatów TLS, agregację metryk itd. Data plane informuje control plane o swoim zachowaniu; w zamian control plane udostępnia API, które pozwala na zmianę i śledzenie zachowania data plane jako całości.

Poniżej przedstawiono schemat control plane i data plane w Linkerd. Jak widać, control plane składa się z kilku różnych komponentów, w tym instancji Prometheus, która zbiera metryki z serwerów proxy, oraz innych komponentów, takich jak destination (wykrywanie usług), identity (centrum certyfikacji, CA) i public-api (punkty końcowe dla web i CLI). W przeciwieństwie do tego, data plane to prosty linkerd-proxy obok instancji aplikacji. To tylko schemat logiczny; w rzeczywistości, podczas wdrażania, możesz mieć trzy repliki każdego komponentu control plane i setki lub tysiące proxy w data plane.

(Niebieskie prostokąty na tym schemacie symbolizują granice podów Kubernetes. Widać, że kontenery z linkerd-proxy znajdują się w tym samym podzie co kontenery aplikacji. Taki schemat zna się jako sidecar-kontener..)

Service Mesh: co każdy Software Engineer powinien wiedzieć o najmodniejszej technologii

Architektura service mesh ma kilka istotnych konsekwencji. Po pierwsze, ponieważ zadaniem proxy jest przechwytywanie wywołań między usługami, service mesh ma sens tylko wtedy, gdy twoja aplikacja została zbudowana na bazie zestawu usług. Mesh można nie jest używany z monolitami, ponieważ jest to wyraźnie zbędne dla jednego jedynego proxy, a jego funkcjonalność najprawdopodobniej nie będzie potrzebna.

Inną ważną konsekwencją jest to, że service mesh wymaga ogromnej liczby proxy. W rzeczywistości, Linkerd przyczepia linkerd-proxy do każdej instancji każdej usługi (inne realizacje dodają proxy do każdego węzła/gospodarza/maszyny wirtualnej. W każdym razie to nie mało). Tak intensywne użycie proxy niesie ze sobą szereg dodatkowych komplikacji:

  1. Proxy w data plane muszą być szybkie,ponieważ na każde wywołanie przypada para zapytań do proxy: jedno po stronie klienta, jedno — po stronie serwera.
  2. Ponadto proxy muszą być małe, i lekkie.Każde z nich będzie konsumować zasoby pamięci i CPU, a to zużycie będzie rosło liniowo wraz z aplikacją.
  3. Będzie potrzebny mechanizm do wdrażania i aktualizacji dużej liczby proxy. Robienie tego ręcznie to nie opcja.

Ogólnie rzecz biorąc, service mesh wygląda tak (przynajmniej z lotu ptaka): wdrażasz mnóstwo proxy userspace, które „coś robią” z wewnętrznym, międzyserwisowym ruchem, i używasz control plane do monitorowania i zarządzania nimi.

Nadszedł czas na pytanie 'Dlaczego?'

Po co potrzebna jest service mesh?

Osoby, które po raz pierwszy spotykają się z ideą service mesh, mogą poczuć lekki niepokój. Konstrukcja service mesh oznacza, że nie tylko zwiększy opóźnienia w aplikacji, ale także będzie zużywać zasoby i doda mnóstwo nowych mechanizmów do infrastruktury. Najpierw instalujesz service mesh, a potem nagle odkrywasz, że musisz obsługiwać setki (jeśli nie tysiące) proxy. Pytanie brzmi, kto dobrowolnie podejmie się tego zadania?

Odpowiedź na to pytanie składa się z dwóch części. Po pierwsze, koszty operacyjne związane z wdrażaniem tych proxy mogą być znacznie obniżone dzięki pewnym zmianom zachodzącym w ekosystemie (więcej na ten temat później).

Po drugie, takie urządzenie to w rzeczywistości doskonały sposób na wprowadzenie dodatkowej logiki do systemu. I nie tylko dlatego, że za pomocą service mesh można dodać wiele nowych funkcji, ale także dlatego, że można to zrobić, nie ingerując w ekosystem. W rzeczywistości cała koncepcja service mesh opiera się na tym postulacie: w systemie wielousługowym, niezależnie od tego, co robią poszczególne usługi, ruch między nimi jest idealnym punktem do dodawania funkcjonalności.

Na przykład w Linkerd (jak i w większości mesh’ów) funkcjonalność koncentruje się głównie na wywołaniach HTTP, w tym HTTP/2 i gRPC*. Funkcjonalność jest dość bogata – można ją podzielić na trzy klasy:

  1. Funkcje związane z niezawodnością. Powtarzanie zapytań, limity czasowe, podejście kanaryjskie (podział/przekierowanie ruchu) itd.
  2. Funkcje związane z monitoringiem. Agregacja wskaźników efektywności, opóźnień i wolumenów zapytań dla każdej usługi lub poszczególnych kierunków; budowanie map topologicznych usług itd.
  3. Funkcje związane z bezpieczeństwem. Mutual TLS, kontrola dostępu itd.

* Z perspektywy Linkerd gRPC praktycznie niczym nie różni się od HTTP/2: po prostu w ładunku używa się protobuf. Z punktu widzenia programisty te dwie rzeczy oczywiście się różnią.

Wiele z tych mechanizmów działa na poziomie zapytań (stąd "L7-proxy"). Na przykład, jeśli serwis Foo wysyła wywołanie HTTP do serwisu Bar, linkerd-proxy po stronie Foo może przeprowadzić inteligentne balansowanie obciążenia i kierować wywołania z Foo do instancji Bar w zależności od obserwowanej latencji; może powtórzyć zapytanie w razie potrzeby (jeśli jest idempotentne); może zapisać kod odpowiedzi i czas oczekiwania, itd. Podobnie linkerd-proxy po stronie Bar może odrzucić zapytanie, jeśli nie jest dozwolone lub przekroczono limit zapytań; może zarejestrować latencję po swojej stronie, itd.

Prox'y mogą "coś robić" także na poziomie połączenia. Na przykład linkerd-proxy po stronie Foo może zainicjować połączenie TLS, a linkerd-proxy po stronie Bar — je zakończyć, a obie strony mogą sprawdzić certyfikaty TLS wzajemnie. To zapewnia nie tylko szyfrowanie między serwisami, ale także kryptograficznie bezpieczny sposób identyfikacji serwisów: Foo i Bar mogą "udowodnić", że są tymi, za które się podają.

* "Wzajemnie" oznacza, że certyfikat klienta również jest weryfikowany (mutual TLS). W "klasycznym" TLS, na przykład między przeglądarką a serwerem, zazwyczaj weryfikowany jest certyfikat tylko jednej strony (serwera).

Niezależnie od tego, czy działają na poziomie zapytań, czy połączeń, ważne jest podkreślenie, że wszystkie funkcje service mesh mają operacyjny charakter. Linkerd nie jest w stanie zmieniać semantyki ładunku — na przykład dodawać pól do fragmentu JSON lub wprowadzać zmiany w protobuf. O tej istotnej cesze porozmawiamy później, gdy omówimy ESB i middleware.

Taki jest zestaw funkcji, które oferuje service mesh. Pojawia się pytanie: po co nie wdrożyć ich bezpośrednio w aplikacji? I po co w ogóle wiązać się z prox'y?

Dlaczego service mesh to dobry pomysł

Choć możliwości service mesh fascynują, jej podstawowa wartość tak naprawdę nie leży w funkcjach. W końcu możemy wdrożyć je bezpośrednio w aplikacji (później zobaczymy, że takie było pochodzenie service mesh). Jeśli spróbować wyrazić tę myśl jednym zdaniem, wartość service mesh polega na tym: zapewnia funkcje krytycznie ważne dla działania nowoczesnego oprogramowania serwerowego, jednolite dla całego stosu i niezależne od kodu aplikacji.

Przyjrzyjmy się tej wypowiedzi.

«Funkcje krytycznie ważne dla działania nowoczesnego oprogramowania serwerowego». Jeśli tworzysz aplikację serwerową transakcyjną, związaną z publicznym internetem, przyjmującą zapytania zewnętrzne i odpowiadającą na nie w krótkim czasie — na przykład aplikację webową, serwer API, a także przeważającą większość innych nowoczesnych aplikacji — i jeśli realizujesz ją jako zestaw usług, które synchronizują się ze sobą, oraz jeśli nieustannie modernizujesz to oprogramowanie, dodając nowe funkcje, i jeśli musisz utrzymywać ten system w działaniu podczas jego modyfikacji — gratuluję, zajmujesz się tworzeniem nowoczesnego oprogramowania serwerowego. A wszystkie te wspaniałe funkcje, wymienione powyżej, okazują się w rzeczywistości krytycznie ważne dla Ciebie. Aplikacja musi być niezawodna, bezpieczna, i musisz mieć możliwość monitorowania tego, co robi. To dokładnie te kwestie rozwiązuje service mesh.

(OK, do poprzedniego akapitu wkradła się moje przekonanie, że podejście to jest nowoczesnym sposobem tworzenia oprogramowania serwerowego. Inni wolą rozwijać monolity, 'reaktywne mikroserwisy' i inne rzeczy, które nie wpisują się w powyższą definicję. Ci ludzie na pewno mają swoje zdanie, różniące się od mojego. Ja natomiast uważam, że 'nie mają racji' — chociaż w każdym razie service mesh nie jest dla nich zbyt przydatna).

«Jednolity dla całego stosu». Funkcje oferowane przez service mesh są nie tylko krytycznie ważne. Stosuje się je do wszystkich usług w aplikacji, niezależnie od tego, w jakim języku są napisane, którego frameworka używają, kto je napisał, jak zostały wdrożone i od wszelkich innych niuansów ich rozwoju i zastosowania.

«Niezależnym od kodu aplikacjiW końcu service mesh nie tylko zapewnia jednolite funkcjonalności dla całego stosu, ale robi to w sposób, który nie wymaga modyfikacji aplikacji. Fundamentalna podstawa funkcjonalności service mesh, w tym zadania konfiguracyjne, aktualizacyjne, operacyjne, serwisowe itd., znajduje się wyłącznie na poziomie platformy i jest niezależna od aplikacji. Aplikacja może się zmieniać, nie wpływając na service mesh. Z kolei service mesh może się zmieniać, bez żadnego zaangażowania aplikacji.

Krótko mówiąc, service mesh nie tylko zapewnia kluczowe funkcje, ale robi to w sposób globalny, spójny i niezależny od aplikacji. Dlatego, choć funkcjonalności service mesh mogą być wdrażane w kodzie serwisu (na przykład jako biblioteka dołączona do każdego serwisu), takie podejście nie zapewni jednorodności i niezależności, które są tak cenne w przypadku service mesh.

A wszystko, co jest do tego potrzebne, to dodać mnóstwo proxy! Obiecuję, że bardzo szybko omówimy koszty operacyjne związane z dodawaniem tych proxy. Ale najpierw zatrzymajmy się i przyjrzyjmy tej idei niezależności z punktu widzenia różnych ludzi.

Komu pomaga service mesh?

Choć może to być niewygodne, aby jakaś technologia stała się istotną częścią ekosystemu, musi zostać zaakceptowana przez ludzi. Kto więc interesuje się service mesh? Kto korzysta z jej zastosowania?

Jeśli rozwijasz nowoczesne oprogramowanie serwerowe, możesz mniej więcej wyobrazić sobie swoją drużynę jako grupę właścicieli serwisów, którzy wspólnie rozwijają i wdrażają logikę biznesową, oraz właścicieli platformy, zajmujących się rozwojem wewnętrznej platformy, na której te serwisy działają. W małych organizacjach mogą to być te same osoby, ale wraz ze wzrostem firmy te role zazwyczaj stają się bardziej wyraźne i nawet dzielą się na podrole... (Można powiedzieć wiele o zmieniającej się naturze devopsu, organizacyjnym wpływie mikrousług itp. Ale na razie przyjmijmy te opisy jako dane.)

Z tej perspektywy wyraźnymi beneficjentami service mesh są właściciele platform. Ostatecznie celem zespołu platformy jest stworzenie wewnętrznej platformy, na której właściciele usług mogą wdrażać logikę biznesową w sposób, który gwarantuje ich maksymalną niezależność od trudnych szczegółów jej eksploatacji. Service mesh nie tylko oferuje możliwości, które są krytycznie ważne dla osiągnięcia tego celu: czyni to w sposób, który z kolei nie narzuca zależności na właścicieli usług.

Właściciele usług również odnoszą korzyści, choć w sposób bardziej pośredni. Celem właściciela usługi jest maksymalna produktywność w realizacji logiki procesów biznesowych, a im mniej musi martwić się kwestiami eksploatacyjnymi, tym lepiej. Zamiast zajmować się wdrażaniem, powiedzmy, polityki ponownych zapytań czy TLS, mogą skupić się wyłącznie na zadaniach biznesowych, mając nadzieję, że platforma zajmie się resztą. To dla nich duża zaleta.

Wartość organizacyjna takiego podziału między właścicielami platform i usług jest trudna do przecenienia. Myślę, że wnosi główną wkład w wartość service mesh.

Nauczyliśmy się tej lekcji, kiedy jeden z pierwszych entuzjastów Linkerd opowiedział nam, dlaczego wybrali service mesh: ponieważ pozwoliła im „zredukować do minimum rozmowy”. Oto kilka szczegółów: chłopaki z dużej firmy migrowali swoją platformę do Kubernetes. Ponieważ aplikacja pracowała z poufnymi informacjami, chcieli zaszyfrować wszystkie komunikacje w klastrach. Sytuacja była jednak skomplikowana przez setki usług i setki zespołów deweloperskich. Perspektywa kontaktowania się z wszystkimi i przekonywani ich do wdrożenia wsparcia dla TLS zupełnie ich nie cieszyła. Instalując Linkerd, przenieśli odpowiedzialność z deweloperów (z punktu widzenia których było to zbędne obciążenie) na platformowców, dla których stanowiło to najwyższy priorytet. Innymi słowy, Linkerd rozwiązywał dla nich nie tylko techniczny, ale także organizacyjny problem.

Krótko mówiąc, service mesh to raczej rozwiązanie nie techniczne, a socio-techniczne problemu. (Dziękuję Cindy Sridharan za wprowadzenie w ten termin.)

Czy service mesh rozwiąże wszystkie moje problemy?

Tak. W sensie, nie!

Analizując trzy klasy funkcji, o których wspomniano powyżej: niezawodność, bezpieczeństwo i obserwowalność, staje się jasne, że service mesh nie jest pełnoprawnym rozwiązaniem dla żadnego z tych problemów. Chociaż Linkerd może wysyłać powtarzające się zapytania (jeśli wie, że są one idempotentne), nie jest w stanie podejmować decyzji dotyczących tego, co zwrócić użytkownikowi, jeśli usługa całkowicie zawiedzie — takie decyzje powinno podejmować aplikacja. Linkerd może prowadzić statystyki udanych zapytań, jednakże nie jest w stanie zajrzeć do usługi i dostarczyć jej wewnętrzne metryki — taki zestaw narzędzi powinien być dostępny w aplikacji. I chociaż Linkerd jest w stanie zorganizować mTLS, pełne rozwiązania w zakresie bezpieczeństwa wymagają znacznie więcej.

Podzbiór funkcji w tych obszarach, oferowanych przez service mesh, odnosi się do funkcji platformy. Przez to rozumiem funkcje, które:

  1. Są niezależne od logiki biznesowej. Sposób, w jaki budowane są histogramy wywołań między Foo a Bar, nie zależy od tego, dlaczego czy Foo wywołuje Bar.
  2. Trudno to prawidłowo zaimplementować. W Linkerd próby ponowne są parametryzowane różnymi zaawansowanymi funkcjami, takimi jak budżety prób ponownych (retry budgets), ponieważ prymitywne podejście w implementacji takich rzeczy na pewno doprowadzi do powstania tzw. "lawiny zapytań" (retry storm) i innych problemów typowych dla systemów rozproszonych.
  3. Są najbardziej skuteczne, gdy stosowane są jednolicie. Mechanizm TLS ma sens tylko wtedy, gdy stosowany jest wszędzie.

Ponieważ te funkcje są realizowane na poziomie proxy (a nie na poziomie aplikacji), service mesh oferuje je na poziomie platformy, a nie aplikacji. Dlatego nie ma znaczenia, w jakim języku napisane są usługi, z jakiego frameworka korzystają, kto je napisał i dlaczego. Proxy działa poza wszystkimi tymi szczegółami, a fundament tej funkcjonalności, w tym zadania związane z konfiguracją, aktualizacją, eksploatacją, serwisowaniem itp., leży wyłącznie na poziomie platformy.

Przykłady możliwości service mesh

Service Mesh: co każdy Software Engineer powinien wiedzieć o najmodniejszej technologii

Podsumowując, chcę powiedzieć, że service mesh nie jest pełnym rozwiązaniem zapewniającym niezawodność, obserwowalność lub bezpieczeństwo. Zakres tych obszarów wymaga obowiązkowego zaangażowania właścicieli usług, zespołów Ops/SRE oraz innych podmiotów w firmie. Service mesh oferuje jedynie „przekrój” na poziomie platformy dla każdego z tych obszarów.

Dlaczego service mesh stał się popularny właśnie teraz?

Prawdopodobnie w tej chwili zastanawiasz się: okej, jeśli service mesh jest tak dobry, dlaczego nie zaczęliśmy wdrażać milionów proxy w stosie dziesięć lat temu?

Jest prosta odpowiedź na to pytanie: dziesięć lat temu wszyscy budowali monolity, a service mesh nikomu nie był potrzebny. To prawda, ale moim zdaniem w tej odpowiedzi traci się sens. Nawet dziesięć lat temu koncepcja mikroserwisów jako obiecującego sposobu tworzenia systemów o dużej skali była szeroko dyskutowana i stosowana w takich firmach jak Twitter, Facebook, Google i Netflix. Ogólne wrażenie - przynajmniej w tych częściach branży, z którymi się kontaktowałem - polegało na tym, że mikroserwisy to „właściwy sposób” tworzenia dużych systemów, nawet jeśli było to cholernie trudne.

Oczywiście, chociaż dziesięć lat temu były firmy wykorzystujące mikroserwisy, wcale nie umieszczały proxy wszędzie tam, gdzie tylko mogły, aby stworzyć service mesh. Jednak jeśli się przyjrzeć, robiły coś podobnego: w wielu z tych firm wymagano korzystania z określonej wewnętrznej biblioteki do komunikacji sieciowej (czasami nazywanej biblioteką grubego klienta, fat client library).

Netflix miał Hysterix, Google miał Stubby, Twitter miał bibliotekę Finagle. Finagle na przykład była obowiązkowa dla każdej nowej usługi w Twitterze. Obsługiwała zarówno część kliencką, jak i serwerową połączeń, umożliwiała wykonywanie ponownych zapytań, wspierała routowanie zapytań, balansowanie obciążenia i pomiary. Zapewniała spójny poziom niezawodności i obserwowalności dla całego stosu Twittera, niezależnie od tego, czym dokładnie zajmowała się usługa. Oczywiście działała tylko dla języków JVM i opierała się na modelu programowania, który należało stosować w całej aplikacji. Niemniej jednak jej funkcjonalności były prawie takie same jak w przypadku service mesh. (W rzeczywistości pierwsza wersja Linkerd była po prostu Finagle, zapakowany w formę proxy.)

Tak więc dziesięć lat temu istniały nie tylko mikrousługi, ale także specjalne biblioteki proto-service-mesh, które rozwiązywały te same problemy, które dzisiaj rozwiązuje service mesh. Jednak samego service mesh wówczas nie było. Musiał nastąpić jeszcze jeden zwrot, zanim się pojawiła.

I to właśnie tutaj leży głębsza odpowiedź, ukryta w innej zmianie, która miała miejsce w ciągu ostatnich 10 lat: doszło do drastycznego spadku kosztów wdrażania mikrousług. Wspomniane wcześniej firmy, które korzystały z mikrousług dziesięć lat temu: Twitter, Netflix, Facebook, Google — były firmami o ogromnej skali i zasobach. Miały nie tylko potrzebę, ale i możliwość tworzenia, wdrażania i eksploatacji dużych aplikacji opartych na mikrousługach. Energia i wysiłki inżynierów Twittera, aby przejść z monolitu na podejście mikrousługowe, po prostu wprawiają w zdziwienie. (Szczerze mówiąc, jak i fakt, że to się udało.) Tego rodzaju manewry infrastrukturalne były wtedy niemożliwe dla mniejszych firm.

Przenieśmy się do teraźniejszości. Dzisiaj istnieją startupy, w których stosunek mikrousług do programistów wynosi 5:1 (lub nawet 10:1), i co więcej, radzą sobie z tym pomyślnie! Jeśli startup składający się z 5 osób jest w stanie, bez wysiłku, eksploatować 50 mikrousług, to znaczy, że coś wyraźnie obniżyło koszt ich wdrożenia.

Service Mesh: co każdy Software Engineer powinien wiedzieć o najmodniejszej technologii
1500 mikrousług w Monzo; każda linia to przepisana reguła sieciowa, która zezwala na ruch.

Drastyczny spadek kosztów eksploatacji mikrousług jest wynikiem jednego procesu: wzrostu popularności kontenerów i orkiestratorów. W tym właśnie tkwi głęboka odpowiedź na pytanie, co przyczyniło się do powstania service mesh. Ta sama technologia uczyniła zarówno service mesh, jak i mikrousługi atrakcyjnymi: Kubernetes i Docker.

Dlaczego? Cóż, Docker rozwiązuje jeden duży problem — problem pakowania. Pakując aplikację i jej (niesieciowe) zależności czasowe w kontener, Docker zamienia aplikację w wymienny składnik, który można umieścić i uruchomić gdziekolwiek. Jednocześnie znacznie upraszcza eksploatację wielojęzycznego Stos: ponieważ kontener jest atomową jednostką wykonawczą, dla celów wdrażania i eksploatacji nie ma znaczenia, co znajduje się wewnątrz, czy to aplikacja na JVM, Node, Go, Python czy Ruby. Po prostu uruchamiasz go i już.

Kubernetes wprowadza wszystko na nowy poziom. Teraz, gdy istnieje mnóstwo „wykonywalnych elementów” i wiele maszyn, na których można je uruchamiać, pojawia się potrzeba narzędzia, które potrafi je ze sobą dopasować. W szerokim sensie, dostarczasz Kubernetesowi wiele kontenerów i wiele maszyn, a on dopasowuje je do siebie (oczywiście jest to dynamiczny i nieustannie zmieniający się proces: nowe kontenery poruszają się po systemie, maszyny są uruchamiane i zatrzymywane itd. Jednak Kubernetes bierze to wszystko pod uwagę).

Po skonfigurowaniu Kubernetes czas potrzebny na wdrożenie i eksploatację jednego serwisu niewiele różni się od kosztów związanych z wdrożeniem i eksploatacją dziesięciu serwisów (w rzeczywistości są praktycznie analogiczne i dla 100 serwisów). Dodaj do tego kontenery jako mechanizm pakowania, który sprzyja wielojęzycznej implementacji, a otrzymasz masę nowych aplikacji wdrożonych w formie mikrousług, napisanych w różnych językach — dokładnie takie środowisko, do którego tak dobrze pasuje service mesh.

Więc doszliśmy do odpowiedzi na pytanie, dlaczego pomysł service mesh stał się popularny właśnie teraz: ta jednorodność, którą Kubernetes zapewnia dla serwisów, ma bezpośrednie zastosowanie do zadań eksploatacyjnych, przed którymi stoi service mesh. Pakujesz proxy w kontenery, dajesz Kubernetesowi zadanie przymocowania ich wszędzie, gdzie można, i voilà! Na końcu otrzymujesz service mesh, a całą mechanikę jej wdrożenia obsługuje Kubernetes. (Przynajmniej z lotu ptaka. Oczywiście w tym procesie jest wiele niuansów.)

Podsumowując: powód, dla którego service mesh stał się popularny właśnie teraz, a nie dziesięć lat temu, polega na tym, że Kubernetes i Docker nie tylko znacząco zwiększyły potrzebę na niego, upraszczając wdrożenie aplikacji jako zestawów wielojęzycznych mikrousług, ale również znacznie zmniejszyły koszty jego eksploatacji, zapewniając mechanizmy wdrażania i wsparcia parków proxy sidecar.

Dlaczego jest tak wiele rozmów o service mesh?

Ostrzeżenie: w tej części posługuję się wszelkimi przypuszczeniami, domysłami, spekulacjami i wewnętrznymi informacjami.

Szukając frazy „service mesh”, natkniesz się na mnóstwo przerobionych treści niskokalorycznych, dziwnych projektów i kalejdoskopu zniekształceń, godnych echa komory. Każdej modnej nowej technologii towarzyszy coś takiego, ale w przypadku service mesh problem ten jest szczególnie wyraźny. Dlaczego?

Częściowo to moja wina. Robiłem wszystko, aby promować Linkerd i service mesh przy każdej okazji, pisząc niezliczone wpisy na blogu i artykuły, takie jak ten. Ale nie jestem aż tak potężny. Aby naprawdę odpowiedzieć na to pytanie, musimy chwilę porozmawiać o ogólnej sytuacji. A mówienie o niej jest niemożliwe bez wspomnienia jednego projektu: Istio — service mesh z otwartym kodem źródłowym, rozwijanym wspólnie przez Google, IBM i Lyft.

(Te trzy firmy mają zupełnie różne role: udział Lyfta wydaje się ograniczać tylko do nazwy; są autorami Envoy, ale nie korzystają z Istio ani nie uczestniczą w jego rozwoju. IBM bierze udział w rozwoju Istio i z niego korzysta. Google aktywnie uczestniczy w rozwijaniu Istio, ale z tego, co mogę ocenić, właściwie go nie stosuje.)

Projekt Istio wyróżnia się dwiema cechami. Po pierwsze, to ogromne wysiłki marketingowe, które Google, w szczególności, podejmuje w celu jego promocji. Szacuję, że większość osób, które obecnie wiedzą o koncepcji service mesh, dowiedziała się o niej po raz pierwszy właśnie dzięki Istio. Drugą cechą jest to, jak słabo Istio zostało przyjęte. W tej kwestii, jak widać, jestem zainteresowaną stroną, ale starając się być jak najbardziej obiektywnym, nie mogę nie zaznaczyć dość negatywne nastawienie, nie jest to zbyt charakterystyczne (choć nie unikalne: przypomina mi się systemd, porównanie było już przeprowadzane…) dla projektu Open Source.

(W praktyce wydaje się, że Istio ma problemy nie tylko z złożonością i UX, ale także z wydajnością. Na przykład, podczas oceny wydajności Linkerd, przeprowadzonej przez stronę trzecią, specjaliści odkryli sytuacje, w których opóźnienia końcowe (tail latency) Istio były 100 razy wyższe niż analogiczne dla Linkerd, a także sytuacje z brakiem zasobów, gdy Linkerd funkcjonował pomyślnie, a Istio całkowicie przestawało działać.)

Odkładając na bok moje teorie dotyczące tego, dlaczego tak się stało, uważam, że ogromny hype wokół service mesh tłumaczy się przez zaangażowanie Google. A dokładniej, kombinacją trzech następujących czynników:

  1. natarczywe promowanie Istio przez Google;
  2. odpowiednie negatywne, krytyczne nastawienie do projektu;
  3. niedawny gwałtowny wzrost popularności Kubernetes, którego wspomnienia są wciąż żywe.

Razem te czynniki łączą się w pewne przytłaczające, beztlenowe środowisko, w którym zdolność do racjonalnego rozumowania słabnie, a pozostaje jedynie wspaniała odmiana tulipanomanii..

Z perspektywy Linkerd opisałbym to jako ambiwalentne dobro. Mam na myśli, że świetnie, że service mesh weszło do głównego nurtu — czego nie było w 2016 roku, kiedy Linkerd dopiero pojawił się i było naprawdę trudno przyciągnąć uwagę otoczenia do projektu. Teraz ten problem nie istnieje! Ale złe jest to, że sytuacja z service mesh jest teraz tak skomplikowana, że praktycznie niemożliwe jest zrozumienie, które projekty naprawdę należą do kategorii service mesh (nie mówiąc już o tym, aby zrozumieć, który z nich najlepiej pasuje do konkretnego przypadku użycia). To niewątpliwie przeszkadza wszystkim (i zdecydowanie w niektórych przypadkach Istio lub inny projekt pasuje lepiej niż Linkerd, ponieważ ten ostatni nie jest uniwersalnym rozwiązaniem).

Z perspektywy Linkerd nasza strategia polegała na ignorowaniu hałasu, dalszym skupieniu się na rozwiązywaniu rzeczywistych problemów społeczności i właściwie czekaniu, aż hype opadnie. Ostatecznie entuzjazm spadnie, a my będziemy mogli spokojnie pracować.

Na razie wszyscy musimy trochę poczekać.

Czy service mesh przyda mi się, skromnemu inżynierowi oprogramowania?

Na pytanie to pomoże odpowiedzieć następująca ankieta:

Zajmujesz się wyłącznie realizacją logiki biznesowej? W takim razie service mesh nie będzie ci potrzebna. Oczywiście, możesz się nią zainteresować, ale w idealnym przypadku service mesh nie powinna bezpośrednio wpływać na nic w twoim otoczeniu. Kontynuuj pracę nad tym, za co ci płacą.

Obsługujesz platformę w firmie, która używa Kubernetes? Tak, w takim przypadku potrzebujesz service mesh (oczywiście, jeśli nie używasz K8s tylko do uruchamiania monolitów lub przetwarzania wsadowego — ale wtedy chciałbym zapytać, po co ci K8s). Najprawdopodobniej znajdziesz się w sytuacji z wieloma mikroserwisami napisanymi przez różnych ludzi. Wszystkie one wzajemnie ze sobą współpracują i są powiązane w gmatwaninę zależności w czasie rzeczywistym, a ty musisz znaleźć sposób, aby sobie z tym poradzić. Wykorzystanie Kubernetes pozwala wybrać service mesh

Zarządzasz platformą w firmie, która NIE używa Kubernetes, ale wykorzystuje mikroserwisy? W takim przypadku service mesh będzie przydatna, jednak jej użycie nie będzie trywialne. Oczywiście, możesz symulować dzieło service mesh, umieszczając masę proxy, ale ważnym atutem Kubernetes jest właśnie model wdrażania: ręczna obsługa tych proxy wymagałaby znacznie więcej czasu, wysiłku i kosztów.

Zarządzasz platformą w firmie, która pracuje z monolitami? W tym przypadku service mesh prawdopodobnie nie jest ci potrzebna. Jeśli pracujesz z monolitami (lub nawet z zestawami monolitów), które mają jasno określone i rzadko zmieniające się wzorce interakcji, to service mesh niewiele ci zaoferuje. Więc możesz po prostu jej nie zauważać i mieć nadzieję, że zniknie jak zły sen...

Podsumowanie

Prawdopodobnie nie należy nazywać service mesh „najbardziej hucznie zapowiadaną technologią na świecie” — to wątpliwe zaszczyty prawdopodobnie przypadają bitcoinowi lub AI. Może znajduje się w pierwszej piątce. Ale jeśli przebić się przez warstwy szumu i hałasu, staje się jasne, że service mesh przynosi realne korzyści tym, którzy tworzą aplikacje w Kubernetes.

Chciałbym, żebyś spróbował Linkerd — jego instalacja w klastrze Kubernetes (lub nawet w Minikube na laptopie) zajmuje około 60 sekund, i sam zobaczysz, o czym mówię.

FAQ

-- Jeśli zignoruję service mesh, zniknie?
-- Muszę cię zmartwić: service mesh jest z nami na dłużej.

-- Ale NIE CHCĘ używać service mesh!
-- No i nie musisz! Tylko przeczytaj moją ankietę powyżej, aby zrozumieć, czy powinieneś zapoznać się chociaż z jej podstawami.

-- Czy to nie stare, dobre ESB/middleware w nowym sosie?
— Service mesh zajmuje się logiką operacyjną, a nie semantyką. To był główny problem enterprise service bus (ESB). Utrzymanie tego podziału pomaga service mesh uniknąć tego samego losu.

— Czym różni się service mesh od bram API?
— Jest milion artykułów na ten temat. Po prostu to przeszukaj w Google.

— Envoy to service mesh?
— Nie, Envoy to nie jest service mesh, to serwer proxy. Może być używany do zorganizowania service mesh (i wielu innych rzeczy — to uniwersalny serwer proxy). Ale sam w sobie nie jest service mesh.

— Network Service Mesh to service mesh?
— Nie. Mimo nazwy, to nie jest service mesh (cud marketingu?).

— Czy service mesh pomoże mojemu reaktywnemu systemowi asynchronicznemu bazującemu na kolejce wiadomości?
— Nie, service mesh ci nie pomoże.

— Które service mesh powinienem użyć?
Linkerd, jest oczywiste.

— Artykuł to beznadzieja! / Autora na śmietnik!
— Proszę, podziel się tym linkiem ze wszystkimi przyjaciółmi, żeby mogli się o tym przekonać!

Podziękowania

Jak mogłeś się domyślić po tytule, ten artykuł został zainspirowany fantastycznym traktatem Jaya Krepsa „The Log: Co każdy inżynier oprogramowania powinien wiedzieć o unifying abstraction danych w czasie rzeczywistym”. Spotkałem Jaya dziesięć lat temu, gdy przeprowadzałem wywiad w LinkedIn, i od tamtej pory jest dla mnie inspiracją.

Chociaż lubię nazywać się „programistą Linkerd”, rzeczywistość jest taka, że jestem raczej opiekunem pliku README.md w projekcie. Przy Linkerd pracuje dzisiaj mi się tu, mi się tu, mi się tu wielu ludzi, a ten projekt nie zrealizowałby się bez udziału wspaniałej społeczności współpracowników i użytkowników.

Na koniec szczególne podziękowania dla twórcy Linkerd, Olivera Goulda (primus inter pares), który razem ze mną wiele lat temu zanurzył się w ten cały zamęt związany z service mesh.

P.S. od tłumacza

Przeczytaj także na naszym blogu:

Źródło: habr.com

Kup solidny hosting stron z ochroną przed DDoS, serwery VPS VDS 🔥 Kup solidny hosting stron z ochroną przed DDoS, serwery VPS VDS | ProHoster