Istio a Kubernetes v produkci. Část 2. Sledování

V minulosti článku Prozkoumali jsme základní komponenty Service Mesh Istio, seznámili jsme se se systémem a odpověděli na hlavní otázky, které obvykle vznikají na začátku práce s Istio. V této části se podíváme na to, jak uspořádat shromažďování informací o tracingu v síti.

Istio a Kubernetes v produkci. Část 2. Sledování

První, co mnoha vývojářům a správcům systémů přijde na mysl, když slyší slova Service Mesh, je tracing. A skutečně, do každého uzlu sítě přidáváme speciální proxy server, přes který prochází veškerý TCP provoz. Zdá se, že nyní můžeme snadno zasílat informace o všech síťových interakcích v síti. Bohužel, ve skutečnosti se objevuje mnoho nuancí, které je třeba vzít v úvahu. Pojďme se na ně podívat.

Mýtus číslo jedna: Můžeme získat údaje o cestách v síti zdarma.

Ve skutečnosti můžeme relativně zdarma získat pouze propojené uzly naší systému se šipkami a rate dat, který prochází mezi službami (v podstatě pouze množství bytů za určitý čas). Nicméně v mnoha případech naše služby komunikují podle nějakého aplikačního protokolu, jako je HTTP, gRPC, Redis a tak dále. A samozřejmě chceme vidět tracer informační právě podle těchto protokolů, chceme vidět rate požadavků, nikoli rate dat. Chceme rozumět latenci požadavků podle našeho protokolu. Konečně, chceme vidět celou cestu, kterou požadavek projde od vstupu do našeho systému až po obdržení odpovědi uživatelským. Tuto úlohu již nelze řešit tak jednoduše.

Nejprve si pojďme ukázat, jak vypadá odesílání tracing spanů z pohledu architektury v Istio. Jak si pamatujeme z první části, Istio má pro sběr telemetrie samostatnou komponentu zvanou Mixer. Nicméně v aktuální verzi 1.0.* se odesílání provádí přímo z proxy serverů, konkrétně z envoy proxy. Envoy proxy nativně podporuje odesílání tracing spanů pomocí protokolu zipkin. Jiné protokoly je možné připojit, ale pouze prostřednictvím pluginu. S Istio okamžitě získáváme předpřipravenou a nakonfigurovanou envoy proxy, která podporuje pouze protokol zipkin. Pokud chceme například použít protokol Jaeger a odesílat tracing spany přes UDP, budeme si muset vytvořit vlastní obraz istio-proxy. Podpora vlastních pluginů pro istio-proxy existuje, ale je stále v alpha verzi. Proto, pokud se chceme obejít bez velkého množství vlastních nastavení, se okruh technologií pro ukládání a příjem tracing spanů zmenšuje. Z hlavních systémů lze nyní prakticky použít buď přímo Zipkin, nebo Jaeger, ale odesílat tam vše pomocí zipkin kompatibilního protokolu (což je výrazně méně efektivní). Samotný protokol zipkin předpokládá odesílání všech tracing informací na collectory přes HTTP protokol, což je poměrně nákladné.

Jak jsem již řekl, chceme tracovat protokoly aplikační úrovně. To znamená, že proxy servery, které stojí vedle každé služby, musí chápat, jaká konkrétní interakce právě probíhá. Ve výchozím nastavení Istio konfiguruje pro všechny porty typ plain TCP, což znamená, že žádné trace nebudou odesílány. Aby se trace odesílaly, je třeba nejprve tuto možnost povolit v hlavní mesh konfiguraci a co je velmi důležité, pojmenovat všechny porty u entit služby Kubernetes podle protokolu, který se v službě používá. To znamená například takto:

apiVersion: v1
kind: Service
metadata:
  name: nginx
spec:
  ports:
  - port: 80
    targetPort: 80
    name: http
  selector:
    app: nginx

Je také možné použít složená jména, například http-magic (Istio uvidí http a rozpozná tento port jako http endpoint). Formát je následující: proto-extra.

