
Introduzione
Noi di abbiamo iniziato a implementare Istio come service mesh. In linea di principio, siamo soddisfatti, tranne per una cosa: è costoso.
In per Istio si dice:
Con Istio 1.1, il proxy consuma circa 0,6 vCPU (nuclei virtuali) ogni 1000 richieste al secondo.
Per la prima regione nella service mesh (due proxy per ogni lato della connessione), avremo 1200 nuclei solo per i proxy, calcolando un milione di richieste al secondo. Secondo il calcolatore dei costi di Google, il costo è di circa $40/al mese/per nucleo per la configurazione n1-standard-64, quindi questa regione ci costerà oltre 50 mila dollari al mese per 1 milione di richieste al secondo.
Ivan Sim () le latenze della service mesh dell'anno scorso e ha promesso lo stesso per la memoria e la CPU, ma non è riuscito:
A quanto pare, il file values-istio-test.yaml aumenterà notevolmente le richieste alla CPU. Se ho calcolato bene, servono circa 24 nuclei di CPU per il pannello di controllo e 0,5 CPU per ogni proxy. Non ne ho così tanti. Ripeterò i test quando mi verranno dati più risorse.
Volevo verificare di persona quanto siano simili le prestazioni di Istio rispetto a un'altra service mesh open source: .
Installazione della service mesh
Per prima cosa, ho installato nel cluster :
$ supergloo init
installando la versione supergloo 0.3.12
usando 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 usato SuperGloo perché semplifica notevolmente l'impostazione iniziale della service mesh. Non ho dovuto fare quasi nulla. In produzione non usiamo SuperGloo, ma per un compito simile è perfetto. Ho dovuto eseguire solo un paio di comandi su ciascuna service mesh. Ho utilizzato due cluster per l'isolamento: uno per Istio e l'altro per Linkerd.
L'esperimento è stato condotto su Google Kubernetes Engine. Ho usato Kubernetes 1.12.7-gke.7 e un pool di nodi n1-standard-4 con ridimensionamento automatico dei nodi (minimo 4, massimo 16).
Poi ho installato entrambe le service mesh dalla riga di comando.
Per prima cosa Linkerd:
$ supergloo install linkerd --name linkerd
+---------+--------------+---------+---------------------------+
| INSTALL | TYPE | STATUS | DETAILS |
+---------+--------------+---------+---------------------------+
| linkerd | Linkerd Mesh | In attesa | abilitato: vero |
| | | | versione: stable-2.3.0 |
| | | | namespace: linkerd |
| | | | mtls abilitato: vero |
| | | | auto inject abilitato: vero |
+---------+--------------+---------+---------------------------+Poi Istio:
$ supergloo install istio --name istio --installation-namespace istio-system --mtls=true --auto-inject=true
+---------+------------+---------+---------------------------+
| INSTALL | TYPE | STATUS | DETAILS |
+---------+------------+---------+---------------------------+
| istio | Istio Mesh | In attesa | abilitato: vero |
| | | | versione: 1.0.6 |
| | | | namespace: istio-system |
| | | | mtls abilitato: vero |
| | | | auto inject abilitato: vero |
| | | | grafana abilitato: vero |
| | | | prometheus abilitato: vero |
| | | | jaeger abilitato: vero |
+---------+------------+---------+---------------------------+Il crash-loop ha preso alcuni minuti, e poi i pannelli di controllo si sono stabilizzati.
(Nota. SuperGloo supporta attualmente 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
Per far sì che Istio installi il sidecar Envoy, utilizziamo il sidecar-injector — MutatingAdmissionWebhook. Non ne parleremo in questo articolo. Dirò solo che è un controllore che monitora l'accesso di tutti i nuovi pod e aggiunge dinamicamente sidecar e initContainer, che si occupa dei compiti iptables.
In Shopify abbiamo scritto il nostro controllore di accesso per l'iniezione dei sidecar, ma in questo benchmark ho utilizzato il controllore fornito con Istio. Il controllore di default inietta i sidecar quando nel namespace è presente l'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 etichettatoImpostazione dell'iniezione automatica di Linkerd
Per configurare l'iniezione 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: AttivoSimulatore di tolleranza ai guasti di Istio
Abbiamo sviluppato un simulatore di resilienza di Istio per sperimentare traffico specifico per Shopify. Avevamo bisogno di uno strumento per creare una topologia arbitraria che rappresentasse una parte specifica del grafo del nostro servizio, con impostazioni dinamiche per modellare carichi di lavoro specifici.
L'infrastruttura di Shopify subisce una grande pressione durante le vendite lampo. In questo contesto, Shopify . I grandi clienti a volte avvisano in anticipo riguardo a vendite lampo programmati. Altri le effettuano inaspettatamente, a qualsiasi ora del giorno e della notte.
Volevamo che il nostro simulatore di resilienza modellasse i flussi di lavoro che corrispondevano a topologie e carichi di lavoro che in passato avevano causato sovraccarichi all'infrastruttura di Shopify. L'obiettivo principale nell'utilizzare un service mesh è che abbiamo bisogno di affidabilità e resilienza a livello di rete, ed è importante per noi che il service mesh gestisca efficacemente i carichi che in passato hanno compromesso il funzionamento dei servizi.
Al centro del simulatore di resilienza c'è un nodo di lavoro che funge da nodo del service mesh. Il nodo di lavoro può essere configurato staticamente all'avvio o dinamicamente tramite REST API. Utilizziamo la configurazione dinamica dei nodi di lavoro per creare flussi di lavoro come test di regressione.
Ecco un esempio di tale processo:
- Avviamo 10 server come
barun servizio che restituisce una risposta200/OKdopo 100 ms. - Avviamo 10 client, ognuno dei quali invia 100 richieste al secondo a
bar. - Ogni 10 secondi rimuoviamo 1 server e monitoriamo gli errori
5xxsul client.
Alla fine del ciclo di lavoro, analizziamo i log e le metriche per verificare se il test è stato superato. In questo modo, scopriamo le prestazioni del nostro service mesh e eseguiamo un test di regressione per confermare le nostre ipotesi sulla resilienza.
(Nota. Stiamo pensando di aprire il codice sorgente del simulatore di resilienza di Istio, ma non siamo ancora pronti per farlo.)
Simulatore di resilienza di Istio per il benchmark del service mesh
Stiamo configurando diversi nodi di lavoro del 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 di traffico stabile tra 9 punti finali. I sidecar in irs-client-loadgen e irs-server ricevono 100 richieste al secondo, e irs-client — 200 (in entrata e in uscita).
Monitoriamo l'utilizzo delle risorse tramite , perché non abbiamo un cluster Prometheus.
Risultati
Pannelli di controllo
Inizialmente abbiamo studiato il consumo della CPU.
Pannello di controllo Linkerd ~22 miliardi
Pannello di controllo Istio: ~750 miliardi
Il pannello di controllo Istio utilizza circa 35 volte più risorse della CPU, rispetto a Linkerd. Ovviamente, tutto è impostato di default e molte risorse della CPU sono consumate da istio-telemetry (può essere disattivato rinunciando ad alcune funzionalità). Anche rimuovendo questo componente, otteniamo ancora più di 100 miliardi, cioè 4 volte di più, rispetto a Linkerd.
Proxy sidecar
Poi abbiamo verificato l'utilizzo del proxy. Qui dovrebbe esserci una relazione lineare con il numero di richieste, ma per ogni sidecar ci sono alcune spese generali che influenzano la curva.
Linkerd: ~100 miliardi per irs-client, ~50 miliardi 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 per il client.
Istio/Envoy: ~155 miliardi per irs-client, ~75 miliardi per irs-client-loadgen
Vediamo risultati simili per i sidecar di Istio.
Ma nel complesso, il proxy Istio/Envoy consuma circa il 50% in più di risorse della CPU, rispetto a Linkerd.
La stessa tendenza è visibile 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% in più di risorse della CPU, rispetto a Linkerd.
Conclusione
Il proxy Istio Envoy consuma oltre il 50% di CPU in più rispetto a Linkerd, sulla nostra workload simulata. Il pannello di controllo Linkerd consuma molto meno risorse rispetto a Istio, soprattutto per quanto riguarda i componenti principali.
Stiamo ancora pensando a come ridurre questi costi. Se hai idee, condividile!
Fonte: habr.com
