Istio și Kubernetes în producție. Partea 2. Trasare

În trecut articol Ne-am uitat la componentele de bază ale Service Mesh Istio, ne-am familiarizat cu sistemul și am răspuns la principalele întrebări care apar de obicei atunci când începem să lucrați cu Istio. În această parte ne vom uita la modul de organizare a colecției de informații de urmărire într-o rețea.

Istio și Kubernetes în producție. Partea 2. Trasare

Primul lucru care vine în minte pentru mulți dezvoltatori și administratori de sistem atunci când aud cuvintele Service Mesh este urmărirea. Într-adevăr, adăugăm un server proxy special fiecărui nod de rețea prin care trece tot traficul TCP. Se pare că acum este posibil să trimiteți cu ușurință informații despre toate interacțiunile de rețea din rețea. Din păcate, în realitate există multe nuanțe care trebuie luate în considerare. Să ne uităm la ele.

Concepția greșită numărul unu: putem obține gratuit date de drumeții online.

De fapt, relativ gratuit, putem obține doar nodurile sistemului nostru conectate prin săgeți și rata de date care trece între servicii (de fapt, doar numărul de octeți pe unitatea de timp). Cu toate acestea, în cele mai multe cazuri, serviciile noastre comunică printr-un fel de protocol de nivel de aplicație, cum ar fi HTTP, gRPC, Redis și așa mai departe. Și, desigur, vrem să vedem informații de urmărire în mod specific pentru aceste protocoale; vrem să vedem rata de solicitare, nu rata de date. Dorim să înțelegem latența solicitărilor folosind protocolul nostru. În cele din urmă, dorim să vedem calea completă pe care o ia o solicitare de la conectarea la sistemul nostru până la primirea unui răspuns de la utilizator. Această problemă nu mai este atât de ușor de rezolvat.

În primul rând, să ne uităm la cum arată intervalele de urmărire de trimitere din punct de vedere arhitectural în Istio. După cum ne amintim din prima parte, Istio are o componentă separată numită Mixer pentru colectarea telemetriei. Totuși, în versiunea actuală 1.0.*, trimiterea se face direct de pe serverele proxy, și anume, de la proxy envoy. Proxy Envoy acceptă trimiterea intervalelor de urmărire folosind protocolul zipkin din cutie. Este posibilă conectarea altor protocoale, dar numai printr-un plugin. Cu Istio primim imediat un proxy envoy asamblat și configurat, care acceptă doar protocolul zipkin. Dacă dorim să folosim, de exemplu, protocolul Jaeger și să trimitem intervale de urmărire prin UDP, atunci va trebui să ne construim propria imagine istio-proxy. Există suport pentru pluginuri personalizate pentru istio-proxy, dar este încă în versiunea alfa. Prin urmare, dacă vrem să ne lipsim de un număr mare de setări personalizate, gama de tehnologii utilizate pentru stocarea și primirea intervalelor de urmărire este redusă. Dintre sistemele principale, de fapt, acum puteți folosi Zipkin în sine, sau Jaeger, dar trimiteți totul acolo folosind protocolul compatibil zipkin (care este mult mai puțin eficient). Protocolul zipkin în sine implică trimiterea tuturor informațiilor de urmărire către colectori prin protocolul HTTP, care este destul de costisitor.

După cum am spus deja, vrem să urmărim protocoalele la nivel de aplicație. Aceasta înseamnă că serverele proxy care stau lângă fiecare serviciu trebuie să înțeleagă ce fel de interacțiune are loc acum. În mod implicit, Istio configurează toate porturile să fie TCP simplu, ceea ce înseamnă că nu vor fi trimise urme. Pentru ca urmele să fie trimise, trebuie, în primul rând, să activați această opțiune în configurația principală a rețelei și, ceea ce este foarte important, să denumiți toate porturile entităților de serviciu kubernetes în conformitate cu protocolul care este utilizat în serviciu. Adică, de exemplu, așa:

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

De asemenea, puteți utiliza nume compuse precum http-magic (Istio va vedea http și va recunoaște acel port ca punct final http). Formatul este: proto-extra.

