Utilizzo di Istio+Kiali per avviare e visualizzare la distribuzione Canary

Articoli di questo ciclo
- (questo articolo)
- Distribuzione Canary usando Jenkins-X Istio Flagger
Distribuzione Canary
Speriamo che abbiate letto , dove abbiamo brevemente spiegato cosa sono le distribuzioni Canary e mostrato come implementarle utilizzando le risorse standard di Kubernetes.
Istio
E supponiamo che leggendo questo articolo sappiate già cos'è Istio. Se non lo sapete, potete leggere di esso .
Applicazione per test

Ogni pod contiene due contenitori: la nostra applicazione e istio-proxy.
Useremo una semplice applicazione di test con pod frontend-nginx e backend in python. Il pod con nginx reindirizzerà semplicemente ogni richiesta al pod con backend e funzionerà come proxy. I dettagli possono essere visti nei seguenti YAML:
Esecuzione dell'applicazione di test in autonomia
Se desiderate seguire il mio esempio e utilizzare questa applicazione di test autonomamente, consulta il .
Distribuzione iniziale
Avviando la prima distribuzione, vediamo che i pod della nostra applicazione hanno solo 2 contenitori ciascuno, ovvero che l'Istio sidecar è ancora in fase di implementazione:

Vediamo anche Istio Gateway Loadbalancer nel namespace istio-system:

Creazione del traffico
Useremo il seguente IP per generare traffico, che sarà ricevuto dai pod frontend e reindirizzato ai pod backend:
while true; do curl -s --resolve 'frontend.istio-test:80:35.242.202.152' frontend.istio-test; sleep 0.1; done
Aggiungete anche frontend.istio-test al nostro file hosts.
Visualizzazione del Mesh tramite Kiali
Abbiamo installato l'applicazione di test e Istio insieme a Tracing, Grafana, Prometheus e Kiali (vedi in dettaglio ). Pertanto, possiamo utilizzare Kiali tramite:
istioctl dashboard kiali # admin:admin

Kiali visualizza il traffico attuale attraverso il Mesh
Come possiamo vedere, il 100% del traffico arriva al servizio frontend, poi al pod frontend con label v1, poiché utilizziamo un semplice nginx-proxy, che reindirizza le richieste al servizio backend, il quale a sua volta le reindirizza ai pod backend con label v1.
Kiali funziona ottimamente con Istio e offre una soluzione pronta per la visualizzazione del Mesh. Davvero fantastico.
Distribuzione Canary
Il nostro backend ha già due distribuzioni k8s, una per v1 e una per v2. Ora dobbiamo semplicemente dire a Istio di reindirizzare una certa percentuale di richieste a v2.
Passo 1: 10%
E tutto ciò che dobbiamo fare è regolare il peso del VirtualService in :
apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
name: backend
namespace: default
spec:
gateways: []
hosts:
- "backend.default.svc.cluster.local"
http:
- match:
- {}
route:
- destination:
host: backend.default.svc.cluster.local
subset: v1
port:
number: 80
weight: 90
- destination:
host: backend.default.svc.cluster.local
subset: v2
port:
number: 80
weight: 10 
Vediamo che il 10% delle richieste è stato reindirizzato a v2.
Passo 2: 50%
E ora è sufficiente aumentarlo al 50%:
apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
name: backend
namespace: default
spec:
...
- destination:
host: backend.default.svc.cluster.local
subset: v1
port:
number: 80
weight: 50
- destination:
host: backend.default.svc.cluster.local
subset: v2
port:
number: 80
weight: 50 
Passo 3: 100%
Ora il deployment Canary può considerarsi completato e tutto il traffico viene reindirizzato a v2:

Testing Canary manualmente
Supponiamo che attualmente stiamo inviando al backend v2 il 10% di tutte le richieste. E se volessimo testare manualmente v2 per assicurarci che tutto funzioni come ci aspettiamo?
Possiamo aggiungere una regola di corrispondenza speciale basata sulle intestazioni HTTP:
apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
name: backend
namespace: default
spec:
gateways: []
hosts:
- "backend.default.svc.cluster.local"
http:
- match:
- headers:
canary:
exact: "canary-tester"
route:
- destination:
host: backend.default.svc.cluster.local
subset: v2
port:
number: 80
weight: 100
- match:
- {}
route:
- destination:
host: backend.default.svc.cluster.local
subset: v1
port:
number: 80
weight: 90
- destination:
host: backend.default.svc.cluster.local
subset: v2
port:
number: 80
weight: 10Ora utilizzando curl possiamo forzare una richiesta a v2 inviando l'intestazione:
![]()
Le richieste senza intestazione saranno ancora gestite dal rapporto 1/10:

Canary per due versioni dipendenti
Ora consideriamo un caso in cui abbiamo la versione v2 sia per il frontend che per il backend. Per entrambi abbiamo specificato che il 10% del traffico deve andare a v2:

Vediamo che il frontend v1 e v2 entrambi inoltrano il traffico in un rapporto di 1/10 verso il backend v1 e v2.
E se avessimo bisogno di reindirizzare il traffico da frontend-v2 solo a backend-v2, perché non è compatibile con v1? Per questo impostiamo un rapporto di 1/10 per il frontend, che controlla quale traffico arriva a backend-v2 utilizzando la corrispondenza basata su sourceLabels :
apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
name: backend
namespace: default
spec:
gateways: []
hosts:
- "backend.default.svc.cluster.local"
http:
...
- match:
- sourceLabels:
app: frontend
version: v2
route:
- destination:
host: backend.default.svc.cluster.local
subset: v2
port:
number: 80
weight: 100Di conseguenza otteniamo ciò di cui abbiamo bisogno:

Differenze rispetto all'approccio manuale di Canary
In prima parte abbiamo eseguito il Canary deployment manualmente, utilizzando anche due deployment k8s. Lì gestivamo il rapporto delle richieste modificando il numero di repliche. Questo approccio funziona, ma presenta seri svantaggi.
Istio consente di definire il rapporto delle richieste indipendentemente dal numero di repliche. Questo significa, ad esempio, che possiamo utilizzare gli HPA (Horizontal Pod Autoscalers — scalabilità orizzontale dei pod) e non è necessario configurarlo secondo lo stato attuale del Canary deployment.
Risultato
Istio funziona ottimamente e utilizzandolo insieme a Kiali otteniamo una combinazione molto potente. Il prossimo elemento nella mia lista di interessi è la combinazione di Spinnaker con Istio per l'automazione e l'analisi di Canary.
Fonte: habr.com
