Come eseguire Istio utilizzando Kubernetes in produzione. Parte 1

che cosa Istio? Questa è la cosiddetta Service mesh, una tecnologia che aggiunge uno strato di astrazione sulla rete. Intercettiamo tutto o parte del traffico nel cluster ed eseguiamo un certo insieme di operazioni con esso. Quale? Ad esempio, eseguiamo il routing intelligente o implementiamo l'approccio dell'interruttore di circuito, possiamo organizzare il "deployment canary", spostando parzialmente il traffico a una nuova versione del servizio, oppure possiamo limitare le interazioni esterne e controllare tutti i viaggi dal cluster al rete esterna. È possibile impostare regole di criteri per controllare i viaggi tra diversi microservizi. Infine, possiamo ottenere l'intera mappa delle interazioni di rete e rendere la raccolta unificata di metriche completamente trasparente per le applicazioni.

Puoi leggere il meccanismo di lavoro in documentazione ufficiale. Istio è uno strumento davvero potente che ti consente di risolvere molti compiti e problemi. In questo articolo, vorrei rispondere alle domande principali che di solito sorgono quando si inizia a utilizzare Istio. Questo ti aiuterà ad affrontarlo più velocemente.

Come eseguire Istio utilizzando Kubernetes in produzione. Parte 1

Come funziona

Istio è costituito da due aree principali: il piano di controllo e il piano dati. Il piano di controllo contiene i componenti principali che assicurano il corretto funzionamento del resto. Nella versione attuale (1.0) il piano di controllo ha tre componenti principali: Pilot, Mixer, Citadel. Non prenderemo in considerazione Citadel, è necessario generare certificati per garantire il TLS reciproco tra i servizi. Diamo un'occhiata più da vicino al dispositivo e allo scopo di Pilot e Mixer.

Come eseguire Istio utilizzando Kubernetes in produzione. Parte 1

