
Einführung
Wir bei Shopify haben Istio als Service-Mesh bereitgestellt. Im Prinzip passt alles, bis auf eines: Es ist teuer .
Die veröffentlichten Benchmarks für Istio lauten:
Mit Istio 1.1 verbraucht der Proxy ungefähr 0,6 vCPUs (virtuelle Kerne) pro 1000 Anforderungen pro Sekunde.
Für die erste Region im Service-Mesh (2 Proxys auf jeder Seite der Verbindung) stehen 1200 Kerne nur für Proxys mit einer Rate von einer Million Anforderungen pro Sekunde zur Verfügung. Laut dem Kostenrechner von Google erhalten Sie für die n1-standard-64
Konfiguration etwa 40 US-Dollar pro Monat und Kern, n1-standard-64
allein diese Region kostet uns mehr als 50.000 US-Dollar pro Monat für 1 Million Anfragen pro Sekunde.
Ivan Sim ( Ivan Sim ) hat die Verzögerungen beim Service-Mesh im letzten Jahr klar verglichen und dasselbe für den Speicher und den Prozessor versprochen, ist jedoch gescheitert:
Anscheinend wird values-istio-test.yaml die Prozessoranforderungen ernsthaft erhöhen. Wenn ich alles richtig berechnet habe, benötigen Sie ungefähr 24 Prozessorkerne für das Bedienfeld und 0,5 CPU für jeden Proxy. Ich habe nicht so viel. Ich werde die Tests wiederholen, wenn mir mehr Ressourcen zugewiesen werden.
Ich wollte selbst sehen, wie ähnlich Istios Leistung einem anderen Open-Source-Service-Mesh ist: Linkerd .
Installation des Servicegitters
Das erste, was ich im SuperGloo- Cluster installiert habe, war :
$ 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!
Ich habe SuperGloo verwendet, weil es den Start des Service-Mesh erheblich vereinfacht. Ich hatte fast nichts zu tun. In der Produktion verwenden wir kein SuperGloo, aber es ist ideal für eine ähnliche Aufgabe. Ich musste nur ein paar Befehle auf jedes Service-Mesh anwenden. Ich habe zwei Cluster zur Isolation verwendet - einen für Istio und Linkerd.
Das Experiment wurde mit der Google Kubernetes Engine durchgeführt. Ich habe Kubernetes 1.12.7-gke.7
und den 1.12.7-gke.7
n1-standard-4
mit automatischer 1.12.7-gke.7
(Minimum 4, Maximum 16) verwendet.
Dann habe ich beide Service-Mesh über die Kommandozeile installiert.
Linkerd zuerst:
$ 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 | +---------+--------------+---------+---------------------------+
Dann 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 | +---------+------------+---------+---------------------------+
Die Crash-Schleife dauerte einige Minuten, und dann stabilisierten sich die Bedienfelder.
(Hinweis: SuperGloo unterstützt derzeit nur Istio 1.0.x. Ich habe das Experiment mit Istio 1.1.3 wiederholt, aber keinen merklichen Unterschied festgestellt.)
Einrichten der automatischen Bereitstellung von Istio
Damit Istio den Sidecar Envoy installieren kann, verwenden wir den Sidecar-Injektor - MutatingAdmissionWebhook
. Wir werden in diesem Artikel nicht über ihn sprechen. Ich kann nur sagen, dass dies ein Controller ist, der den Zugriff aller neuen Pods überwacht und dynamisch einen Beiwagen und initContainer hinzufügt, der für iptables
Aufgaben verantwortlich ist.
Wir bei Shopify haben unseren Zugangscontroller geschrieben, um den Beiwagen zu implementieren, aber in diesem Benchmark habe ich den Controller genommen, der mit Istio geliefert wird. Der Controller injiziert standardmäßig einen Beiwagen, wenn im Namespace eine Verknüpfung mit 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
Konfigurieren Sie die automatische Bereitstellung von Linkerd
Um die Implementierung von Linkerd-Beiwagen zu konfigurieren, verwenden wir Anmerkungen (ich habe sie manuell über kubectl edit
hinzugefügt):
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
Fehlertoleranzsimulator Istio
Wir haben den Istio-Fehlertoleranzsimulator entwickelt, um mit dem für Shopify einzigartigen Datenverkehr zu experimentieren. Wir brauchten ein Tool, um eine beliebige Topologie zu erstellen, die einen bestimmten Teil des Diagramms unseres Dienstes mit dynamischer Optimierung darstellt, um bestimmte Workloads zu simulieren.
Die Shopify-Infrastruktur ist während des Flash-Verkaufs stark ausgelastet. Gleichzeitig empfiehlt Shopify den Verkäufern, solche Verkäufe häufiger durchzuführen . Großkunden warnen manchmal vor einem geplanten Flash-Verkauf. Andere geben sie zu jeder Tages- und Nachtzeit unerwartet für uns aus.
Wir wollten, dass unser Fehlertoleranzsimulator Workflows modelliert, die den Topologien und Workloads entsprechen, die die Shopify-Infrastruktur in der Vergangenheit überlastet haben. Das Hauptziel der Verwendung des Service-Meshs besteht darin, dass wir Zuverlässigkeit und Fehlertoleranz auf Netzwerkebene benötigen. Für uns ist es wichtig, dass das Service-Mesh die Lasten effektiv bewältigt, die zuvor den Betrieb von Services unterbrochen haben.
Der Failover-Simulator basiert auf einem Arbeitsknoten, der als Service-Mesh-Knoten fungiert. Der Arbeitsknoten kann beim Start statisch oder dynamisch über die REST-API konfiguriert werden. Wir verwenden die dynamische Optimierung 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
, der nach 100 ms eine 200/OK
Antwort zurückgibt. - Wir starten 10 Clients - jeder sendet 100 Anfragen pro Sekunde an
bar
. - Alle 10 Sekunden entfernen wir 1 Server und überwachen
5xx
Fehler auf dem Client.
Am Ende des Workflows untersuchen wir die Protokolle und Metriken und prüfen, ob der Test erfolgreich ist. Auf diese Weise lernen wir die Leistung unseres Service-Netzes kennen und führen einen Regressionstest durch, um unsere Annahmen zur Fehlertoleranz zu testen.
(Hinweis: Wir erwägen, den Quellcode für den Istio-Fehlertoleranzsimulator zu öffnen, sind jedoch noch nicht bereit dafür.)
Istio-Fehlertoleranzsimulator für Service-Mesh-Benchmark
Wir konfigurieren mehrere Arbeitsknoten des Simulators:
irs-client-loadgen
: 3 Replikate, die 100 Anforderungen pro Sekunde an irs-client
senden.irs-client
: 3 Replikate, die die Anfrage empfangen, warten 100 ms und leiten die Anfrage an den irs-server
.irs-server
: 3 Replikate, die nach 100 ms 200/OK
zurückgeben.
Mit dieser Konfiguration können wir einen stabilen Verkehrsfluss zwischen 9 Endpunkten messen. Beiwagen in irs-client-loadgen
und irs-server
empfangen 100 Anfragen pro Sekunde und irs-client
- 200 (eingehend und ausgehend).
Wir verfolgen die Ressourcennutzung über DataDog, da wir keinen Prometheus-Cluster haben.
Ergebnisse
Bedienfelder
Zuerst haben wir den CPU-Verbrauch untersucht.

