Qu'est-ce que ? Это так называемый Service mesh, технология, которая добавляет уровень абстракции над сетью. Мы перехватываем весь или часть трафика в кластере и производим определенный набор операций с ним. Какой именно? Например, делаем умный роутинг, или реализуем подход circuit breaker, можем организовывать «canary deployment», частично переключая трафик на новую версию сервиса, а можем ограничивать внешние взаимодействия и контролировать все походы из кластера во внешнюю сеть. Есть возможность задавать policy правила для контроля походов между разными микросервисами. Наконец, мы можем получить всю карту взаимодействия по сети и сделать унифицированный сбор метрик полностью прозрачно для приложений.
Vous pouvez lire sur le mécanisme de fonctionnement dans . Istio est vraiment un outil puissant qui permet de résoudre de nombreux problèmes et tâches. Dans cet article, je voudrais répondre aux questions principales qui se posent généralement au début de l'utilisation d'Istio. Cela vous aidera à vous familiariser plus rapidement avec cet outil.

Principe de fonctionnement
Istio est composé de deux zones principales : le control plane et le data plane. Le control plane contient les principaux composants qui assurent le bon fonctionnement des autres. Dans la version actuelle (1.0), le control plane comprend trois composants principaux : Pilot, Mixer, Citadel. Nous ne traiterons pas Citadel, qui est nécessaire pour la génération de certificats pour assurer le fonctionnement de mutual TLS entre les services. Examinons plus en détail la structure et la fonction de Pilot et de Mixer.

