Benchmark des CPU-Verbrauchs für Istio und Linkerd

Benchmark des CPU-Verbrauchs für Istio und Linkerd

Einführung

Bei Shopify haben mit der Bereitstellung von Istio als Service Mesh begonnen. Im Grunde sind wir zufrieden, außer in einer Hinsicht: es ist teuer.

In veröffentlichten Benchmarks für Istio wird gesagt:

Mit Istio 1.1 verbraucht der Proxy etwa 0,6 vCPU (virtuelle Kerne) pro 1000 Anfragen pro Sekunde.

Für die erste Region im Service Mesh (2 Proxys auf jeder Seite der Verbindung) werden wir 1200 Kerne nur für den Proxy benötigen, basierend auf einer Million Anfragen pro Sekunde. Laut dem Kostenschätzer von Google kostet das etwa 40 $/Monat/Kern für die Konfiguration n1-standard-64, was bedeutet, dass diese Region uns über 50.000 Dollar pro Monat für 1 Million Anfragen pro Sekunde kosten wird.

Ayven Sim (Ivan Sim) hat anschaulich die Latenzen des Service Mesh im letzten Jahr verglichen und dasselbe für Speicher und CPU versprochen, aber das hat nicht geklappt:

Offensichtlich wird die values-istio-test.yaml die CPU-Anfragen erheblich erhöhen. Wenn ich alles richtig gerechnet habe, benötige ich etwa 24 CPU-Kerne für das Control Panel und 0,5 CPU für jeden Proxy. So viele habe ich nicht. Ich werde die Tests wiederholen, wenn mir mehr Ressourcen zugewiesen werden.

Ich wollte selbst sehen, wie vergleichbar die Leistungsdaten von Istio mit einem anderen Open-Source-Service-Mesh sind: Linkerd.

Installation von Service Mesh

Zuerst habe ich im Cluster SuperGloo:

$ supergloo init
installiere SuperGloo Version 0.3.12
verwende Chart-URI https://storage.googleapis.com/supergloo-helm/charts/supergloo-0.3.12.tgz
configmap/sidecar-injection-resources erstellt
serviceaccount/supergloo erstellt
serviceaccount/discovery erstellt
serviceaccount/mesh-discovery erstellt
clusterrole.rbac.authorization.k8s.io/discovery erstellt
clusterrole.rbac.authorization.k8s.io/mesh-discovery erstellt
clusterrolebinding.rbac.authorization.k8s.io/supergloo-role-binding erstellt
clusterrolebinding.rbac.authorization.k8s.io/discovery-role-binding erstellt
clusterrolebinding.rbac.authorization.k8s.io/mesh-discovery-role-binding erstellt
deployment.extensions/supergloo erstellt
deployment.extensions/discovery erstellt
deployment.extensions/mesh-discovery erstellt
Installation erfolgreich!

Ich habe SuperGloo verwendet, da es die initiale Einrichtung von Service Mesh erheblich vereinfacht. Ich musste fast nichts tun. In der Produktion nutzen wir SuperGloo nicht, aber für diese Aufgabe ist es perfekt geeignet. Ich musste lediglich ein paar Befehle für jedes Service Mesh anwenden. Ich habe zwei Cluster zur Isolation verwendet — jeweils eines für Istio und Linkerd.

Das Experiment fand auf Google Kubernetes Engine statt. Ich habe Kubernetes 1.12.7-gke.7 und einen Node-Pool n1-standard-4 mit automatischer Skalierung der Nodes (mindestens 4, maximal 16).

Dann habe ich beide Service Mesh über die Kommandozeile installiert.

Zuerst Linkerd:

$ supergloo install linkerd --name linkerd
+---------+--------------+---------+---------------------------+
| INSTALL |     TYPE     | STATUS  |          DETAILS          |
+---------+--------------+---------+---------------------------+
| linkerd | Linkerd Mesh | Ausstehend | aktiviert: true             |
|         |              |         | version: stable-2.3.0     |
|         |              |         | namespace: linkerd        |
|         |              |         | mtls aktiviert: true        |
|         |              |         | automatische Injektion aktiviert: true |
+---------+--------------+---------+---------------------------+

Dann Istio:

$ supergloo install istio --name istio --installation-namespace istio-system --mtls=true --auto-inject=true
+---------+------------+---------+---------------------------+
| INSTALL |    TYPE    | STATUS  |          DETAILS          |
+---------+------------+---------+---------------------------+
| istio   | Istio Mesh | Ausstehend | aktiviert: true             |
|         |            |         | version: 1.0.6            |
|         |            |         | namespace: istio-system   |
|         |            |         | mtls aktiviert: true        |
|         |            |         | automatische Injektion aktiviert: true |
|         |            |         | grafana aktiviert: true     |
|         |            |         | prometheus aktiviert: true  |
|         |            |         | jaeger aktiviert: true      |
+---------+------------+---------+---------------------------+

