Comment exécuter Istio à l'aide de Kubernetes en production. Partie 1

Qu'est-ce que Istio? C'est ce qu'on appelle le service mesh, une technologie qui ajoute une couche d'abstraction sur le réseau. Nous interceptons tout ou partie du trafic dans le cluster et effectuons un certain ensemble d'opérations avec celui-ci. Lequel? Par exemple, on fait du routage intelligent, ou on met en place l'approche disjoncteur, on peut organiser le « déploiement canari », basculer partiellement le trafic vers une nouvelle version du service, ou on peut limiter les interactions externes et contrôler tous les déplacements du cluster vers le réseau externe. Il est possible de définir des règles de politique pour contrôler les déplacements entre différents microservices. Enfin, nous pouvons obtenir l'ensemble de la carte d'interaction réseau et rendre la collection unifiée de métriques complètement transparente pour les applications.

Vous pouvez lire sur le mécanisme de travail dans documents officiels. Istio est un outil vraiment puissant qui vous permet de résoudre de nombreuses tâches et problèmes. Dans cet article, je souhaite répondre aux principales questions qui se posent généralement lors de la prise en main d'Istio. Cela vous aidera à y faire face plus rapidement.

Comment exécuter Istio à l'aide de Kubernetes en production. Partie 1

Comment ça marche?

Istio se compose de deux zones principales : le plan de contrôle et le plan de données. Le plan de contrôle contient les principaux composants qui assurent le bon fonctionnement du reste. Dans la version actuelle (1.0), le plan de contrôle comporte trois composants principaux : Pilot, Mixer, Citadel. Nous ne considérerons pas Citadel, il est nécessaire de générer des certificats pour assurer le TLS mutuel entre les services. Examinons de plus près l'appareil et le but de Pilot et Mixer.

Comment exécuter Istio à l'aide de Kubernetes en production. Partie 1

Pilot est le composant de contrôle principal qui distribue toutes les informations sur ce que nous avons dans le cluster - les services, leurs points de terminaison et les règles de routage (par exemple, les règles de déploiement Canary ou les règles de disjoncteur).

Mixer est un composant de plan de contrôle facultatif qui permet de collecter des métriques, des journaux et toute information sur l'interaction réseau. Il surveille également le respect des règles de la politique et le respect des limites de taux.

Le plan de données est implémenté à l'aide de conteneurs proxy side-car. Puissant est utilisé par défaut. mandataire d'envoyé. Il peut être remplacé par une autre implémentation, telle que nginx (nginmesh).

