
Présentation
Chez Shopify, nous déployions Istio en tant que maillage de service. En principe, tout convient, sauf une chose: c'est cher .
Les repères publiés pour Istio disent:
Avec Istio 1.1, le proxy consomme environ 0,6 vCPU (cœurs virtuels) pour 1 000 requêtes par seconde.
Pour la première région du maillage de service (2 mandataires de chaque côté de la connexion), nous aurons 1200 cœurs pour les mandataires uniquement, à raison d'un million de requêtes par seconde. Selon le calculateur de coûts de Google, vous obtenez environ 40 $ / mois / noyau pour la configuration n1-standard-64
, c'est-à -dire que cette région à elle seule nous coûtera plus de 50000 $ par mois pour 1 million de demandes par seconde.
Ivan Sim ( Ivan Sim ) a clairement comparé les retards du maillage de service l'année dernière et a promis la même chose pour la mémoire et le processeur, mais a échoué:
Apparemment, values-istio-test.yaml augmentera sérieusement les demandes du processeur. Si j'ai tout calculé correctement, vous avez besoin d'environ 24 cœurs de processeur pour le panneau de commande et 0,5 CPU pour chaque proxy. Je n'en ai pas autant. Je répéterai les tests lorsque plus de ressources me seront allouées.
Je voulais voir par moi-mĂŞme comment les performances d'Istio sont similaires Ă celles d'un autre maillage de service open source: Linkerd .
Installation de maillage de service
La première chose que j'ai installée dans le cluster SuperGloo a été :
$ supergloo init installing supergloo version 0.3.12 using chart uri https://storage.googleapis.com/supergloo-helm/charts/supergloo-0.3.12.tgz configmap/sidecar-injection-resources created serviceaccount/supergloo created serviceaccount/discovery created serviceaccount/mesh-discovery created clusterrole.rbac.authorization.k8s.io/discovery created clusterrole.rbac.authorization.k8s.io/mesh-discovery created clusterrolebinding.rbac.authorization.k8s.io/supergloo-role-binding created clusterrolebinding.rbac.authorization.k8s.io/discovery-role-binding created clusterrolebinding.rbac.authorization.k8s.io/mesh-discovery-role-binding created deployment.extensions/supergloo created deployment.extensions/discovery created deployment.extensions/mesh-discovery created install successful!
J'ai utilisé SuperGloo car cela simplifie considérablement le démarrage du maillage de service. Je n'avais presque rien à faire. En production, nous n'utilisons pas SuperGloo, mais il est idéal pour une tâche similaire. J'ai dû appliquer seulement quelques commandes à chaque maillage de service. J'ai utilisé deux clusters pour l'isolement - un pour Istio et Linkerd.
L'expérience a été menée sur le moteur Google Kubernetes. J'ai utilisé Kubernetes 1.12.7-gke.7
et le pool de nœuds n1-standard-4
avec mise à l'échelle automatique des nœuds (minimum 4, maximum 16).
Ensuite, j'ai installé les deux mailles de service à partir de la ligne de commande.
Linkerd d'abord:
$ supergloo install linkerd --name linkerd +---------+--------------+---------+---------------------------+ | INSTALL | TYPE | STATUS | DETAILS | +---------+--------------+---------+---------------------------+ | linkerd | Linkerd Mesh | Pending | enabled: true | | | | | version: stable-2.3.0 | | | | | namespace: linkerd | | | | | mtls enabled: true | | | | | auto inject enabled: true | +---------+--------------+---------+---------------------------+
Puis Istio:
$ supergloo install istio --name istio --installation-namespace istio-system --mtls=true --auto-inject=true +---------+------------+---------+---------------------------+ | INSTALL | TYPE | STATUS | DETAILS | +---------+------------+---------+---------------------------+ | istio | Istio Mesh | Pending | enabled: true | | | | | version: 1.0.6 | | | | | namespace: istio-system | | | | | mtls enabled: true | | | | | auto inject enabled: true | | | | | grafana enabled: true | | | | | prometheus enabled: true | | | | | jaeger enabled: true | +---------+------------+---------+---------------------------+
Le crash-loop a pris plusieurs minutes, puis les panneaux de contrôle se sont stabilisés.
(Remarque: SuperGloo ne prend actuellement en charge que Istio 1.0.x. J'ai répété l'expérience avec Istio 1.1.3, mais je n'ai remarqué aucune différence notable.)
Configuration du déploiement automatique d'Istio
Pour qu'Istio installe le side-car Envoy, nous utilisons l'injecteur de side-car - MutatingAdmissionWebhook
. Nous ne parlerons pas de lui dans cet article. Je peux seulement dire que c'est un contrôleur qui surveille l'accès à tous les nouveaux pods et ajoute dynamiquement un sidecar et initContainer, qui est responsable des tâches iptables
.
Chez Shopify, nous avons écrit notre contrôleur d'accès pour implémenter le side-car, mais dans cette référence, j'ai pris le contrôleur fourni avec Istio. Le contrôleur injecte sidecar par défaut lorsqu'il y a un istio-injection: enabled
dans l'espace de noms:
$ kubectl label namespace irs-client-dev istio-injection=enabled namespace/irs-client-dev labeled $ kubectl label namespace irs-server-dev istio-injection=enabled namespace/irs-server-dev labeled
Configurer le déploiement automatique de Linkerd
Pour configurer l'implémentation des side-cars Linkerd, nous utilisons des annotations (je les ai ajoutées manuellement via kubectl edit
):
metadata: annotations: linkerd.io/inject: enabled
$ k edit ns irs-server-dev namespace/irs-server-dev edited $ k get ns irs-server-dev -o yaml apiVersion: v1 kind: Namespace metadata: annotations: linkerd.io/inject: enabled name: irs-server-dev spec: finalizers: - kubernetes status: phase: Active
Simulateur de tolérance aux pannes Istio
Nous avons créé le simulateur de tolérance aux pannes Istio pour expérimenter le trafic propre à Shopify. Nous avions besoin d'un outil pour créer une topologie arbitraire qui représenterait une certaine partie du graphique de notre service avec un réglage dynamique pour simuler des charges de travail spécifiques.
L'infrastructure Shopify est sous forte charge lors des ventes flash. Dans le même temps, Shopify recommande aux vendeurs d'effectuer ces ventes plus souvent . Les gros clients avertissent parfois d'une vente flash planifiée. D'autres les dépensent de façon inattendue pour nous à toute heure du jour ou de la nuit.
Nous voulions que notre simulateur de tolérance aux pannes modélise des flux de travail qui correspondent aux topologies et aux charges de travail qui ont surchargé l'infrastructure Shopify dans le passé. L'objectif principal de l'utilisation du maillage de service est que nous avons besoin de fiabilité et de tolérance aux pannes au niveau du réseau, et il est important pour nous que le maillage de service résiste efficacement aux charges qui interrompaient auparavant le fonctionnement des services.
Le simulateur de basculement est basé sur un nœud de travail qui agit comme un nœud de maillage de service. Le nœud de travail peut être configuré statiquement au démarrage ou dynamiquement via l'API REST. Nous utilisons le réglage dynamique des nœuds de travail pour créer des flux de travail sous la forme de tests de régression.
Voici un exemple d'un tel processus:
- Nous démarrons 10 serveurs en tant que service de
bar
, qui renvoie une réponse 200/OK
après 100 ms. - Nous démarrons 10 clients - chacun envoie 100 demandes par seconde à la
bar
. - Toutes les 10 secondes, nous supprimons 1 serveur, nous surveillons les erreurs
5xx
sur le client.
À la fin du workflow, nous étudions les journaux et les métriques et vérifions si le test réussit. C'est ainsi que nous apprenons les performances de notre maillage de service et effectuons un test de régression pour tester nos hypothèses sur la tolérance aux pannes.
(Remarque: nous envisageons d'ouvrir le code source du simulateur de tolérance aux pannes d'Istio, mais nous ne sommes pas encore prêts pour cela.)
Simulateur de tolérance aux pannes Istio pour référence de maillage de service
Nous configurons plusieurs nœuds de travail du simulateur:
irs-client-loadgen
: 3 répliques qui envoient 100 requêtes par seconde à irs-client
.irs-client
: 3 répliques qui reçoivent la demande attendent 100 ms et redirigent la demande vers irs-server
.irs-server
: 3 répliques qui retournent 200/OK
après 100 ms.
Avec cette configuration, nous pouvons mesurer un flux de trafic stable entre 9 points d'extrémité. Sidecar dans irs-client-loadgen
et irs-server
reçoit 100 requêtes par seconde, et irs-client
- 200 (entrants et sortants).
Nous suivons l' utilisation des ressources via DataDog car nous n'avons pas de cluster Prometheus.
Résultats
Panneaux de contrĂ´le
Tout d'abord, nous avons examiné la consommation du processeur.