Der Crash-Loop dauerte einige Minuten, und danach stabilisierten sich die Panels.

(Hinweis: SuperGloo unterstützt derzeit nur Istio 1.0.x. Ich habe das Experiment mit Istio 1.1.3 wiederholt, aber keinen spürbaren Unterschied bemerkt.)

Einrichtung der automatischen Injektion für Istio

Um Istio zur Installation des Envoy-Sidecars zu bringen, verwenden wir den Sidecar-Injector — MutatingAdmissionWebhook. Darüber werden wir in diesem Artikel nicht sprechen. Ich möchte nur erwähnen, dass dies ein Controller ist, der den Zugriff auf alle neuen Pods überwacht und dynamisch Sidecars und InitContainer hinzufügt, die für bestimmte Aufgaben verantwortlich sind. iptables.

Bei Shopify haben wir unseren eigenen Zugriffscontroller für die Einführung von Sidecars geschrieben, aber in diesem Benchmark habe ich den Controller verwendet, der mit Istio geliefert wird. Der Standard-Controller implementiert Sidecars, wenn im Namensraum ein Label vorhanden ist, istio-injection: enabled:

$ kubectl label namespace irs-client-dev istio-injection=enabled
namespace/irs-client-dev gelabelt

$ kubectl label namespace irs-server-dev istio-injection=enabled
namespace/irs-server-dev gelabelt

Einrichtung der automatischen Einführung von Linkerd

Um die Einführung von Linkerd-Sidecars einzurichten, verwenden wir Annotations (ich habe sie manuell über kubectl edit):

metadata:
  annotations:
    linkerd.io/inject: enabled

$ k edit ns irs-server-dev 
namespace/irs-server-dev bearbeitet

$ 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

Istio-Fehlertoleranz-Simulator

Wir haben einen Istio-Ausfallsimulations-Simulator entwickelt, um mit dem für Shopify typischen Traffic zu experimentieren. Wir benötigten ein Werkzeug, um beliebige Topologien zu erstellen, die einen bestimmten Teil des Graphen unseres Services mit dynamischen Einstellungen abbilden, um spezifische Arbeitslasten zu simulieren.

Die Infrastruktur von Shopify steht während Flash-Sales unter hoher Belastung. Darüber hinaus empfiehlt Shopify den Verkäufern, solche Verkäufe häufiger durchzuführen. Große Kunden kündigen manchmal geplante Flash-Sales an. Andere führen sie unerwartet zu jeder Tages- und Nachtzeit durch.Wir wollten, dass unser Ausfallsimulations-Simulator die Arbeitsabläufe modelliert, die den Topologien und Arbeitslasten entsprechen, die in der Vergangenheit zu Überlastungen der Shopify-Infrastruktur geführt haben. Das Hauptziel bei der Verwendung eines Service Mesh ist, dass wir Zuverlässigkeit und Ausfallsicherheit auf Netzwerkebene benötigen, und es ist wichtig, dass das Service Mesh effektiv mit den Lasten umgeht, die zuvor die Funktionalität der Services beeinträchtigt haben.

Wir wollten, dass unser Ausfallsimulations-Simulator die Arbeitsabläufe modelliert, die den Topologien und Arbeitslasten entsprechen, die in der Vergangenheit zu Überlastungen der Shopify-Infrastruktur geführt haben. Das Hauptziel bei der Verwendung eines Service Mesh ist, dass wir Zuverlässigkeit und Ausfallsicherheit auf Netzwerkebene benötigen, und es ist wichtig, dass das Service Mesh effektiv mit den Lasten umgeht, die zuvor die Funktionalität der Services beeinträchtigt haben.

Der Kern des Ausfallsimulationssystems ist ein Arbeitsknoten, der als Knoten im Service Mesh fungiert. Der Arbeitsknoten kann statisch beim Start konfiguriert oder dynamisch über die REST-API eingestellt werden. Wir verwenden die dynamische Konfiguration von Arbeitsknoten, um Workflows in Form von Regressionstests zu erstellen.

Hier ist ein Beispiel für einen solchen Prozess:

  • Wir starten 10 Server als bar ein Dienst, der eine Antwort zurückgibt 200/OK nach 100 ms.
  • Wir starten 10 Clients — jeder sendet 100 Anfragen pro Sekunde an bar.
  • Alle 10 Sekunden entfernen wir 1 Server und überwachen Fehler 5xx auf dem Client.

