Cum să rulați Istio folosind Kubernetes în producție. Partea 1

Ce este Istio? Aceasta este așa-numita plasă de servicii, o tehnologie care adaugă un strat de abstractizare în rețea. Interceptăm tot sau o parte din traficul din cluster și efectuăm un anumit set de operațiuni cu acesta. Care? De exemplu, facem rutare inteligentă sau implementăm abordarea întrerupător de circuit, putem organiza „implementarea canarului”, schimbând parțial traficul la o nouă versiune a serviciului sau putem limita interacțiunile externe și controlăm toate călătoriile de la cluster la rețea externă. Este posibil să setați reguli de politică pentru a controla călătoriile între diferite microservicii. În cele din urmă, putem obține întreaga hartă de interacțiune a rețelei și putem face colecția unificată de valori complet transparentă pentru aplicații.

Puteți citi despre mecanismul de lucru în documentație oficială. Istio este un instrument cu adevărat puternic care vă permite să rezolvați multe sarcini și probleme. În acest articol, aș dori să răspund la principalele întrebări care apar de obicei atunci când începem cu Istio. Acest lucru vă va ajuta să faceți față mai rapid.

Cum să rulați Istio folosind Kubernetes în producție. Partea 1

Principiul de funcționare

Istio este format din două zone principale - planul de control și planul de date. Planul de control conține principalele componente care asigură funcționarea corectă a restului. În versiunea actuală (1.0) planul de control are trei componente principale: Pilot, Mixer, Citadelă. Nu vom lua în considerare Citadel, este nevoie să generăm certificate pentru a asigura TLS reciproc între servicii. Să aruncăm o privire mai atentă la dispozitivul și scopul Pilot și Mixer.

Cum să rulați Istio folosind Kubernetes în producție. Partea 1

Pilot este componenta principală de control care distribuie toate informațiile despre ceea ce avem în cluster - servicii, punctele finale ale acestora și regulile de rutare (de exemplu, reguli pentru implementarea Canary sau reguli de întrerupător).

Mixer este o componentă opțională a planului de control care oferă posibilitatea de a colecta valori, jurnalele și orice informații despre interacțiunea cu rețea. El monitorizează, de asemenea, respectarea regulilor Politicii și respectarea limitelor ratelor.

Planul de date este implementat folosind containere proxy sidecar. Puternic este folosit în mod implicit. mandatar trimis. Poate fi înlocuit cu o altă implementare, cum ar fi nginx (nginmesh).

Pentru ca Istio să funcționeze complet transparent pentru aplicații, există un sistem automat de injecție. Cea mai recentă implementare este potrivită pentru versiunile Kubernetes 1.9+ (webhook de admitere mutațională). Pentru versiunile Kubernetes 1.7, 1.8 este posibil să utilizați inițializatorul.

Containerele sidecar sunt conectate la Pilot folosind protocolul GRPC, care vă permite să optimizați modelul push pentru modificările care apar în cluster. GRPC a fost folosit în Envoy începând cu versiunea 1.6, în Istio a fost folosit începând cu versiunea 0.8 și este un pilot-agent - un golang wrapper peste envoy care configurează opțiunile de lansare.

Pilot și Mixer sunt componente complet apatride, toate stările sunt păstrate în memorie. Configurația pentru acestea este setată sub formă de resurse personalizate Kubernetes, care sunt stocate în etcd.
Istio-agent primește adresa Pilotului și îi deschide un flux GRPC.

După cum am spus, Istio implementează toate funcționalitățile complet transparente pentru aplicații. Să vedem cum. Algoritmul este acesta:

  1. Implementarea unei noi versiuni a serviciului.
  2. În funcție de abordarea injectării containerului sidecar, containerul istio-init și containerul istio-agent (envoy) sunt adăugate în etapa de aplicare a configurației sau pot fi deja inserate manual în descrierea entității Kubernetes Pod.
  3. Containerul istio-init este un script care aplică regulile iptables la pod. Există două opțiuni pentru configurarea traficului pentru a fi împachetat într-un container istio-agent: utilizați regulile de redirecționare iptables sau TPROXY. La momentul scrierii, abordarea implicită este cu reguli de redirecționare. În istio-init, este posibil să configurați ce trafic trebuie interceptat și trimis către istio-agent. De exemplu, pentru a intercepta tot traficul de intrare și de ieșire, trebuie să setați parametrii -i и -b în sens *. Puteți specifica anumite porturi de interceptat. Pentru a nu intercepta o anumită subrețea, o puteți specifica folosind steag -x.
  4. După executarea containerelor init, sunt lansate cele principale, inclusiv pilotul-agent (trimis). Se conectează la Pilot deja implementat prin GRPC și primește informații despre toate serviciile existente și politicile de rutare din cluster. Conform datelor primite, el configurează clusterele și le atribuie direct punctelor finale ale aplicațiilor noastre din clusterul Kubernetes. De asemenea, este necesar să rețineți un punct important: envoy configurează în mod dinamic ascultătorii (IP, perechi de porturi) pe care începe să îi asculte. Prin urmare, atunci când solicitările intră în pod, sunt redirecționate folosind regulile iptables de redirecționare din sidecar, envoy poate deja procesa cu succes aceste conexiuni și poate înțelege unde să proxy traficul. Tot în această etapă, informațiile sunt trimise la Mixer, pe care ne vom uita mai târziu, și sunt trimise intervale de urmărire.

