So führen Sie Istio mit Kubernetes in der Produktion aus. Teil 1

Welche Istio? Hierbei handelt es sich um das sogenannte Service Mesh, eine Technologie, die dem Netzwerk eine Abstraktionsebene hinzufügt. Wir fangen den gesamten oder einen Teil des Datenverkehrs im Cluster ab und führen damit eine Reihe von Operationen durch. Welcher genau? Wir führen zum Beispiel intelligentes Routing durch oder implementieren den Circuit-Breaker-Ansatz, wir können die „Canary-Bereitstellung“ organisieren und den Datenverkehr teilweise auf eine neue Version des Dienstes umstellen, oder wir können externe Interaktionen begrenzen und alle Fahrten vom Cluster zum Cluster steuern externes Netzwerk. Es ist möglich, Richtlinienregeln festzulegen, um Fahrten zwischen verschiedenen Mikrodiensten zu steuern. Schließlich können wir die gesamte Netzwerkinteraktionskarte abrufen und die einheitliche Sammlung von Metriken für Anwendungen vollständig transparent machen.

Über den Arbeitsmechanismus können Sie in lesen amtliche Dokumentation. Istio ist ein wirklich leistungsstarkes Tool, mit dem Sie viele Aufgaben und Probleme lösen können. In diesem Artikel möchte ich die wichtigsten Fragen beantworten, die sich normalerweise beim Einstieg in Istio stellen. Dies wird Ihnen helfen, schneller damit umzugehen.

So führen Sie Istio mit Kubernetes in der Produktion aus. Teil 1

Arbeitsprinzip

Istio besteht aus zwei Hauptbereichen – der Kontrollebene und der Datenebene. Die Steuerebene enthält die Hauptkomponenten, die den ordnungsgemäßen Betrieb der übrigen Komponenten gewährleisten. In der aktuellen Version (1.0) besteht die Kontrollebene aus drei Hauptkomponenten: Pilot, Mixer, Citadel. Wir werden Citadel nicht berücksichtigen, es ist erforderlich, Zertifikate zu generieren, um gegenseitiges TLS zwischen Diensten sicherzustellen. Schauen wir uns das Gerät und den Zweck von Pilot und Mixer genauer an.

So führen Sie Istio mit Kubernetes in der Produktion aus. Teil 1

Pilot ist die Hauptsteuerungskomponente, die alle Informationen darüber verteilt, was wir im Cluster haben – Dienste, ihre Endpunkte und Routing-Regeln (z. B. Regeln für die Canary-Bereitstellung oder Regeln für Leistungsschalter).

Mixer ist eine optionale Steuerungsebenenkomponente, die die Möglichkeit bietet, Metriken, Protokolle und alle Informationen zur Netzwerkinteraktion zu sammeln. Er überwacht auch die Einhaltung der Richtlinienregeln und die Einhaltung der Tarifbegrenzungen.

Die Datenebene wird mithilfe von Sidecar-Proxy-Containern implementiert. Standardmäßig wird „Powerful“ verwendet. Gesandter-Proxy. Es kann durch eine andere Implementierung ersetzt werden, beispielsweise durch Nginx (Nginmesh).

Damit Istio für Anwendungen völlig transparent arbeitet, gibt es ein automatisches Injektionssystem. Die neueste Implementierung ist für Kubernetes 1.9+-Versionen geeignet (Mutational Admission Webhook). Für die Kubernetes-Versionen 1.7, 1.8 ist es möglich, den Initializer zu verwenden.

Sidecar-Container werden über das GRPC-Protokoll mit Pilot verbunden, wodurch Sie das Push-Modell für im Cluster auftretende Änderungen optimieren können. GRPC wird in Envoy seit Version 1.6 verwendet, in Istio wird es seit Version 0.8 verwendet und ist ein Pilot-Agent – ​​ein Golang-Wrapper über Envoy, der Startoptionen konfiguriert.

Pilot und Mixer sind völlig zustandslose Komponenten, alle Zustände werden im Speicher gehalten. Die Konfiguration für sie wird in Form von benutzerdefinierten Kubernetes-Ressourcen festgelegt, die in etcd gespeichert sind.
Der Istio-Agent ruft die Adresse des Piloten ab und öffnet einen GRPC-Stream dazu.

