
Introduzione
Noi di ci siamo occupati dell'implementazione di Istio come service mesh. In linea generale, tutto va bene, tranne per una cosa: è costoso.
In per Istio si dice:
Con Istio 1.1, il proxy consuma circa 0,6 vCPU (core virtuali) per 1000 richieste al secondo.
Per la prima regione nel service mesh (2 proxy da ciascun lato della connessione) avremo bisogno di 1200 core solo per i proxy, basandoci su un milione di richieste al secondo. Secondo il calcolatore dei costi di Google, circa $40/mese/core per la configurazione n1-standard-64, il che significa che questa regione ci costerà più di 50.000 dollari al mese per un milione di richieste al secondo.
Ivan Sim () le latenza della service mesh dell'anno scorso e ha promesso lo stesso per memoria e CPU, ma non ci è riuscito:
Sembra che values-istio-test.yaml aumenterà notevolmente le richieste alla CPU. Se ho calcolato correttamente, servono circa 24 core per il pannello di controllo e 0,5 CPU per ogni proxy. Non ho così tante risorse. Ripeterò i test quando riceverò più risorse.
Volevo vedere di persona quanto i risultati di Istio somigliassero ad un'altra service mesh open source: .
Installazione della service mesh
Per prima cosa, ho installato nel cluster :
$ supergloo init
installazione della versione 0.3.12 di supergloo
utilizzando l'uri del chart https://storage.googleapis.com/supergloo-helm/charts/supergloo-0.3.12.tgz
configmap/sidecar-injection-resources creato
serviceaccount/supergloo creato
serviceaccount/discovery creato
serviceaccount/mesh-discovery creato
clusterrole.rbac.authorization.k8s.io/discovery creato
clusterrole.rbac.authorization.k8s.io/mesh-discovery creato
clusterrolebinding.rbac.authorization.k8s.io/supergloo-role-binding creato
clusterrolebinding.rbac.authorization.k8s.io/discovery-role-binding creato
clusterrolebinding.rbac.authorization.k8s.io/mesh-discovery-role-binding creato
deployment.extensions/supergloo creato
deployment.extensions/discovery creato
deployment.extensions/mesh-discovery creato
installazione riuscita!Ho utilizzato SuperGloo perché semplifica notevolmente il setup iniziale del service mesh. Non ho dovuto fare quasi nulla. In produzione, non usiamo SuperGloo, ma per compiti come questo è perfetto. Ho dovuto utilizzare letteralmente un paio di comandi per ogni service mesh. Ho utilizzato due cluster per l'isolamento — uno per Istio e uno per Linkerd.
L'esperimento è stato condotto su Google Kubernetes Engine. Ho utilizzato Kubernetes 1.12.7-gke.7 e un pool di nodi n1-standard-4 con scaling automatico dei nodi (minimo 4, massimo 16).
Dopo, ho installato entrambe le service mesh dalla riga di comando.
Prima 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 |
+---------+--------------+---------+---------------------------+Poi 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 |
+---------+------------+---------+---------------------------+Il crash-loop ha impiegato diversi minuti, poi i pannelli di controllo si sono stabilizzati.
(Nota. SuperGloo attualmente supporta solo Istio 1.0.x. Ho ripetuto l'esperimento con Istio 1.1.3, ma non ho notato alcuna differenza significativa.)
Impostazione dell'iniezione automatica di Istio
Perché Istio installi il sidecar Envoy, utilizziamo l'iniettore di sidecar — MutatingAdmissionWebhook. Non ne parleremo in questo articolo. Dico solo che è un controller che monitora l'accesso di tutti i nuovi pod e aggiunge dinamicamente sidecar e initContainer, il quale è responsabile delle operazioni iptables.
Noi di Shopify abbiamo scritto il nostro controller di accesso per l'inserimento dei sidecar, ma in questo benchmark ho utilizzato il controller fornito con Istio. Il controller di default inserisce i sidecar quando nell'namespace c'è un'etichetta istio-injection: enabled:
$ kubectl label namespace irs-client-dev istio-injection=enabled
namespace/irs-client-dev etichettato
$ kubectl label namespace irs-server-dev istio-injection=enabled
namespace/irs-server-dev etichettatoConfigurazione dell'inserimento automatico di Linkerd
Per configurare l'inserimento dei sidecar di Linkerd, utilizziamo le annotazioni (le ho aggiunte manualmente tramite kubectl edit):
metadata:
annotations:
linkerd.io/inject: enabled$ k edit ns irs-server-dev
namespace/irs-server-dev modificato
$ 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: ActiveSimulatore di resilienza di Istio
Abbiamo creato un simulatore di tolleranza ai guasti di Istio per sperimentare con il traffico specifico per Shopify. Avevamo bisogno di uno strumento per creare topologie arbitrarie che rappresentassero una parte specifica del grafo del nostro servizio con configurazioni dinamiche per simulare carichi di lavoro specifici.
L'infrastruttura di Shopify subisce un grande carico durante le vendite flash. In questo contesto, Shopify . Grandi clienti talvolta avvisano di una vendita flash programmata. Altri le organizzano inaspettatamente, in qualsiasi momento della giornata e della notte.
Volevamo che il nostro simulatore di tolleranza ai guasti riproducesse flussi di lavoro che corrispondessero a topologie e carichi di lavoro che in passato avevano causato sovraccarichi all'infrastruttura di Shopify. L'obiettivo principale dell'uso del service mesh è garantire la resilienza e la tolleranza ai guasti a livello di rete, ed è importante che il service mesh gestisca efficacemente i carichi che in precedenza avevano disturbato il funzionamento dei servizi.
Alla base del simulatore di tolleranza agli errori c'è un nodo di lavoro che agisce come nodo di service mesh. Il nodo di lavoro può essere configurato staticamente all'avvio o dinamicamente tramite API REST. Utilizziamo la configurazione dinamica dei nodi di lavoro per creare flussi di lavoro sotto forma di test regressivi.
Ecco un esempio di questo processo:
- Avviamo 10 server come
barservizio che restituisce una risposta200/OKdopo 100 ms. - Avviamo 10 client, ciascuno dei quali invia 100 richieste al secondo a
bar. - Ogni 10 secondi rimuoviamo 1 server e monitoriamo gli errori
5xxsul client.
Alla fine del flusso di lavoro, esaminiamo i log e le metriche e verifichiamo se il test è stato superato. In questo modo possiamo valutare le performance della nostra service mesh e condurre un test regressivo per verificare le nostre ipotesi sulla tolleranza agli errori.
(Nota. Stiamo pensando di rendere pubblico il codice sorgente del simulatore di tolleranza agli errori di Istio, ma non siamo ancora pronti per farlo.)
Simulatore di tolleranza agli errori di Istio per il benchmarking della service mesh
Configuriamo diversi nodi di lavoro per il simulatore:
irs-client-loadgen: 3 repliche che inviano 100 richieste al secondo airs-client.irs-client: 3 repliche che ricevono la richiesta, attendono 100 ms e reindirizzano la richiesta airs-server.irs-server: 3 repliche che restituiscono200/OKdopo 100 ms.
Con questa configurazione, possiamo misurare un flusso stabile di traffico tra 9 endpoint. I sidecar in irs-client-loadgen e irs-server ricevono 100 richieste al secondo, mentre irs-client — 200 (in ingresso e in uscita).
Monitoriamo l'uso delle risorse tramite , poiché non abbiamo un cluster Prometheus.
Risultati
Pannelli di controllo
Inizialmente, abbiamo esaminato il consumo della CPU.
Pannello di controllo Linkerd ~22 millisecondi
Pannello di controllo Istio: ~750 millisecondi
Il pannello di controllo Istio utilizza circa 35 volte più risorse di CPU, rispetto a Linkerd. Ovviamente, tutto è impostato per default e molto delle risorse CPU sono consumate da istio-telemetry (che può essere disattivato rinunciando ad alcune funzionalità). Anche senza questo componente, si ottiene comunque più di 100 millisecondi, cioè 4 volte di più, rispetto a Linkerd.
Proxy sidecar
Poi abbiamo controllato l'uso del proxy. Qui dovrebbe esserci una dipendenza lineare dal numero di richieste, ma per ogni sidecar ci sono alcune spese generali che influenzano la curva.
Linkerd: ~100 millisecondi per irs-client, ~50 millisecondi per irs-client-loadgen
I risultati sembrano logici, poiché il proxy client riceve il doppio del traffico rispetto al proxy loadgen: per ogni richiesta in uscita da loadgen, ci sono una richiesta in entrata e una in uscita da parte del client.
Istio/Envoy: ~155 miliardi per irs-client, ~75 miliardi per irs-client-loadgen
Osserviamo risultati simili per i sidecar di Istio.
Tuttavia, in generale, il proxy Istio/Envoy consuma circa il 50% di risorse CPU in più, rispetto a Linkerd.
La stessa situazione si verifica sul lato server:
Linkerd: ~50 miliardi per irs-server
Istio/Envoy: ~80 miliardi per irs-server
Sul lato server, il sidecar Istio/Envoy consuma circa il 60% di risorse CPU in più, rispetto a Linkerd.
Conclusione
Il proxy Istio Envoy consuma oltre il 50% di CPU in più rispetto a Linkerd, sulla nostra simulazione di carico di lavoro. La dashboard di Linkerd utilizza molte meno risorse rispetto a Istio, in particolare per quanto riguarda i componenti principali.
Stiamo ancora valutando come ridurre questi costi. Se hai idee, condividile!
Fonte: habr.com