Drept urmare, obținem o întreagă rețea de servere proxy envoy pe care le putem configura dintr-un punct (Pilot). Toate cererile de intrare și de ieșire trec prin envoy. Mai mult, doar traficul TCP este interceptat. Aceasta înseamnă că IP-ul serviciului Kubernetes este rezolvat folosind kube-dns peste UDP fără a fi modificat. Apoi, după rezolvare, cererea de ieșire este interceptată și procesată de către trimis, care decide deja la ce punct final trebuie trimisă cererea (sau nu, în cazul politicilor de acces sau a întrerupătorului algoritmului).

Ne-am dat seama de Pilot, acum trebuie să înțelegem cum funcționează Mixer și de ce este necesar. Puteți citi documentația oficială pentru aceasta aici.

Mixer în forma sa actuală constă din două componente: istio-telemetrie, istio-politică (înainte de versiunea 0.8 era o componentă istio-mixer). Ambele sunt mixere, fiecare fiind responsabil pentru propria sa sarcină. Telemetria Istio primește informații despre cine merge unde și cu ce parametri de la containerele de raportare sidecar prin GRPC. Istio-policy acceptă solicitările de verificare pentru a verifica dacă regulile politicii sunt îndeplinite. Verificările Poilicy, desigur, nu sunt efectuate pentru fiecare cerere, dar sunt stocate în cache pe client (în sidecar) pentru un anumit timp. Verificările rapoartelor sunt trimise ca solicitări de lot. Să vedem cum se configurează și ce parametri ar trebui să fie trimiși puțin mai târziu.

Mixerul ar trebui să fie o componentă foarte disponibilă care asigură lucrul neîntrerupt la asamblarea și procesarea datelor de telemetrie. Sistemul este obținut ca rezultat ca un tampon cu mai multe niveluri. Inițial, datele sunt stocate în tampon pe partea laterală a containerelor, apoi pe partea mixerului și apoi trimise la așa-numitele backend-uri ale mixerului. Ca rezultat, dacă oricare dintre componentele sistemului eșuează, tamponul crește și este golit după ce sistemul este restaurat. Backend-urile mixerului sunt puncte finale pentru trimiterea datelor de telemetrie: statsd, newrelic etc. Îți poți scrie propriul backend, este destul de simplu și vom vedea cum să o facem.

Cum să rulați Istio folosind Kubernetes în producție. Partea 1

Pentru a rezuma, schema de lucru cu istio-telemetrie este următoarea.

  1. Serviciul 1 trimite o cerere către serviciul 2.
  2. La părăsirea serviciului 1, cererea este ambalată în propriul sidecar.
  3. Sidecar envoy monitorizează modul în care cererea ajunge la serviciul 2 și pregătește informațiile necesare.
  4. Apoi îl trimite către istio-telemetry folosind o solicitare de raportare.
  5. Istio-telemetria determină dacă acest Raport trebuie trimis către backend-uri, către care și ce date trebuie trimise.
  6. Istio-telemetry trimite datele de raport la backend, dacă este necesar.

Acum să vedem cum să implementăm Istio în sistem, constând doar din componentele principale (pilot și sidecar envoy).

Mai întâi, să ne uităm la configurația principală (mesh) pe care o citește Pilot:

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

Toate componentele principale de control (planul de control) vor fi localizate în sistemul istio-spațiu de nume din Kubernetes.

Cel puțin, trebuie doar să implementăm Pilot. Pentru aceasta folosim o astfel de configurație.

Și vom configura manual sidecarul de injectare al containerului.

Init container:

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

Si 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

Pentru ca totul să înceapă cu succes, trebuie să creați un ServiceAccount, ClusterRole, ClusterRoleBinding, CRD pentru Pilot, ale căror descrieri pot fi găsite aici.

Drept urmare, serviciul în care injectăm sidecar cu envoy ar trebui să înceapă cu succes, să primească toate descoperirile de la pilot și să proceseze cererile.

Este important să înțelegeți că toate componentele planului de control sunt aplicații apatride și pot fi scalate orizontal fără probleme. Toate datele sunt stocate în etcd sub formă de descrieri personalizate ale resurselor Kubernetes.

De asemenea, Istio (încă experimental) are capacitatea de a rula în afara clusterului și abilitatea de a urmări și de a detecta descoperirea serviciilor între mai multe clustere Kubernetes. Puteți citi mai multe despre asta aici.

Pentru o instalare cu mai multe clustere, fiți conștienți de următoarele limitări:

  1. Pod CIDR și Service CIDR trebuie să fie unice în toate clusterele și nu trebuie să se suprapună.
  2. Toate podurile CIDR trebuie să fie accesibile din orice poduri CIDR dintre clustere.
  3. Toate serverele API Kubernetes trebuie să fie accesibile unul altuia.

Acestea sunt informațiile inițiale care vă vor ajuta să începeți cu Istio. Cu toate acestea, există încă multe capcane. De exemplu, caracteristici de rutare a traficului extern (în afara clusterului), abordări pentru depanarea sidecar-urilor, profilare, configurarea unui mixer și scrierea unui backend de mixer personalizat, configurarea unui mecanism de urmărire și funcționarea acestuia folosind Envoy.
Toate acestea le vom lua în considerare în următoarele publicații. Pune-ți întrebările, voi încerca să le acopăr.

Sursa: www.habr.com

Adauga un comentariu