Wie gesagt, Istio implementiert alle Funktionen völlig transparent für Anwendungen. Mal sehen, wie. Der Algorithmus ist dieser:

  1. Bereitstellen einer neuen Version des Dienstes.
  2. Abhängig vom Sidecar-Container-Injektionsansatz werden der Istio-Init-Container und der Istio-Agent-Container (Envoy) in der Phase der Anwendung der Konfiguration hinzugefügt oder können bereits manuell in die Beschreibung der Kubernetes-Pod-Entität eingefügt werden.
  3. Der istio-init-Container ist ein Skript, das die iptables-Regeln auf den Pod anwendet. Es gibt zwei Möglichkeiten, den Datenverkehr so ​​zu konfigurieren, dass er in einen Istio-Agent-Container eingeschlossen wird: Verwenden Sie die Umleitungsregeln von iptables oder TPROXY. Zum Zeitpunkt des Verfassens dieses Artikels sind Umleitungsregeln der Standardansatz. In istio-init kann konfiguriert werden, welcher Datenverkehr abgefangen und an istio-agent gesendet werden soll. Um beispielsweise den gesamten eingehenden und ausgehenden Datenverkehr abzufangen, müssen Sie die Parameter festlegen -i и -b in die Bedeutung *. Sie können bestimmte Ports zum Abfangen angeben. Um ein bestimmtes Subnetz nicht abzufangen, können Sie es über das Flag angeben -x.
  4. Nachdem die Init-Container ausgeführt wurden, werden die wichtigsten gestartet, einschließlich des Pilot-Agenten (Gesandten). Es stellt über GRPC eine Verbindung zum bereits bereitgestellten Pilot her und erhält Informationen über alle vorhandenen Dienste und Routing-Richtlinien im Cluster. Basierend auf den erhaltenen Daten konfiguriert er die Cluster und weist sie direkt den Endpunkten unserer Anwendungen im Kubernetes-Cluster zu. Es ist auch notwendig, einen wichtigen Punkt zu beachten: Envoy konfiguriert dynamisch Listener (IP, Portpaare), die es zu überwachen beginnt. Wenn also Anfragen in den Pod gelangen und mithilfe der Iptables-Umleitungsregeln im Sidecar umgeleitet werden, kann Envoy diese Verbindungen bereits erfolgreich verarbeiten und verstehen, wohin der Datenverkehr weiter weitergeleitet werden soll. Außerdem werden in dieser Phase Informationen an den Mixer gesendet, auf die wir später noch eingehen werden, und es werden Ablaufverfolgungsspannen gesendet.

Als Ergebnis erhalten wir ein ganzes Netzwerk von Envoy-Proxyservern, die wir von einem Punkt aus konfigurieren können (Pilot). Alle eingehenden und ausgehenden Anfragen laufen über den Envoy. Darüber hinaus wird nur TCP-Verkehr abgefangen. Dies bedeutet, dass die Kubernetes-Dienst-IP ohne Änderung mithilfe von kube-dns über UDP aufgelöst wird. Nach der Auflösung wird die ausgehende Anfrage dann vom Envoy abgefangen und verarbeitet, der bereits entscheidet, an welchen Endpunkt die Anfrage gesendet werden soll (oder nicht gesendet werden soll, im Fall von Zugriffsrichtlinien oder dem Leistungsschalter des Algorithmus).

Wir haben Pilot herausgefunden, jetzt müssen wir verstehen, wie Mixer funktioniert und warum es benötigt wird. Sie können die offizielle Dokumentation dazu lesen hier.

Mixer in seiner aktuellen Form besteht aus zwei Komponenten: istio-telemetry und istio-policy (vor Version 0.8 war es eine istio-mixer-Komponente). Bei beiden handelt es sich um Mischer, von denen jeder für seine eigene Aufgabe zuständig ist. Istio-Telemetrie erhält Informationen darüber, wer wohin geht und mit welchen Parametern von Sidecar-Report-Containern über GRPC. Istio-policy akzeptiert Prüfanfragen, um zu überprüfen, ob die Richtlinienregeln erfüllt sind. Natürlich werden Richtlinienprüfungen nicht bei jeder Anfrage durchgeführt, sondern für eine bestimmte Zeit auf dem Client (im Sidecar) zwischengespeichert. Berichtsprüfungen werden als Batch-Anfragen gesendet. Sehen wir uns etwas später an, wie man konfiguriert und welche Parameter gesendet werden sollen.

