
Introducere
Noi, la am început să desfășurăm Istio ca service mesh. În principiu, totul este în regulă, cu o singură excepție: este scump.
În pentru Istio se menționează:
Cu Istio 1.1, proxy-ul consumă aproximativ 0,6 vCPU (nuclee virtuale) la 1000 de cereri pe secundă.
Pentru prima zonă din service mesh (câte 2 proxy de fiecare parte a conexiunii), avem nevoie de 1200 de nuclee doar pentru proxy, calculând pentru un milion de cereri pe secundă. Conform calculatorului de costuri de la Google, costul este de aproximativ $40/lună/nucleu pentru configurația n1-standard-64, adică această zonă ne va costa mai mult de 50.000 de dolari pe lună pentru 1 milion de cereri pe secundă.
Ivan Sim () latențele service mesh din anul trecut și a promis același lucru pentru memorie și procesor, dar nu a reușit:
Se pare că values-istio-test.yaml va crește semnificativ cererile către procesor. Dacă am calculat corect, sunt necesare aproximativ 24 de nuclee de procesor pentru panoul de control și 0,5 CPU pentru fiecare proxy. Nu am asemenea resurse. Voi repeta testele când mi se vor aloca mai multe resurse.
Am vrut să mă asigur personal cât de asemănătoare sunt performanțele Istio cu alt service mesh cu cod deschis: .
Instalarea service mesh
Mai întâi am instalat în cluster :
$ 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!Am folosit SuperGloo pentru că simplifică semnificativ inițializarea service mesh. Pratic, nu a trebuit să fac mare lucru. În producție, nu folosim SuperGloo, dar pentru o astfel de sarcină este perfect. A trebuit să aplic literalmente doar câteva comenzi pentru fiecare service mesh. Am folosit două clustere pentru izolare — câte unul pentru Istio și Linkerd.
Experimentul a fost realizat pe Google Kubernetes Engine. Am folosit Kubernetes 1.12.7-gke.7 și un pool de noduri n1-standard-4 cu scalare automată a nodurilor (minimum 4, maximum 16).
Apoi am instalat ambele service mesh din linia de comandă.
Mai întâi Linkerd:
$ 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 |
+---------+--------------+---------+---------------------------+Apoi 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 |
+---------+------------+---------+---------------------------+Crash-loop a durat câteva minute, după care panourile de control s-au stabilizat.
(Notă. SuperGloo suportă momentan doar Istio 1.0.x. Am repetat experimentul cu Istio 1.1.3, dar nu am observat nicio diferență semnificativă.)
Configurarea injectării automate Istio
Pentru ca Istio să instaleze sidecar-ul Envoy, folosim injectorul de sidecar — MutatingAdmissionWebhook. Nu vom discuta despre el în acest articol. Voi menționa doar că acesta este un controller care supraveghează accesul tuturor noilor pod-uri și adaugă dinamic sidecar-uri și initContainer, care se ocupă de sarcini iptables.
Noi, la Shopify, am scris propriul nostru controller de acces pentru injectarea sidecar-urilor, dar în acest benchmark am utilizat controllerul livrat cu Istio. Controllerul implicit injectează sidecar-uri atunci când există un label în spațiul de nume 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 labeledConfigurarea injectării automate Linkerd
Pentru a configura injectarea sidecar-urilor Linkerd, folosim adnotări (le-am adăugat manual prin 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: ActiveSimulator de reziliență Istio
Am creat un simulator de reziliență Istio pentru a experimenta cu traficul unic pentru Shopify. Aveam nevoie de un instrument pentru a construi o topologie arbitrară care să reprezinte o parte specifică a grafului serviciului nostru, cu configurare dinamică pentru a modela sarcini de lucru specifice.
Infrastructura Shopify suportă o încărcare mare în timpul vânzărilor flash. În acest timp, Shopify . Clienții mari uneori anunță o vânzare flash planificată. Alții le desfășoară neașteptat, în orice moment al zilei și al nopții.
Am dorit ca simulatorul nostru de reziliență să modeleze fluxuri de lucru care corespund topologiilor și sarcinilor de lucru care au dus la supraîncărcarea infrastructurii Shopify în trecut. Scopul principal al utilizării service mesh este că avem nevoie de fiabilitate și reziliență la nivel de rețea, iar este important pentru noi ca service mesh să facă față eficient sarcinilor care anterior perturbau funcționarea serviciilor.
În centrul simulatorului de reziliență se află un nod de lucru care acționează ca un nod în service mesh. Nodul de lucru poate fi configurat static la pornire sau dinamic prin REST API. Folosim configurarea dinamică a nodurilor de lucru pentru a crea fluxuri de lucru sub formă de teste regresive.
Iată un exemplu de acest proces:
- Pornim 10 servere ca
barserviciu care returnează un răspuns200/OKîn 100 ms. - Pornim 10 clienți — fiecare trimite 100 de cereri pe secundă la
bar. - La fiecare 10 secunde eliminăm 1 server, monitorizăm erorile
5xxdin client.
La sfârșitul fluxului de lucru analizăm logurile și metricile și verificăm dacă testul a fost trecut. Astfel aflăm despre performanța service mesh-ului nostru și realizăm un test regresiv pentru a verifica presupunerile noastre despre reziliență.
(Notă. Ne gândim să deschidem codul sursă al simulatorului de reziliență Istio, dar încă nu suntem pregătiți pentru asta.)
Simulatorul de reziliență Istio pentru benchmark-ul service mesh
Configurăm mai multe noduri de lucru ale simulatorului:
irs-client-loadgen: 3 replici care trimit 100 de cereri pe secundă cătreirs-client.irs-client: 3 replici care primesc cereri, așteaptă 100 ms și redirecționează cererea cătreirs-server.irs-server: 3 replici care returnează200/OKîn 100 ms.
Cu această configurație, putem măsura un flux stabil de trafic între 9 puncte finale. Sidecar-urile în irs-client-loadgen și irs-server primește 100 de cereri pe secundă, iar irs-client — 200 (întrări și ieșiri).
Urmărim utilizarea resurselor prin , deoarece nu avem un cluster Prometheus.
Rezultate
Panouri de control
La început, am studiat consumul de CPU.
Panoul de control Linkerd ~22 miliarde
Panoul de control Istio: ~750 miliarde
Panoul de control Istio folosește aproximativ de 35 de ori mai multe resurse de procesor, decât Linkerd. Desigur, totul este configurat implicit, iar multe resurse de procesor sunt consumate de istio-telemetry (poate fi dezactivat, renunțând la unele funcții). Chiar și fără acest component, obținem totuși mai mult de 100 miliarde, adică de 4 ori mai mult, decât la Linkerd.
Proxy-ul Sidecar
Apoi, am verificat utilizarea proxy-ului. Aici ar trebui să existe o dependență liniară de numărul de cereri, dar pentru fiecare sidecar există anumite costuri indirecte care afectează curba.
Linkerd: ~100 miliarde pentru irs-client, ~50 miliarde pentru irs-client-loadgen
Rezultatele par logice, deoarece proxy-ul client primește de două ori mai mult trafic decât proxy-ul loadgen: pentru fiecare cerere ieșită de la loadgen, clientul primește o cerere de intrare și una de ieșire.
Istio/Envoy: ~155 miliarde pentru irs-client, ~75 miliarde pentru irs-client-loadgen
Vedem rezultate similare pentru sidecar-urile Istio.
Dar, în general, proxy-urile Istio/Envoy consumă aproximativ cu 50% mai multe resurse de procesor, decât Linkerd.
Aceeași schematică o vedem și pe partea serverului:
Linkerd: ~50 miliarde pentru irs-server
Istio/Envoy: ~80 miliarde pentru irs-server
Pe partea serverului, sidecar-ul Istio/Envoy consumă aproximativ cu 60% mai multe resurse de procesor, decât Linkerd.
Concluzie
Proxy-ul Istio Envoy consumă cu 50+% mai mult CPU decât Linkerd, pe sarcina noastră simulată. Panoul de control Linkerd consumă mult mai puține resurse decât Istio, în special în ceea ce privește componentele de bază.
Încă ne gândim la cum să reducem aceste costuri. Dacă aveți idei, împărtășiți-le!
Sursa: habr.com