Pentru a nu corecta un număr mare de configurații pentru a determina protocolul, puteți utiliza o soluție murdară: corecționați componenta Pilot în momentul în care este doar realizează logica de definire a protocolului. În cele din urmă, desigur, va fi necesar să schimbați această logică la standard și să treceți la o convenție de denumire pentru toate porturile.

Pentru a înțelege dacă protocolul este într-adevăr definit corect, trebuie să intrați în oricare dintre containerele sidecar cu proxy envoy și să faceți o solicitare către portul de administrare al interfeței envoy cu locația /config_dump. În configurația rezultată, trebuie să vă uitați la câmpul de operare al serviciului dorit. Este folosit în Istio ca un identificator pentru locul în care se face cererea. Pentru a personaliza valoarea acestui parametru în Istio (o vom vedea apoi în sistemul nostru de urmărire), este necesar să specificați steag-ul serviceCluster în etapa de lansare a containerului sidecar. De exemplu, poate fi calculat astfel din variabilele obținute din API-ul kubernetes descendent:

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

Un bun exemplu pentru a înțelege cum funcționează urmărirea în envoy aici.

Punctul final însuși pentru trimiterea intervalelor de urmărire trebuie, de asemenea, specificat în steaguri de lansare a proxy envoy, de exemplu: --zipkinAddress tracing-collector.tracing:9411

Concepția greșită numărul doi: putem obține ieftin urme complete ale solicitărilor prin intermediul sistemului din cutie

Din păcate, nu este. Complexitatea implementării depinde de modul în care ați implementat deja interacțiunea serviciilor. De ce este asta?

Cert este că, pentru ca istio-proxy să poată înțelege corespondența cererilor primite către un serviciu cu cele care părăsesc același serviciu, nu este suficient să interceptăm pur și simplu tot traficul. Trebuie să aveți un fel de identificator de comunicare. Proxy HTTP Envoy utilizează antete speciale, prin care envoy înțelege ce cerere specifică către serviciu generează solicitări specifice altor servicii. Lista acestor anteturi:

  • x-request-id,
  • x-b3-traceid,
  • x-b3-spanid,
  • x-b3-parentspanid,
  • x-b3-eșantionat,
  • x-b3-steaguri,
  • x-ot-span-context.

Dacă aveți un singur punct, de exemplu, un client de bază, în care puteți adăuga o astfel de logică, atunci totul este în regulă, trebuie doar să așteptați ca această bibliotecă să fie actualizată pentru toți clienții. Dar dacă aveți un sistem foarte eterogen și nu există o unificare în trecerea de la serviciu la serviciu prin rețea, atunci aceasta va fi cel mai probabil o mare problemă. Fără a adăuga o astfel de logică, toate informațiile de urmărire vor fi doar „la un singur nivel”. Adică vom primi toate interacțiunile inter-servicii, dar nu vor fi lipite în lanțuri unice de trecere prin rețea.

Concluzie

Istio oferă un instrument convenabil pentru colectarea informațiilor de urmărire într-o rețea, dar trebuie să înțelegeți că pentru implementare va trebui să vă adaptați sistemul și să țineți cont de caracteristicile implementării Istio. Ca urmare, trebuie rezolvate două puncte principale: definirea protocolului la nivel de aplicație (care trebuie să fie suportat de proxy-ul envoy) și configurarea redirecționării informațiilor despre conectarea solicitărilor la serviciu din solicitările serviciului (folosind anteturi). , în cazul protocolului HTTP). Când aceste probleme sunt rezolvate, avem un instrument puternic care ne permite să colectăm în mod transparent informații din rețea, chiar și în sisteme foarte eterogene scrise în multe limbi și cadre diferite.

În următorul articol despre Service Mesh, vom analiza una dintre cele mai mari probleme cu Istio - consumul mare de memorie RAM de către fiecare container proxy sidecar și vom discuta cum puteți face față acestuia.

Sursa: www.habr.com

Adauga un comentariu