Abychom neměli nutnost patchovat obrovské množství konfigurací pro určení protokolu, můžeme využít neestetický workaround: propatchovat komponentu Pilot ve chvíli, kdy právě provádí logiku určování protokolu.. Nakonec bude samozřejmě nutné změnit tuto logiku na standardní a přejít na konvenci pojmenovávání všech portů.

Abychom zjistili, zda je protokol skutečně definován správně, je nutné vstoupit do některého z sidecar kontejnerů s envoy proxy a provést dotaz na port administrátorského rozhraní envoy s umístěním /config_dump. Ve vzniklé konfiguraci je potřeba zkontrolovat u příslušné služby pole operation. To se v Istio používá jako identifikátor, kam dotaz směřuje. Abychom v Istio přizpůsobili hodnotu tohoto parametru (ten pak uvidíme v našem tracing systému), je nutné při spuštění sidecar kontejneru zadat příznak serviceCluster. Například ho lze takto zpracovat z proměnných získaných z downward API kubernetes:

--serviceCluster ${POD_NAMESPACE}.$(echo ${POD_NAME} | sed -e 's/-[a-z0-9]*-[a-z0-9]*$//g')

Dobrým příkladem pro pochopení toho, jak tracing v envoy funguje, je tady.

Samotný endpoint pro odesílání tracing spanů je také nutné uvést v příznacích spuštění envoy proxy, například: --zipkinAddress tracing-collector.tracing:9411

Myšlenková chyba číslo dvě: můžeme levně získat kompletní trasy průchodu dotazů systémem přímo z krabice.

Bohužel, není tomu tak. Složitost implementace závisí na tom, jak máte již realizováno vzájemné propojení služeb. Proč tomu tak je?

Jde o to, že abychom umožnili istio-proxy pochopit vymezení příchozích dotazů do služby a odchozích z této služby, nestačí jen odchytit veškerý provoz. Je nutné mít nějaký identifikátor propojení. V HTTP envoy proxy se používají speciální hlavičky, podle kterých envoy chápe, který konkrétní dotaz k službě generuje konkrétní dotazy do jiných služeb. Seznam těchto hlaviček je:

  • x-request-id,
  • x-b3-traceid,
  • x-b3-spanid,
  • x-b3-parentspanid,
  • x-b3-sampled,
  • x-b3-flags,
  • x-ot-span-context.

Pokud máte jednotný bod, například základní klient, do kterého lze tuto logiku přidat, je vše skvělé, musíte jen počkat na aktualizaci této knihovny u všech klientů. Ale pokud máte velmi heterogenní systém a chybí unifikace při přechodu z jedné služby na druhou v síti, pravděpodobně to bude velký problém. Bez přidání podobné logiky budou všechny tracing informace pouze "jednoúrovňové". To znamená, že získáme veškerou mezislužební interakci, ale nebudou pospojovány do jediné sítě.

Závěr

Istio poskytuje užitečný nástroj pro sběr tracing informací po síti, avšak je potřeba mít na paměti, že pro implementaci bude třeba přizpůsobit svůj systém a vzít v úvahu specifika implementace Istio. Nakonec je třeba vyřešit dvě zásadní otázky: určení aplikačního protokolu (který by měl být podporován envoy proxy) a nastavení přenosu informací o propojenosti požadavků ze služby na požadavky ze služby (pomocí headerů, pokud je použit protokol HTTP). Jakmile jsou tyto otázky vyřešeny, získáme mocný nástroj, který umožňuje transparentně sbírat informace ze sítě i ve velmi heterogenních systémech napsaných v různých jazycích a rámcích.

V následujícím článku o Service Mesh se zaměříme na jeden z největších problémů Istio – vysokou spotřebu operační paměti každým sidecar proxy kontejnerem a prodiskutujeme, jak s ním lze bojovat.

Zdroj: habr.com

Koupit spolehlivý hosting pro webové stránky s ochranou proti DDoS, VPS VDS servery 🔥 Koupit spolehlivý hosting pro webové stránky s ochranou proti DDoS, VPS VDS servery | ProHoster