Panneau de contrĂ´le Linkerd ~ 22M

Panneau de configuration Istio: ~ 750 millions de cœurs
Le panneau de configuration Istio utilise environ 35 fois plus de ressources processeur que Linkerd. Bien sûr, tout est défini par défaut, et l'istio-télémétrie consomme beaucoup de ressources processeur (vous pouvez le désactiver en abandonnant certaines fonctions). Si vous supprimez ce composant, il s'avère être plus de 100 multicœurs, soit 4 fois plus que Linkerd.
Proxy Sidecar
Ensuite, nous avons vérifié l'utilisation des procurations. Il devrait y avoir une dépendance linéaire sur le nombre de demandes, mais pour chaque side-car, il y a des frais généraux qui affectent la courbe.

Linkerd: ~ 100Mnucléaire pour irs-client, ~ 50Mnucléaire pour irs-client-loadgen
Les résultats semblent logiques, car le proxy client reçoit deux fois plus de trafic que le proxy loadgen: pour chaque demande sortante de loadgen, le client a un entrant et un sortant.

Istio / Envoy: ~ 155 millionnaires pour irs-client, ~ 75 millionnaires pour irs-client-loadgen
Nous voyons des résultats similaires pour le side-car Istio.
Mais dans l'ensemble, les proxys Istio / Envoy consomment environ 50% plus de ressources processeur que Linkerd.
Nous voyons le même schéma du côté serveur:

Linkerd: ~ 50 multicœurs pour irs-server

Istio / Envoy: ~ 80 multicœurs pour irs-server
Côté serveur, le side-car Istio / Envoy consomme environ 60% de ressources processeur en plus que Linkerd.
Conclusion
Le proxy Istio Envoy consomme 50 +% de CPU de plus que Linkerd sur notre charge de travail simulée. Le panneau de contrôle de Linkerd consomme beaucoup moins de ressources que Istio, en particulier pour les principaux composants.
Nous réfléchissons toujours à la manière de réduire ces coûts. Si vous avez des idées, partagez-les!