Linkerd Control Panel ~ 22M

Istio Control Panel: ~ 750 Millionen Kerne
Das Istio-Bedienfeld verwendet ungefähr 35-mal mehr Prozessorressourcen als Linkerd. Natürlich ist standardmäßig alles eingestellt, und die Istio-Telemetrie verbraucht viele Prozessorressourcen (Sie können sie deaktivieren, indem Sie einige Funktionen aufgeben). Wenn Sie diese Komponente entfernen, stellt sich heraus, dass es sich immer noch um mehr als 100 Multicore handelt, das ist viermal mehr als bei Linkerd.
Beiwagen-Proxy
Dann haben wir die Verwendung von Proxies überprüft. Es sollte eine lineare Abhängigkeit von der Anzahl der Anforderungen bestehen, aber für jeden Beiwagen gibt es einige Gemeinkosten, die sich auf die Kurve auswirken.

Linkerd: ~ 100Mnuclear für irs-client, ~ 50Mnuclear für irs-client-loadgen
Die Ergebnisse sehen logisch aus, da der Client-Proxy doppelt so viel Datenverkehr empfängt wie der Loadgen-Proxy: Für jede ausgehende Anforderung von Loadgen verfügt der Client über einen eingehenden und einen ausgehenden.

Istio / Gesandter: ~ 155 Millionäre für irs-client, ~ 75 Millionäre für irs-client-loadgen
Wir sehen ähnliche Ergebnisse für den Istio-Beiwagen.
Insgesamt verbrauchen Istio / Envoy-Proxys jedoch etwa 50% mehr Prozessorressourcen als Linkerd.
Wir sehen das gleiche Schema auf der Serverseite:

Linkerd: ~ 50 Multicore für IRS-Server

Istio / Envoy: ~ 80 Multicore für IRS-Server
Auf der Serverseite verbraucht der Istio / Envoy-Beiwagen etwa 60% mehr Prozessorressourcen als Linkerd.
Fazit
Der Istio Envoy-Proxy verbraucht bei unserer simulierten Arbeitslast 50 +% mehr CPU als Linkerd. Das Linkerd-Bedienfeld verbraucht viel weniger Ressourcen als Istio, insbesondere für die Hauptkomponenten.
Wir denken immer noch darüber nach, wie wir diese Kosten senken können. Wenn Sie Ideen haben, teilen Sie!