Benchmark de consommation CPU pour Istio et Linkerd

Benchmark de consommation CPU pour Istio et Linkerd

introduction

Nous sommes en Shopify a commencé à déployer Istio en tant que service mesh. En principe, tout va bien, sauf une chose : il est coûteux.

В repères publiés pour Istio, il est dit :

Avec Istio 1.1, le proxy consomme environ 0,6 vCPU (cœurs virtuels) pour 1000 XNUMX requêtes par seconde.

Pour la première région du service mesh (2 proxys de chaque côté de la connexion), nous disposerons de 1200 cœurs rien que pour le proxy, à raison d'un million de requêtes par seconde. Selon le calculateur de coûts de Google, cela équivaut à environ 40 $/mois/cœur pour la configuration. n1-standard-64, c'est-à-dire que cette région à elle seule nous coûtera plus de 50 1 dollars par mois pour XNUMX million de requêtes par seconde.

Ivan Sim (Ivan Sim) comparé visuellement le maillage de service a retardé l'année dernière et a promis la même chose pour la mémoire et le processeur, mais cela n'a pas fonctionné :

Apparemment,values-istio-test.yaml augmentera considérablement les demandes de processeur. Si j'ai fait mes calculs correctement, vous avez besoin d'environ 24 cœurs de processeur pour le panneau de commande et de 0,5 processeur pour chaque proxy. Je n'en ai pas beaucoup. Je répéterai les tests lorsque davantage de ressources me seront allouées.

Je voulais voir par moi-même à quel point les performances d'Istio sont similaires à celles d'un autre maillage de services open source : Linker.

Installation du maillage de services

Tout d'abord, je l'ai installé dans un cluster supergloo:

$ 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 facilite grandement l'amorçage du maillage de services. Je n'avais pas grand-chose à faire. Nous n'utilisons pas SuperGloo en production, mais il est idéal pour une telle tâche. J'ai dû utiliser littéralement quelques commandes pour chaque maillage de service. J'ai utilisé deux clusters pour l'isolation - un pour Istio et Linkerd.

L'expérience a été menée sur Google Kubernetes Engine. J'ai utilisé Kubernetes 1.12.7-gke.7 et un 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 maillages de services à partir de la ligne de commande.

Premier lien :

$ 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      |
+---------+------------+---------+---------------------------+

La boucle de crash a duré quelques minutes, puis les panneaux de contrôle se sont stabilisés.