Pilot est le principal composant de gestion qui diffuse toutes les informations sur ce que nous avons dans le cluster – les services, leurs points d'accès et les règles de routage (par exemple, les règles pour le déploiement Canary ou les règles du circuit breaker).
Mixer est un composant optionnel du control plane qui permet de collecter des métriques, des journaux et toute information sur l'interaction réseau. Il s'assure également du respect des règles de politique et des limites de taux.
Le data plane est réalisé à l'aide de conteneurs proxy sidecar. Par défaut, un puissant . Il peut être remplacé par une autre implémentation, comme nginx (nginmesh).
Pour que Istio fonctionne complètement en transparence pour les applications, il existe un système d'injection automatique. La dernière implémentation convient aux versions Kubernetes 1.9+ (mutational admission webhook). Pour les versions Kubernetes 1.7, 1.8, il est possible d'utiliser Initializer.
Les conteneurs sidecar se connectent à Pilot via le protocole GRPC, qui permet d'optimiser le modèle de diffusion des modifications se produisant dans le cluster. GRPC a commencé à être utilisé dans Envoy à partir de la version 1.6, et dans Istio, il est utilisé depuis la version 0.8 et constitue un pilote-agent - un wrapper en golang sur envoy, qui configure les paramètres de démarrage.
Pilot et Mixer sont des composants entièrement sans état, toute l'état étant conservé en mémoire. La configuration pour eux est spécifiée sous forme de ressources personnalisées Kubernetes, qui sont stockées dans etcd.
Istio-agent obtient l'adresse de Pilot et ouvre un flux GRPC vers lui.
Comme je l'ai dit, Istio implémente toute la fonctionnalité de manière entièrement transparente pour les applications. Voyons comment. L'algorithme est le suivant :
- Nous déployons une nouvelle version du service.
- En fonction de l'approche d'injection, le conteneur istio-init et le conteneur istio-agent (envoy) sont ajoutés au moment de l'application de la configuration, ou bien ils peuvent avoir été insérés manuellement dans la description de l'entité Pod dans Kubernetes.
- Le conteneur istio-init se présente sous la forme d'un script qui applique des règles iptables pour le pod. Il existe deux options pour configurer l'encapsulation du trafic dans le conteneur istio-agent : utiliser des règles iptables de redirection, ou . Au moment de la rédaction de cet article, l'approche par défaut utilise des règles de redirection. Dans istio-init, il est possible de configurer quel trafic doit être intercepté et dirigé vers istio-agent. Par exemple, pour intercepter tout le trafic entrant et sortant, il faut définir les paramètres
-iet-bà la valeur*. On peut spécifier des ports spécifiques à intercepter. Pour éviter d'intercepter un certain sous-réseau, il est possible de le spécifier à l'aide du drapeau-x. - Après l'exécution des conteneurs init, les principaux conteneurs sont lancés, y compris le pilot-agent (envoy). Il se connecte au Pilot déjà déployé via GRPC et obtient des informations sur tous les services existants et les politiques de routage dans le cluster. Sur la base des données reçues, il configure les clusters et enregistre directement les points de terminaison de nos applications dans le cluster Kubernetes. Il est également important de noter un point crucial : envoy configure dynamiquement les écouteurs (paires IP, port) qu'il commence à écouter. Par conséquent, lorsque des requêtes entrent dans le pod, elles sont redirigées via les règles iptables de redirection vers le sidecar, et envoy peut déjà traiter ces connexions et comprendre où le trafic doit être proxy. À ce stade, des informations sont également envoyées au Mixer, que nous examinerons plus tard, ainsi que l'envoi de spans de traçage.
En fin de compte, nous obtenons un réseau entier de serveurs proxy envoy, que nous pouvons configurer depuis un seul point (Pilot). Toutes les requêtes inbound et outbound passent par envoy. De plus, seul le trafic TCP est intercepté. Cela signifie que l'IP du service Kubernetes est résolue à l'aide de kube-dns par UDP sans modification. Ensuite, après la résolution, l'interception de la requête sortante a lieu et est traitée par envoy, qui détermine quel point de terminaison la requête doit atteindre (ou si elle ne doit pas être envoyée, en cas de politiques d'accès ou de déclenchement de l'algorithme de circuit breaker).
Nous avons compris le Pilot, maintenant il faut comprendre comment fonctionne le Mixer et pourquoi il est nécessaire. Vous pouvez lire la documentation officielle à son sujet. .
Le Mixer, dans sa forme actuelle, se compose de deux composants : istio-telemetry et istio-policy (jusqu'à la version 0.8, il s'agissait d'un seul composant istio-mixer). Chacun d'eux représente un mixer, chacun ayant son propre rôle. Istio telemetry reçoit des informations de rapport via GRPC des conteneurs sidecar sur qui va où et avec quels paramètres. Istio-policy reçoit des requêtes de vérification pour s'assurer que les règles de politique sont respectées. Les vérifications de politique ne sont pas effectuées pour chaque requête, elles sont mises en cache sur le client (dans le sidecar) pendant une certaine période. Les rapports sont envoyés par lots. Nous verrons plus tard comment configurer cela et quels paramètres doivent être envoyés.
Le Mixer est conçu comme un composant hautement disponible, garantissant un fonctionnement ininterrompu pour la collecte et le traitement des données de télémétrie. Le système devient donc un tampon multi-niveaux. Au départ, les données sont mises en cache du côté des conteneurs sidecar, puis du côté du mixer, avant d'être envoyées à ce qu'on appelle les backend du mixer. Ainsi, si un des composants du système échoue, le tampon grandit et, après la restauration du système, il est vidé. Les backends du mixer représentent les points de terminaison pour l'envoi des données de télémétrie : statsd, newrelic, etc. On peut écrire son propre backend, c'est assez simple, et nous verrons comment faire cela.

En résumé, le schéma de fonctionnement avec istio-telemetry est le suivant.
- Le service 1 envoie une requête au service 2.
- À la sortie du service 1, la requête est enveloppée dans son propre sidecar.
- Le sidecar envoy surveille le passage de la requête au service 2 et prépare les informations nécessaires.
- Il les envoie ensuite à istio-telemetry à l'aide d'une requête de rapport.
- Istio-telemetry détermine s'il faut envoyer ce rapport aux backends, lesquels précisément et quelles données doivent être envoyées.
- Istio-telemetry envoie les données de rapport aux backends si cela est nécessaire.
Voyons maintenant comment déployer dans le système Istio, composé uniquement des composants de base (Pilot et sidecar envoy).
Pour commencer, examinons la configuration principale (mesh) que lit Pilot :
apiVersion: v1
kind: ConfigMap
metadata:
name: istio
namespace: istio-system
labels:
app: istio
service: istio
data:
mesh: |-
# Nous ne activons pas encore l'envoi des informations de tracing (le pilot configurera les envoyés pour que l'envoi ne se produise pas)
enableTracing: false
# Nous ne spécifions pas encore les endpoints de mixer, pour que les conteneurs sidecar n'envoient pas d'informations là-bas
#mixerCheckServer: istio-policy.istio-system:15004
#mixerReportServer: istio-telemetry.istio-system:15004
# Définissons le délai d'intervalle avec lequel envoy interrogera Pilot (c'est pour l'ancienne version du proxy envoy)
rdsRefreshDelay: 5s
# Configuration par défaut pour le sidecar envoy
defaultConfig:
# Pareil que rdsRefreshDelay
discoveryRefreshDelay: 5s
# Restons par défaut (chemin vers la configuration et le binaire envoy)
configPath: "/etc/istio/proxy"
binaryPath: "/usr/local/bin/envoy"
# Nom par défaut du conteneur sidecar lancé (utilisé, par exemple, dans les noms de service lors de l'envoi des spans de tracing)
serviceCluster: istio-proxy
# Temps que va attendre envoy avant de forcer la fermeture de toutes les connexions établies
drainDuration: 45s
parentShutdownDuration: 1m0s
# Par défaut, les règles de REDIRECT iptables sont utilisées. Peut être changé en TPROXY.
#interceptionMode: REDIRECT
# Port sur lequel sera lancée le panneau d'administration de chaque conteneur sidecar (envoy)
proxyAdminPort: 15000
# Adresse à laquelle les traces seront envoyées selon le protocole zipkin (au début, nous avons désactivé l'envoi lui-même, donc ce champ ne sera actuellement pas utilisé)
zipkinAddress: tracing-collector.tracing:9411
# Adresse statsd pour l'envoi des métriques des conteneurs envoy (désactivées)
# statsdUdpAddress: aggregator:8126
# Désactivation de l'option de support Mutual TLS
controlPlaneAuthPolicy: NONE
# Adresse sur laquelle istio-pilot écoutera pour informer tous les conteneurs sidecar sur la découverte des services
discoveryAddress: istio-pilot.istio-system:15007
Nous allons placer tous les principaux composants de contrôle (control plane) dans le namespace istio-system dans Kubernetes.
Nous devons au minimum déployer seulement Pilot. Pour cela, nous allons utiliser
Et nous allons configurer manuellement l'injection du conteneur sidecar.
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 sidecar :
nom : istio-proxy
args:
- "bash"
- "-c"
- |
exec /usr/local/bin/pilot-agent proxy sidecar
--configPath
/etc/istio/proxy
--binaryPath
/usr/local/bin/envoy
--serviceCluster
nom-du-service
--drainDuration
45s
--parentShutdownDuration
1m0s
--discoveryAddress
istio-pilot.istio-system:15007
--discoveryRefreshDelay
1s
--connectTimeout
10s
--proxyAdminPort
"15000"
--controlPlaneAuthPolicy
AUCUN
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 fonctionne correctement, il est nécessaire de créer un ServiceAccount, un ClusterRole, un ClusterRoleBinding, ainsi qu'un CRD pour Pilot, dont les descriptions peuvent être trouvées. .
En fin de compte, le service dans lequel nous injectons le sidecar avec envoy doit démarrer correctement, recevoir toute la découverte de Pilot et traiter les requêtes.
Il est important de comprendre que tous les composants du control plane sont des applications sans état et peuvent être facilement évolutifs horizontalement. Toutes les données sont stockées dans etcd sous forme de descriptions de ressources personnalisées Kubernetes.
Istio propose également (pour l'instant de manière expérimentale) la possibilité de fonctionner en dehors du cluster et d'observer et partager la découverte de services entre plusieurs clusters Kubernetes. Vous pouvez en savoir plus à ce sujet. .
Lors d'une installation multicluster, il convient de prendre en compte les limitations suivantes :
- Les Pod CIDR et Service CIDR doivent être uniques à travers tous les clusters et ne doivent pas se chevaucher.
- Tous les Pod CIDR doivent être accessibles depuis n'importe quel Pod CIDR entre les clusters.
- Tous les serveurs API Kubernetes doivent être accessibles les uns aux autres.
Ce sont des informations initiales qui vous aideront à commencer à travailler avec Istio. Cependant, il existe encore de nombreuses subtilités. Par exemple, les particularités du routage du trafic externe (en dehors du cluster), les méthodes de débogage des sidecars, le profilage, la configuration de mixer et l'écriture d'un backend de mixer personnalisé, la configuration du mécanisme de traçage et son fonctionnement avec envoy.
Nous examinerons tout cela dans nos prochaines publications. N'hésitez pas à poser vos questions, j'essaierai d'y répondre.
Source : habr.com