Pilot è il componente di controllo principale che distribuisce tutte le informazioni su ciò che abbiamo nel cluster: i servizi, i loro endpoint e le regole di instradamento (ad esempio, le regole per la distribuzione di Canary o le regole dell'interruttore automatico).

Mixer è un componente del piano di controllo facoltativo che offre la possibilità di raccogliere metriche, registri e qualsiasi informazione sull'interazione di rete. Monitora inoltre il rispetto delle regole della politica e il rispetto dei limiti tariffari.

Il piano dati viene implementato utilizzando contenitori proxy sidecar. Potente è utilizzato per impostazione predefinita. delegato dell'inviato. Può essere sostituito da un'altra implementazione, come nginx (nginmesh).

Affinché Istio funzioni in modo completamente trasparente alle applicazioni, esiste un sistema di iniezione automatica. L'ultima implementazione è adatta per le versioni Kubernetes 1.9+ (webhook di ammissione mutazionale). Per le versioni Kubernetes 1.7, 1.8 è possibile utilizzare l'inizializzatore.

I contenitori sidecar sono connessi a Pilot tramite il protocollo GRPC, che consente di ottimizzare il modello push per le modifiche che si verificano nel cluster. GRPC è stato utilizzato in Envoy dalla versione 1.6, in Istio è stato utilizzato dalla versione 0.8 ed è un agente pilota, un wrapper golang su envoy che configura le opzioni di avvio.

Pilot e Mixer sono componenti completamente privi di stato, tutti gli stati sono mantenuti in memoria. La loro configurazione è impostata sotto forma di risorse personalizzate Kubernetes, che sono archiviate in etcd.
Istio-agent ottiene l'indirizzo del pilota e gli apre un flusso GRPC.

Come ho detto, Istio implementa tutte le funzionalità in modo completamente trasparente alle applicazioni. Vediamo come. L'algoritmo è questo:

  1. Distribuzione di una nuova versione del servizio.
  2. A seconda dell'approccio di iniezione del contenitore sidecar, il contenitore istio-init e il contenitore istio-agent (envoy) vengono aggiunti nella fase di applicazione della configurazione oppure possono essere già inseriti manualmente nella descrizione dell'entità Kubernetes Pod.
  3. Il contenitore istio-init è uno script che applica le regole di iptables al pod. Ci sono due opzioni per configurare il traffico da racchiudere in un contenitore istio-agent: utilizzare le regole di reindirizzamento di iptables o PROXY. Al momento della scrittura, l'approccio predefinito prevede regole di reindirizzamento. In istio-init è possibile configurare quale traffico deve essere intercettato e inviato a istio-agent. Ad esempio, per intercettare tutto il traffico in entrata e in uscita è necessario impostare i parametri -i и -b nel significato *. È possibile specificare porte specifiche da intercettare. Per non intercettare una sottorete specifica, puoi specificarla utilizzando il flag -x.
  4. Dopo che i contenitori init sono stati eseguiti, vengono lanciati quelli principali, compreso l'agente pilota (inviato). Si connette al pilota già distribuito tramite GRPC e riceve informazioni su tutti i servizi esistenti e le politiche di instradamento nel cluster. In base ai dati ricevuti, configura i cluster e li assegna direttamente agli endpoint delle nostre applicazioni nel cluster Kubernetes. È inoltre necessario notare un punto importante: envoy configura dinamicamente gli ascoltatori (IP, coppie di porte) che inizia ad ascoltare. Pertanto, quando le richieste entrano nel pod e vengono reindirizzate utilizzando le regole di reindirizzamento di iptables nel sidecar, envoy può già elaborare correttamente queste connessioni e capire dove inoltrare ulteriormente il traffico. Anche in questa fase, le informazioni vengono inviate al Mixer, che esamineremo in seguito, e vengono inviati gli intervalli di tracciamento.

Di conseguenza, otteniamo un'intera rete di server proxy di invio che possiamo configurare da un punto (pilota). Tutte le richieste in entrata e in uscita passano attraverso envoy. Inoltre, viene intercettato solo il traffico TCP. Ciò significa che l'IP del servizio Kubernetes viene risolto utilizzando kube-dns su UDP senza modifiche. Quindi, dopo la risoluzione, la richiesta in uscita viene intercettata ed elaborata da envoy, che decide già a quale endpoint inviare la richiesta (o non inviarla, nel caso delle policy di accesso o del circuit breaker dell'algoritmo).

Abbiamo capito Pilot, ora dobbiamo capire come funziona Mixer e perché è necessario. Puoi leggere la documentazione ufficiale per questo qui.

Mixer nella sua forma attuale è costituito da due componenti: istio-telemetry, istio-policy (prima della versione 0.8 era un componente istio-mixer). Entrambi sono mixer, ognuno dei quali è responsabile del proprio compito. La telemetria di Istio riceve informazioni su chi va dove e con quali parametri dai contenitori di report sidecar tramite GRPC. Istio-policy accetta le richieste di controllo per verificare che le regole della politica siano soddisfatte. I controlli di politica, ovviamente, non vengono eseguiti per ogni richiesta, ma vengono memorizzati nella cache del client (nel sidecar) per un certo tempo. I controlli dei report vengono inviati come richieste batch. Vediamo come configurare e quali parametri dovrebbero essere inviati un po 'più tardi.

Il Mixer dovrebbe essere un componente altamente disponibile che garantisce un lavoro ininterrotto sull'assemblaggio e l'elaborazione dei dati di telemetria. Il sistema si ottiene come risultato come buffer multilivello. Inizialmente, i dati vengono bufferizzati sul lato sidecar dei container, quindi sul lato mixer e quindi inviati ai cosiddetti backend mixer. Di conseguenza, se uno dei componenti del sistema si guasta, il buffer aumenta e viene svuotato dopo il ripristino del sistema. I backend del mixer sono endpoint per l'invio di dati di telemetria: statsd, newrelic, ecc. Puoi scrivere il tuo backend, è abbastanza semplice e vedremo come farlo.

Come eseguire Istio utilizzando Kubernetes in produzione. Parte 1

Per riassumere, lo schema per lavorare con l'istio-telemetria è il seguente.

  1. Il servizio 1 invia una richiesta al servizio 2.
  2. All'uscita dal servizio 1, la richiesta viene avvolta nel proprio sidecar.
  3. Sidecar envoy monitora come la richiesta va al servizio 2 e prepara le informazioni necessarie.
  4. Quindi lo invia a istio-telemetry utilizzando una richiesta Report.
  5. Istio-telemetry determina se questo report deve essere inviato ai backend, a quali e quali dati devono essere inviati.
  6. Istio-telemetry invia i dati del rapporto al back-end, se necessario.

Vediamo ora come implementare Istio nel sistema, costituito solo dai componenti principali (Pilot e sidecar envoy).

Innanzitutto, diamo un'occhiata alla configurazione principale (mesh) che Pilot legge:

apiVersion: v1
kind: ConfigMap
metadata:
  name: istio
  namespace: istio-system
  labels:
    app: istio
    service: istio
data:
  mesh: |-

    # пока что не включаем отправку tracing информации (pilot настроит envoy’и таким образом, что отправка не будет происходить)
    enableTracing: false

    # пока что не указываем mixer endpoint’ы, чтобы sidecar контейнеры не отправляли информацию туда
    #mixerCheckServer: istio-policy.istio-system:15004
    #mixerReportServer: istio-telemetry.istio-system:15004

    # ставим временной промежуток, с которым будет envoy переспрашивать Pilot (это для старой версии envoy proxy)
    rdsRefreshDelay: 5s

    # default конфигурация для envoy sidecar
    defaultConfig:
      # аналогично как rdsRefreshDelay
      discoveryRefreshDelay: 5s

      # оставляем по умолчанию (путь к конфигурации и бинарю envoy)
      configPath: "/etc/istio/proxy"
      binaryPath: "/usr/local/bin/envoy"

      # дефолтное имя запущенного sidecar контейнера (используется, например, в именах сервиса при отправке tracing span’ов)
      serviceCluster: istio-proxy

      # время, которое будет ждать envoy до того, как он принудительно завершит все установленные соединения
      drainDuration: 45s
      parentShutdownDuration: 1m0s

      # по умолчанию используются REDIRECT правила iptables. Можно изменить на TPROXY.
      #interceptionMode: REDIRECT

      # Порт, на котором будет запущена admin панель каждого sidecar контейнера (envoy)
      proxyAdminPort: 15000

      # адрес, по которому будут отправляться trace’ы по zipkin протоколу (в начале мы отключили саму отправку, поэтому это поле сейчас не будет использоваться)
      zipkinAddress: tracing-collector.tracing:9411

      # statsd адрес для отправки метрик envoy контейнеров (отключаем)
      # statsdUdpAddress: aggregator:8126

      # выключаем поддержку опции Mutual TLS
      controlPlaneAuthPolicy: NONE

      # адрес, на котором будет слушать istio-pilot для того, чтобы сообщать информацию о service discovery всем sidecar контейнерам
      discoveryAddress: istio-pilot.istio-system:15007

Tutti i principali componenti di controllo (piano di controllo) si troveranno nello spazio dei nomi istio-system in Kubernetes.

Come minimo, dobbiamo solo distribuire Pilot. Per questo useremo una tale configurazione.

E configureremo manualmente il sidecar di iniezione del contenitore.

Contenitore di inizializzazione:

initContainers:
 - name: istio-init
   args:
   - -p
   - "15001"
   - -u
   - "1337"
   - -m
   - REDIRECT
   - -i
   - '*'
   - -b
   - '*'
   - -d
   - ""
   image: istio/proxy_init:1.0.0
   imagePullPolicy: IfNotPresent
   resources:
     limits:
       memory: 128Mi
   securityContext:
     capabilities:
       add:
       - NET_ADMIN

E sidecar:

       name: istio-proxy
       args:
         - "bash"
         - "-c"
         - |
           exec /usr/local/bin/pilot-agent proxy sidecar 
           --configPath 
           /etc/istio/proxy 
           --binaryPath 
           /usr/local/bin/envoy 
           --serviceCluster 
           service-name 
           --drainDuration 
           45s 
           --parentShutdownDuration 
           1m0s 
           --discoveryAddress 
           istio-pilot.istio-system:15007 
           --discoveryRefreshDelay 
           1s 
           --connectTimeout 
           10s 
           --proxyAdminPort 
           "15000" 
           --controlPlaneAuthPolicy 
           NONE
         env:
         - name: POD_NAME
           valueFrom:
             fieldRef:
               fieldPath: metadata.name
         - name: POD_NAMESPACE
           valueFrom:
             fieldRef:
               fieldPath: metadata.namespace
         - name: INSTANCE_IP
           valueFrom:
             fieldRef:
               fieldPath: status.podIP
         - name: ISTIO_META_POD_NAME
           valueFrom:
             fieldRef:
               fieldPath: metadata.name
         - name: ISTIO_META_INTERCEPTION_MODE
           value: REDIRECT
         image: istio/proxyv2:1.0.0
         imagePullPolicy: IfNotPresent
         resources:
           requests:
             cpu: 100m
             memory: 128Mi
           limits:
             memory: 2048Mi
         securityContext:
           privileged: false
           readOnlyRootFilesystem: true
           runAsUser: 1337
         volumeMounts:
         - mountPath: /etc/istio/proxy
           name: istio-envoy

Affinché tutto si avvii correttamente, è necessario creare un ServiceAccount, ClusterRole, ClusterRoleBinding, CRD per Pilot, le cui descrizioni possono essere trovate qui.

Di conseguenza, il servizio in cui inseriamo il sidecar con envoy dovrebbe avviarsi correttamente, ricevere tutte le scoperte dal pilota ed elaborare le richieste.

È importante comprendere che tutti i componenti del piano di controllo sono applicazioni stateless e possono essere scalati orizzontalmente senza problemi. Tutti i dati vengono archiviati in etcd sotto forma di descrizioni personalizzate delle risorse Kubernetes.

Inoltre, Istio (ancora sperimentale) ha la capacità di funzionare al di fuori del cluster e la capacità di osservare e armeggiare la scoperta di servizi tra diversi cluster Kubernetes. Puoi leggere di più su questo qui.

Per un'installazione multi-cluster, tenere presente le seguenti limitazioni:

  1. Il CIDR del pod e il CIDR del servizio devono essere univoci in tutti i cluster e non devono sovrapporsi.
  2. Tutti i pod CIDR devono essere accessibili da qualsiasi pod CIDR tra i cluster.
  3. Tutti i server API Kubernetes devono essere reciprocamente accessibili.

Queste sono le informazioni iniziali per aiutarti a iniziare con Istio. Tuttavia, ci sono ancora molte insidie. Ad esempio, le funzionalità di instradamento del traffico esterno (all'esterno del cluster), gli approcci al debug dei sidecar, la profilazione, l'impostazione di un mixer e la scrittura di un back-end del mixer personalizzato, l'impostazione di un meccanismo di tracciamento e il suo funzionamento tramite envoy.
Tutto ciò che prenderemo in considerazione nelle seguenti pubblicazioni. Fai le tue domande, cercherò di coprirle.

Fonte: habr.com

Aggiungi un commento