(Remarque : SuperGloo ne prend en charge qu'Istio 1.0.x pour l'instant. 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 side-car - MutatingAdmissionWebhook. Nous n'en parlerons pas dans cet article. Permettez-moi simplement de dire qu'il s'agit d'un contrôleur qui surveille l'accès à tous les nouveaux pods et ajoute dynamiquement un side-car et un initContainer, qui est responsable des tâches. iptables.

Chez Shopify, nous avons écrit notre propre contrôleur d'accès pour implémenter des side-cars, mais pour ce test, j'ai utilisé le contrôleur fourni avec Istio. Le contrôleur injecte des side-cars par défaut lorsqu'il y a un raccourci dans l'espace de noms istio-injection: enabled:

$ 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

Configuration du déploiement automatique de Linkerd

Pour configurer l'intégration du side-car 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 construit un simulateur de tolérance aux pannes appelé Istio pour expérimenter le trafic unique à Shopify. Nous avions besoin d'un outil pour créer une topologie personnalisée qui représenterait une partie spécifique de notre graphique de service, configurée dynamiquement pour modéliser des charges de travail spécifiques.

L'infrastructure de Shopify est fortement sollicitée lors des ventes flash. En parallèle, Shopify recommande aux vendeurs d'organiser de telles ventes plus souvent. Les gros clients mettent parfois en garde contre une vente flash prévue. D'autres les effectuent à l'improviste pour nous, à toute heure du jour ou de la nuit.

Nous voulions que notre simulateur de résilience modélise des flux de travail qui correspondent aux topologies et aux charges de travail qui ont submergé l'infrastructure de Shopify dans le passé. L'objectif principal de l'utilisation d'un maillage de services 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 services fasse face efficacement aux charges qui perturbaient auparavant les services.

Au cœur du simulateur de tolérance aux pannes se trouve un nœud de travail, qui agit comme un nœud de maillage de services. Le nœud de travail peut être configuré de manière statique au démarrage ou dynamiquement via une API REST. Nous utilisons la configuration dynamique des nœuds de travail pour créer des workflows sous forme de tests de régression.

Voici un exemple d’un tel processus :

  • Nous lançons 10 serveurs comme bar service qui renvoie une réponse 200/OK après 100 ms.
  • Nous lançons 10 clients - chacun envoie 100 requêtes par seconde à bar.
  • Toutes les 10 secondes, nous supprimons 1 serveur et surveillons les erreurs 5xx sur le client.

À la fin du flux de travail, nous examinons les journaux et les métriques et vérifions si le test a réussi. De cette façon, nous en apprenons davantage sur les performances de notre maillage de services et effectuons un test de régression pour tester nos hypothèses sur la tolérance aux pannes.

(Remarque : nous envisageons d'ouvrir le simulateur de tolérance aux pannes Istio, mais nous ne sommes pas encore prêts à le faire.)

Simulateur de tolérance aux pannes Istio pour référence de maillage de services

Nous avons mis en place plusieurs nœuds de travail du simulateur :

  • irs-client-loadgen: 3 répliques qui envoient 100 requêtes par seconde et par irs-client.
  • irs-client: 3 réplicas qui reçoivent la requête, attendent 100 ms et transmettent la requête à irs-server.
  • irs-server: 3 répliques qui reviennent 200/OK après 100 ms.

Avec cette configuration, nous pouvons mesurer un flux de trafic stable entre 9 points de terminaison. Side-cars dans irs-client-loadgen и irs-server recevoir 100 requêtes par seconde, et irs-client — 200 (entrants et sortants).

Nous suivons l'utilisation des ressources via DataDogparce que nous n'avons pas de cluster Prometheus.

résultats

Panneaux de contrôle

Tout d’abord, nous avons examiné la consommation du processeur.

Benchmark de consommation CPU pour Istio et Linkerd
Panneau de contrôle Linkerd ~ 22 millicore

Benchmark de consommation CPU pour Istio et Linkerd
Panneau de configuration Istio : ~750 millicore

Le panneau de configuration Istio utilise environ 35 fois plus de ressources CPUque Linkerd. Bien entendu, tout est installé par défaut, et l'istio-télémétrie consomme ici beaucoup de ressources processeur (elle peut être désactivée en désactivant certaines fonctions). Si nous supprimons ce composant, nous obtenons toujours plus de 100 millicores, c'est-à-dire 4 fois plusque Linkerd.

Proxy side-car

Nous avons ensuite testé l'utilisation d'un proxy. Il devrait y avoir une relation linéaire avec le nombre de requêtes, mais pour chaque side-car, il y a une certaine surcharge qui affecte la courbe.

Benchmark de consommation CPU pour Istio et Linkerd
Linkerd : ~100 millicores pour irs-client, ~50 millicores 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 requête sortante de Loadgen, le client en a une entrante et une sortante.

Benchmark de consommation CPU pour Istio et Linkerd
Istio/Envoy : ~155 millicores pour irs-client, ~75 millicores pour irs-client-loadgen

Nous constatons des résultats similaires pour les side-cars Istio.

Mais en général, les proxys Istio/Envoy consomment environ 50 % de ressources CPU en plusque Linkerd.

On retrouve le même schéma côté serveur :

Benchmark de consommation CPU pour Istio et Linkerd
Linkerd : ~ 50 millicore pour le serveur irs

Benchmark de consommation CPU pour Istio et Linkerd
Istio/Envoy : ~80 millicore pour le serveur irs

Côté serveur, le side-car Istio/Envoy consomme environ 60 % de ressources CPU en plusque Linkerd.

Conclusion

Le proxy Istio Envoy consomme plus de 50 % de CPU que Linkerd sur notre charge de travail simulée. Le panneau de contrôle Linkerd consomme beaucoup moins de ressources qu'Istio, notamment pour les composants principaux.

Nous réfléchissons encore à la manière de réduire ces coûts. Si vous avez des idées, partagez-les !

Source: habr.com

Ajouter un commentaire