Istio e Kubernetes in produzione. Parte 2. Tracing

Nell'articolo precedente abbiamo chiarito il corretto completamento dei programmi che utilizzano il mediastreamer. Abbiamo esaminato i componenti di base del Service Mesh Istio, ci siamo familiarizzati con il sistema e abbiamo risposto alle domande principali che solitamente sorgono all'inizio dell'utilizzo di Istio. In questa parte, vedremo come organizzare la raccolta di informazioni di tracing attraverso la rete.

Istio e Kubernetes in produzione. Parte 2. Tracing

La prima cosa che viene in mente a molti sviluppatori e amministratori di sistema quando sentono le parole Service Mesh è il tracing. È vero, aggiungiamo un proxy server speciale a ogni nodo della rete, attraverso il quale passa tutto il traffico TCP. Sembra che ora sia facile inviare informazioni su tutte le interazioni di rete. Purtroppo, in realtà ci sono molte sfumature da considerare. Vediamole.

Fraintendimento numero uno: possiamo ottenere dati sul traffico di rete gratuitamente.

In realtà, relativamente gratuitamente possiamo solo ottenere i nodi della nostra sistema connessi da frecce e il rate dei dati che passa tra i servizi (in sostanza, solo la quantità di byte per unità di tempo). Tuttavia, nella maggior parte dei casi, i nostri servizi comunicano tramite qualche protocollo di livello applicativo, come HTTP, gRPC, Redis e così via. E, naturalmente, vogliamo vedere informazioni di tracing proprio su questi protocolli, vogliamo vedere il rate delle richieste, non il rate dei dati. Vogliamo comprendere la latenza delle richieste secondo il nostro protocollo. Infine, vogliamo vedere il percorso completo che una richiesta compie dall’ingresso nel nostro sistema fino alla ricezione della risposta da parte dell’utente. Questo compito non è facile da risolvere.

Per iniziare, vediamo come appare l'invio dei tracing span dal punto di vista architettonico in Istio. Come abbiamo ricordato nella prima parte, Istio ha un componente separato per la raccolta della telemetria, chiamato Mixer. Tuttavia, nella versione attuale 1.0.*, l'invio avviene direttamente dai server proxy, in particolare, dal proxy envoy. Il proxy envoy supporta l'invio dei tracing span tramite il protocollo zipkin out-of-the-box. Altri protocolli possono essere integrati, ma solo tramite plugin. Con Istio, otteniamo immediatamente un proxy envoy configurato e pronto all'uso, che supporta solo il protocollo zipkin. Se desideriamo utilizzare, ad esempio, il protocollo Jaeger e inviare i tracing span tramite UDP, dobbiamo creare la nostra immagine istio-proxy. Il supporto per plugin personalizzati per istio-proxy esiste, ma è ancora in versione alpha. Pertanto, se vogliamo evitarci un numero elevato di configurazioni personalizzate, il cerchio delle tecnologie utilizzate per memorizzare e ricevere i tracing span si riduce. Tra le principali, attualmente si può usare solo Zipkin, oppure Jaeger, ma tutto deve essere inviato tramite un protocollo compatibile con zipkin (cosa decisamente meno efficiente). Il protocollo zipkin prevede l'invio di tutte le informazioni di tracing ai collettori tramite protocollo HTTP, il che è piuttosto oneroso.

Come ho già detto, vogliamo tracciare i protocolli di livello applicativo. Questo significa che i server proxy, che si trovano accanto a ciascun servizio, devono comprendere quale interazione si sta verificando in questo momento. Di default, Istio configura tutti i porti come tipo TCP semplice, il che significa che non verranno inviati tracciamenti. Per far sì che i tracciamenti vengano inviati, è necessario, innanzitutto, attivare tale opzione nella configurazione mesh principale e, cosa molto importante, nominare tutti i porti delle entità service di kubernetes in conformità al protocollo utilizzato nel servizio. Cioè, ad esempio, in questo modo:

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

