Canary Deployment in Kubernetes #3: Istio

Utilizzo di Istio+Kiali per avviare e visualizzare il Canary deployment

Canary Deployment in Kubernetes #3: Istio

Articoli di questo ciclo

  1. Canary Deployment in Kubernetes #1: Gitlab CI
  2. Canary Deployment in Kubernetes #2: Argo Rollouts
  3. (questo articolo)
  4. Canary Deployment utilizzando Jenkins-X Istio Flagger

Deployment Canary

Speriamo che tu abbia letto la prima parte, dove spiegavamo brevemente cosa sono i Canary deployments e mostravamo come implementarli utilizzando le risorse standard di Kubernetes.

Istio

E presumiamo che leggendo questo articolo tu conosca già Istio. Se non lo sai, puoi leggere di lui qui.

Applicazione per test

Canary Deployment in Kubernetes #3: Istio

Ogni pod contiene due container: la nostra applicazione e istio-proxy.

Utilizzeremo 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 consultati nei seguenti yaml:

Avvio dell'applicazione di test autonomamente

Se vuoi seguire il mio esempio e utilizzare questa applicazione di test da solo, vedi il readme del progetto.

Deployment iniziale

Quando avviamo il primo Deployment vediamo che i pod della nostra applicazione hanno solo 2 container ciascuno, il che significa che il sidecar di Istio è ancora in fase di implementazione:

Canary Deployment in Kubernetes #3: Istio

E vediamo anche Istio Gateway Loadbalancer nel namespace istio-system:

Canary Deployment in Kubernetes #3: Istio

Creazione del traffico

Utilizzeremo il seguente IP per generare traffico, che sarà ricevuto dai pod frontend e ridiretto ai pod backend:

while true; do curl -s --resolve 'frontend.istio-test:80:35.242.202.152' frontend.istio-test; sleep 0.1; done

Aggiungeremo anche frontend.istio-test al nostro file hosts.

Visualizzazione Mesh attraverso Kiali

Abbiamo installato un'applicazione di test e Istio insieme a Tracing, Grafana, Prometheus e Kiali (maggiori dettagli su readme del progetto). Pertanto, possiamo utilizzare Kiali tramite:

istioctl dashboard kiali # admin:admin

Canary Deployment in Kubernetes #3: Istio

Kiali visualizza il traffico attuale attraverso la Mesh

Come possiamo vedere, il 100% del traffico raggiunge il servizio frontend, quindi al pod frontend con etichetta v1, poiché utilizziamo un semplice proxy nginx che reindirizza le richieste al servizio backend, che a sua volta le reindirizza ai pod backend con etichetta v1.

Kiali funziona perfettamente con Istio e offre una soluzione 'out of the box' per la visualizzazione della Mesh. È semplicemente fantastico.

Deployment Canary

Il nostro backend ha già due deployment k8s, uno per v1 e uno per v2. Ora dobbiamo solo 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 istio.yaml:

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

Canary Deployment in Kubernetes #3: Istio

Vediamo che il 10% delle richieste è 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

Canary Deployment in Kubernetes #3: Istio

Passo 3: 100%

Ora il deployment Canary può dirsi completato e tutto il traffico è reindirizzato a v2:

Canary Deployment in Kubernetes #3: Istio

Testare Canary manualmente

Supponiamo che al momento stiamo inviando al backend v2 il 10% di tutte le richieste. Cosa succede se vogliamo testare manualmente v2 per assicurarci che tutto funzioni come previsto?

Possiamo aggiungere una regola di corrispondenza speciale basata sugli header 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: 10

Ora, utilizzando curl possiamo forzare la richiesta a v2 inviando l'intestazione:

Canary Deployment in Kubernetes #3: Istio

Le richieste senza intestazione saranno ancora gestite con un rapporto di 1/10:

Canary Deployment in Kubernetes #3: Istio

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 dovrebbe andare a v2:

Canary Deployment in Kubernetes #3: Istio

Vediamo che il frontend v1 e v2 inoltrano entrambi il traffico nel rapporto di 1/10 verso il backend v1 e v2.

E se avessimo bisogno di inoltrare il traffico da frontend-v2 solo a backend-v2, poiché non è compatibile con v1? Per questo impostiamo un rapporto di 1/10 per il frontend, che controlla quale traffico va a backend-v2 utilizzando la corrispondenza per 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: 100

Di conseguenza, otteniamo ciò di cui abbiamo bisogno:

Canary Deployment in Kubernetes #3: Istio

Differenze rispetto all'approccio manuale Canary

In parte uno Abbiamo eseguito il deployment Canary manualmente, utilizzando anche due deployment k8s. In quel caso, gestivamo il rapporto delle richieste modificando il numero di repliche. Questo approccio funziona, ma presenta seri svantaggi.

Istio offre la possibilità di definire il rapporto delle richieste indipendentemente dal numero di repliche. Ciò significa, ad esempio, che possiamo utilizzare gli HPA (Horizontal Pod Autoscalers — scalabilità orizzontale dei pod) e non è necessario configurarlo in base allo stato attuale del deployment Canary.

Risultato

Istio funziona ottimamente e utilizzandolo insieme a Kiali otteniamo una combinazione molto potente. Il prossimo nel mio elenco di interessi è la combinazione di Spinnaker con Istio per l'automazione e l'analisi Canary.

Fonte: habr.com

Acquista hosting affidabile per siti web con protezione DDoS, server VPS VDS 🔥 Acquista hosting affidabile per siti web con protezione DDoS, server VPS VDS | ProHoster