Pour qu'Istio fonctionne en toute transparence vis-à-vis des applications, il existe un système d'injection automatique. La dernière implémentation est adaptée aux versions Kubernetes 1.9+ (webhook d'admission mutationnelle). Pour les versions 1.7, 1.8 de Kubernetes, il est possible d'utiliser l'initialiseur.

Les conteneurs sidecar sont connectés à Pilot à l'aide du protocole GRPC, ce qui vous permet d'optimiser le modèle push pour les changements survenant dans le cluster. GRPC est utilisé dans Envoy depuis la version 1.6, dans Istio depuis la version 0.8 et est un agent pilote - un wrapper golang sur envoy qui configure les options de lancement.

Pilot et Mixer sont des composants complètement sans état, tous les états sont conservés en mémoire. Leur configuration est définie sous la forme de ressources personnalisées Kubernetes, qui sont stockées dans etcd.
Istio-agent obtient l'adresse du pilote et lui ouvre un flux GRPC.

Comme je l'ai dit, Istio implémente toutes les fonctionnalités de manière totalement transparente pour les applications. Voyons comment. L'algorithme est celui-ci :

  1. Déploiement d'une nouvelle version du service.
  2. Selon l'approche d'injection de conteneur side-car, le conteneur istio-init et le conteneur istio-agent (envoy) sont ajoutés au stade de l'application de la configuration, ou ils peuvent déjà être insérés manuellement dans la description de l'entité Kubernetes Pod.
  3. Le conteneur istio-init est un script qui applique les règles iptables au pod. Il existe deux options pour configurer le trafic à envelopper dans un conteneur istio-agent : utiliser les règles de redirection iptables ou TPROXY. Au moment de la rédaction, l'approche par défaut est avec des règles de redirection. Dans istio-init, il est possible de configurer quel trafic doit être intercepté et envoyé à istio-agent. Par exemple, afin d'intercepter tout le trafic entrant et sortant, vous devez définir les paramètres -i и -b dans le sens *. Vous pouvez spécifier des ports spécifiques à intercepter. Afin de ne pas intercepter un sous-réseau spécifique, vous pouvez le spécifier à l'aide du drapeau -x.
  4. Une fois les conteneurs init exécutés, les principaux sont lancés, y compris le pilote-agent (envoyé). Il se connecte au pilote déjà déployé via GRPC et reçoit des informations sur tous les services et politiques de routage existants dans le cluster. Selon les données reçues, il configure les clusters et les affecte directement aux endpoints de nos applications dans le cluster Kubernetes. Il faut aussi noter un point important : envoy configure dynamiquement les listeners (IP, paires de ports) qu'il commence à écouter. Par conséquent, lorsque les demandes entrent dans le pod et sont redirigées à l'aide des règles de redirection iptables dans le side-car, envoy peut déjà traiter ces connexions avec succès et comprendre où rediriger davantage le trafic. Également à ce stade, les informations sont envoyées au mélangeur, que nous examinerons plus tard, et les plages de traçage sont envoyées.

En conséquence, nous obtenons tout un réseau de serveurs proxy envoyés que nous pouvons configurer à partir d'un point (pilote). Toutes les demandes entrantes et sortantes passent par l'envoyé. De plus, seul le trafic TCP est intercepté. Cela signifie que l'adresse IP du service Kubernetes est résolue à l'aide de kube-dns sur UDP sans modification. Ensuite, après la résolution, la demande sortante est interceptée et traitée par envoy, qui décide déjà à quel point de terminaison la demande doit être envoyée (ou non envoyée, dans le cas des politiques d'accès ou du disjoncteur de l'algorithme).

Nous avons compris Pilot, nous devons maintenant comprendre comment fonctionne Mixer et pourquoi il est nécessaire. Vous pouvez lire la documentation officielle pour cela ici.

Mixer dans sa forme actuelle se compose de deux composants : istio-telemetry, istio-policy (avant la version 0.8, il s'agissait d'un composant istio-mixer). Les deux sont des mélangeurs, chacun étant responsable de sa propre tâche. La télémétrie Istio reçoit des informations sur qui va où et avec quels paramètres à partir de conteneurs de rapports sidecar via GRPC. Istio-policy accepte les demandes de vérification pour vérifier que les règles de stratégie sont satisfaites. Les contrôles de confidentialité ne sont bien sûr pas effectués pour chaque requête, mais sont mis en cache sur le client (dans le side-car) pendant un certain temps. Les vérifications de rapport sont envoyées sous forme de demandes groupées. Voyons comment configurer et quels paramètres doivent être envoyés un peu plus tard.

Le Mixer est censé être un composant hautement disponible qui assure un travail ininterrompu sur l'assemblage et le traitement des données de télémétrie. Le système est ainsi obtenu sous la forme d'un tampon à plusieurs niveaux. Initialement, les données sont mises en mémoire tampon du côté side-car des conteneurs, puis du côté du mélangeur, puis envoyées aux soi-disant backends du mélangeur. Par conséquent, si l'un des composants du système tombe en panne, la mémoire tampon s'agrandit et est vidée après la restauration du système. Les backends de mixage sont des points de terminaison pour l'envoi de données de télémétrie : statsd, newrelic, etc. Vous pouvez écrire votre propre backend, c'est assez simple, et nous verrons comment le faire.

Comment exécuter Istio à l'aide de Kubernetes en production. Partie 1

Pour résumer, le schéma de travail avec l'istio-télémétrie est le suivant.

  1. Le service 1 envoie une requête au service 2.
  2. En quittant le service 1, la requête est enveloppée dans son propre side-car.
  3. L'envoyé Sidecar surveille la façon dont la demande est transmise au service 2 et prépare les informations nécessaires.
  4. Puis l'envoie à l'istio-télémétrie à l'aide d'une requête de rapport.
  5. L'istio-télémétrie détermine si ce rapport doit être envoyé aux backends, à qui et quelles données doivent être envoyées.
  6. Istio-telemetry envoie des données de rapport au backend si nécessaire.

Voyons maintenant comment déployer Istio dans le système, composé uniquement des composants principaux (Pilot et sidecar envoy).

Tout d'abord, regardons la configuration principale (maillage) que Pilot lit :

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

Tous les principaux composants de contrôle (plan de contrôle) seront situés dans l'espace de noms istio-system dans Kubernetes.

Au minimum, nous n'avons qu'à déployer Pilot. Pour cela nous utilisons une telle configuration.

Et nous configurerons manuellement le side-car d'injection du conteneur.

Conteneur d'initialisation :

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

Et side-car :

       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

Pour que tout démarre avec succès, vous devez créer un ServiceAccount, ClusterRole, ClusterRoleBinding, CRD for Pilot, dont vous trouverez les descriptions ici.

Par conséquent, le service dans lequel nous injectons side-car avec envoy devrait démarrer avec succès, recevoir toutes les découvertes du pilote et traiter les demandes.

Il est important de comprendre que tous les composants du plan de contrôle sont des applications sans état et peuvent être mis à l'échelle horizontalement sans problème. Toutes les données sont stockées dans etcd sous la forme de descriptions personnalisées des ressources Kubernetes.

De plus, Istio (toujours expérimental) a la capacité de s'exécuter en dehors du cluster et la possibilité de surveiller et de tâtonner la découverte de services entre plusieurs clusters Kubernetes. Vous pouvez en savoir plus à ce sujet ici.

Pour une installation multicluster, tenez compte des limitations suivantes :

  1. Le CIDR de pod et le CIDR de service doivent être uniques dans tous les clusters et ne doivent pas se chevaucher.
  2. Tous les pods CIDR doivent être accessibles à partir de n'importe quel pod CIDR entre les clusters.
  3. Tous les serveurs d'API Kubernetes doivent être accessibles les uns aux autres.

Il s'agit des informations initiales pour vous aider à démarrer avec Istio. Cependant, il reste encore de nombreux écueils. Par exemple, les fonctionnalités de routage du trafic externe (en dehors du cluster), les approches de débogage des side-cars, le profilage, la configuration d'un mélangeur et l'écriture d'un backend de mélangeur personnalisé, la configuration d'un mécanisme de traçage et son fonctionnement à l'aide d'envoy.
Nous examinerons tout cela dans les publications suivantes. Posez vos questions, je vais essayer de les couvrir.

Source: habr.com

Ajouter un commentaire