Am Ende des Workflows analysieren wir die Protokolle und Metriken und prüfen, ob der Test bestanden wurde. So erfahren wir mehr über die Leistung unseres Service Mesh und führen einen Regressionstest durch, um unsere Annahmen zur Ausfallsicherheit zu überprüfen.

(Anmerkung: Wir denken darüber nach, den Quellcode des Ausfallsimulationssystems von Istio zu öffnen, sind aber noch nicht bereit dafür.)

Ausfallsimulationssystem von Istio für das Benchmarking von Service Mesh

Wir konfigurieren mehrere Arbeitsknoten des Simulators:

  • irs-client-loadgen: 3 Replikate, die jeweils 100 Anfragen pro Sekunde an irs-client senden.
  • irs-client senden: 3 Replikate, die Anfragen erhalten, 100 ms warten und die Anfrage an irs-server.
  • irs-server: 3 Replikate, die zurückgeben 200/OK nach 100 ms.

Mit dieser Konfiguration können wir einen stabilen Datenverkehr zwischen 9 Endpunkten messen. Die Sidecars in irs-client-loadgen und irs-server erhalten jeweils 100 Anfragen pro Sekunde, während irs-client senden — 200 (eingehend und ausgehend).

Wir überwachen den Ressourcenverbrauch über DataDog, da wir keinen Prometheus-Cluster haben.

Ergebnisse

Management-Panels

Zunächst haben wir den CPU-Verbrauch untersucht.

Benchmark des CPU-Verbrauchs für Istio und Linkerd
Linkerd-Dashboard ~22 Milliarde

Benchmark des CPU-Verbrauchs für Istio und Linkerd
Istio-Dashboard: ~750 Milliarde

Das Istio-Dashboard benötigt ungefähr 35-mal mehr Rechenressourcen, als Linkerd. Natürlich ist alles standardmäßig eingestellt, und viele Rechenressourcen werden hier von istio-telemetry verbraucht (dies kann deaktiviert werden, indem auf einige Funktionen verzichtet wird). Selbst ohne diese Komponente bleiben es über 100 Milliarde, das sind 4-mal mehr, als bei Linkerd.

Sidecar-Proxy

Dann haben wir die Nutzung des Proxys überprüft. Hier sollte eine lineare Abhängigkeit von der Anzahl der Anfragen bestehen, jedoch gibt es für jeden Sidecar einige Overheads, die die Kurve beeinflussen.

Benchmark des CPU-Verbrauchs für Istio und Linkerd
Linkerd: ~100 Milliarde für irs-client, ~50 Milliarde für irs-client-loadgen

Die Ergebnisse erscheinen schlüssig, da der Proxy-Client doppelt so viel Traffic erhält wie der Proxy-Loadgen: Auf jede ausgehende Anfrage des Loadgen entfällt eine eingehende und eine ausgehende Anfrage des Clients.

Benchmark des CPU-Verbrauchs für Istio und Linkerd
Istio/Envoy: ~155 Millarden für irs-client, ~75 Millarden für irs-client-loadgen

Wir sehen ähnliche Ergebnisse für die Sidecars von Istio.

Insgesamt verbrauchen die Proxys Istio/Envoy ungefähr 50 % mehr CPU-Ressourcen, als Linkerd.

Ein ähnliches Muster beobachten wir auf der Serverseite:

Benchmark des CPU-Verbrauchs für Istio und Linkerd
Linkerd: ~50 Millarden für irs-server

Benchmark des CPU-Verbrauchs für Istio und Linkerd
Istio/Envoy: ~80 Millarden für irs-server

Auf der Serverseite benötigt das Sidecar Istio/Envoy ungefähr 60 % mehr CPU-Ressourcen, als Linkerd.

Fazit

Der Proxy Istio Envoy benötigt über 50 % mehr CPU als Linkerd unter unserer simulierten Arbeitslast. Das Linkerd-Dashboard verbraucht deutlich weniger Ressourcen als Istio, insbesondere bei den Hauptkomponenten.

Wir denken weiterhin darüber nach, wie wir diese Kosten senken können. Wenn Sie Ideen haben, teilen Sie diese mit uns!

Quelle: habr.com

Kaufen Sie zuverlässiges Hosting für Websites mit DDoS-Schutz, VPS VDS-Server 🔥 Kaufen Sie zuverlässiges Hosting für Websites mit DDoS-Schutz, VPS VDS-Server | ProHoster