È possibile utilizzare anche nomi compositi, ad esempio http-magic (Istio vedrà http e riconoscerà questo porto come endpoint http). Il formato è: proto-extra.

Per evitare di dover patchare un'enorme quantità di configurazioni per definire il protocollo, è possibile utilizzare un workaround sporco: patchare il componente Pilot nel momento in cui esegue la logica di definizione del protocollo. Esegue la logica di definizione del protocollo.. Alla fine, dovremo certamente modificare questa logica in una standard e adottare una convenzione di denominazione per tutte le porte.

Per comprendere se il protocollo è definito correttamente, è necessario accedere a uno qualsiasi dei contenitori sidecar con envoy proxy e fare una richiesta sulla porta dell'interfaccia admin di envoy con la location /config_dump. Nella configurazione risultante, bisogna controllare il campo operation del servizio desiderato. Questo viene utilizzato in Istio come identificatore della destinazione della richiesta. Per personalizzare in Istio il valore di questo parametro (che poi vedremo nel nostro sistema di tracciamento), è necessario specificare il flag serviceCluster al momento dell'avvio del contenitore sidecar. Ad esempio, può essere calcolato in questo modo dalle variabili ottenute dall'API downward di kubernetes:

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

Un buon esempio per comprendere come funziona il tracciamento in envoy è qui.

L'endpoint stesso per inviare gli span di tracciamento deve essere specificato anche nei flag di avvio dell'envoy proxy, ad esempio: --zipkinAddress tracing-collector.tracing:9411

Malinteso numero due: possiamo ottenere senza costi elevati tracce complete del passaggio delle richieste nel sistema out-of-the-box.

Purtroppo non è così. La complessità di implementazione dipende dal modo in cui è già realizzata l'interazione tra i servizi. Perché?

Il fatto è che affinché istio-proxy possa capire la corrispondenza delle richieste in entrata a un servizio con quelle in uscita dallo stesso servizio, non è sufficiente intercettare tutto il traffico. È necessario avere un identificatore di correlazione. In HTTP, l'envoy proxy utilizza intestazioni speciali, in base alle quali envoy comprende quale specifico request al servizio generi richieste particolari ad altri servizi. L'elenco di queste intestazioni è:

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

Se hai un punto unico, ad esempio un client di base, in cui puoi aggiungere tale logica, allora va tutto bene, dovrai solo aspettare che questa libreria venga aggiornata in tutti i client. Ma se hai un sistema molto eterogeneo e non c'è un'unificazione nel modo in cui i servizi comunicano tra loro in rete, allora probabilmente sarà un grande problema. Senza l'aggiunta di tale logica, tutte le informazioni di tracciamento saranno solo "a un livello". Cioè, otterremo tutte le interazioni tra i servizi, ma queste non saranno collegate in un'unica catena attraverso la rete.

Conclusione

Istio offre uno strumento utile per la raccolta di informazioni di tracing attraverso la rete, ma è importante comprendere che per implementarlo sarà necessario adattare il proprio sistema e considerare le peculiarità della realizzazione di Istio. In definitiva, è necessario risolvere due questioni principali: la definizione del protocollo applicativo (che deve essere supportato da envoy proxy) e la configurazione del passaggio delle informazioni sulla correlazione delle richieste nel servizio a partire dalle richieste provenienti da altri servizi (tramite header, nel caso di un protocollo HTTP). Una volta risolti questi problemi, avremo a disposizione uno strumento potente che consente di raccogliere trasparentemente informazioni dalla rete anche in sistemi molto eterogenei, sviluppati in un'ampia varietà di linguaggi e framework.

Nell'articolo successivo su Service Mesh esamineremo uno dei principali problemi di Istio: l'elevato consumo di memoria da parte di ogni container sidecar proxy e discuteremo come affrontarlo.

Fonte: habr.com

Acquista hosting affidabile per siti web con protezione DDoS, VPS VDS server 🔥 Acquista hosting affidabile per siti web con protezione DDoS, VPS VDS server | ProHoster