Der Mixer soll eine hochverfügbare Komponente sein, die ein unterbrechungsfreies Arbeiten bei der Zusammenstellung und Verarbeitung von Telemetriedaten gewährleistet. Das System ergibt sich dadurch als mehrstufiger Puffer. Die Daten werden zunächst auf der Sidecar-Seite von Containern gepuffert, dann auf der Mixer-Seite und anschließend an die sogenannten Mixer-Backends gesendet. Wenn eine der Systemkomponenten ausfällt, wächst der Puffer und wird nach der Wiederherstellung des Systems geleert. Mixer-Backends sind Endpunkte zum Senden von Telemetriedaten: statsd, newrelic usw. Sie können Ihr eigenes Backend schreiben, es ist ganz einfach, und wir werden sehen, wie es geht.

So führen Sie Istio mit Kubernetes in der Produktion aus. Teil 1

Zusammenfassend sieht das Schema für die Arbeit mit Istio-Telemetrie wie folgt aus.

  1. Dienst 1 sendet eine Anfrage an Dienst 2.
  2. Beim Verlassen von Dienst 1 wird die Anfrage in einen eigenen Sidecar verpackt.
  3. Der Sidecar-Envoy überwacht, wie die Anfrage an Dienst 2 weitergeleitet wird, und bereitet die erforderlichen Informationen vor.
  4. Sendet es dann mithilfe einer Berichtsanforderung an istio-telemetry.
  5. Istio-Telemetrie bestimmt, ob dieser Bericht an die Backends gesendet werden soll, an welche und welche Daten gesendet werden sollen.
  6. Istio-Telemetry sendet bei Bedarf Berichtsdaten an das Backend.

Sehen wir uns nun an, wie Istio im System bereitgestellt wird, das nur aus den Hauptkomponenten (Pilot und Sidecar-Envoy) besteht.

Schauen wir uns zunächst die Hauptkonfiguration (Mesh) an, die Pilot liest:

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

Alle Hauptsteuerungskomponenten (Steuerungsebene) befinden sich im Namespace istio-system in Kubernetes.

Zumindest müssen wir nur Pilot bereitstellen. Dafür verwenden wir eine solche Konfiguration.

Und wir werden den injizierenden Sidecar des Containers manuell konfigurieren.

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

Und Beiwagen:

       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

Damit alles erfolgreich startet, müssen Sie ein ServiceAccount, ClusterRole, ClusterRoleBinding, CRD für Pilot erstellen, deren Beschreibungen zu finden sind hier.

Infolgedessen sollte der Dienst, in den wir Sidecar mit Envoy einbinden, erfolgreich starten, alle Entdeckungen vom Piloten erhalten und Anfragen verarbeiten.

Es ist wichtig zu verstehen, dass alle Komponenten der Steuerungsebene zustandslose Anwendungen sind und problemlos horizontal skaliert werden können. Alle Daten werden in etcd in Form benutzerdefinierter Beschreibungen von Kubernetes-Ressourcen gespeichert.

Außerdem verfügt Istio (noch experimentell) über die Möglichkeit, außerhalb des Clusters zu laufen und die Serviceerkennung zwischen mehreren Kubernetes-Clustern zu beobachten und zu manipulieren. Mehr dazu können Sie hier lesen hier.

Beachten Sie bei einer Multi-Cluster-Installation die folgenden Einschränkungen:

  1. Pod-CIDR und Service-CIDR müssen in allen Clustern eindeutig sein und dürfen sich nicht überschneiden.
  2. Auf alle CIDR-Pods muss von allen CIDR-Pods zwischen Clustern aus zugegriffen werden können.
  3. Alle Kubernetes-API-Server müssen füreinander zugänglich sein.

Dies sind die ersten Informationen, die Ihnen den Einstieg in Istio erleichtern sollen. Allerdings gibt es noch viele Fallstricke. Zum Beispiel Funktionen zum Weiterleiten von externem Datenverkehr (außerhalb des Clusters), Ansätze zum Debuggen von Sidecars, Profiling, Einrichten eines Mixers und Schreiben eines benutzerdefinierten Mixer-Backends, Einrichten eines Tracing-Mechanismus und dessen Betrieb mithilfe von Envoy.
All dies werden wir in den folgenden Veröffentlichungen berücksichtigen. Stellen Sie Ihre Fragen, ich werde versuchen, sie zu beantworten.

Source: habr.com

Kommentar hinzufügen