Canary Deployment in Kubernetes #3: Istio

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

Canary Deployment in Kubernetes #3: Istio

Articoli di questo ciclo

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

Distribuzione Canary

Speriamo che abbiate letto la prima parte, 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 qui.

Applicazione per test

Canary Deployment in Kubernetes #3: Istio

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 readme del progetto.

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:

Canary Deployment in Kubernetes #3: Istio

Vediamo anche Istio Gateway Loadbalancer nel namespace istio-system:

Canary Deployment in Kubernetes #3: Istio

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 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 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 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 è 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

Canary Deployment in Kubernetes #3: Istio

Passo 3: 100%

Ora il deployment Canary può considerarsi completato e tutto il traffico viene reindirizzato a v2:

Canary Deployment in Kubernetes #3: Istio

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: 10

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

Canary Deployment in Kubernetes #3: Istio

Le richieste senza intestazione saranno ancora gestite dal rapporto 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 deve andare a v2:

Canary Deployment in Kubernetes #3: Istio

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: 100

Di conseguenza otteniamo ciò di cui abbiamo bisogno:

Canary Deployment in Kubernetes #3: Istio

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

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