Bruk av Istio+Kiali for å implementere og visualisere Canary-deployment

Artiklene i denne serien
- (denne artikkelen)
- Canary Deployment ved hjelp av Jenkins-X Istio Flagger
Canary Deployment
Vi håper du har lest , der vi kort forklarte hva Canary-deployments er og viste hvordan man implementerer det med standard Kubernetes-ressurser.
Istio
Og vi antar at ved å lese denne artikkelen, allerede vet hva Istio er. Hvis ikke, kan du lese om det .
Applikasjon for tester

Hver pod inneholder to containere: vår applikasjon og istio-proxy.
Vi vil bruke en enkel testapplikasjon med pods frontend-nginx og backend i Python. Pod-en med nginx vil bare omdirigere hver forespørsel til pod-en med backend og fungere som en proxy. Detaljene kan sees nærmere i de følgende yaml-ene:
Kjøre testapplikasjonen selv
Hvis du ønsker å følge mitt eksempel og bruke denne testapplikasjonen selv, se. .
Første Deployment
Ved oppstart av den første Deployment ser vi at pod-ene til applikasjonen vår har bare to containere hver, det vil si at Istio sidecar for øyeblikket bare er i ferd med å bli implementert:

Og vi ser også Istio Gateway Loadbalancer i namespace istio-system:

Generering av trafikk
Vi vil bruke følgende IP for å generere trafikk som vil bli mottatt av frontend-pod-ene og omdirigert til backend-pod-ene:
while true; do curl -s --resolve 'frontend.istio-test:80:35.242.202.152' frontend.istio-test; sleep 0.1; done
Vi vil også legge til frontend.istio-test i vår hosts-fil.
Se Mesh gjennom Kiali
Vi har installert testapplikasjonen og Istio sammen med Tracing, Grafana, Prometheus og Kiali (se mer ). Derfor kan vi bruke Kiali gjennom:
istioctl dashboard kiali # admin:admin

Kiali visualiserer den nåværende trafikken gjennom Mesh
Som vi ser, går 100% av trafikken til frontend-tjenesten, deretter til frontend-poden med label v1, siden vi bruker en enkel nginx-proxy som omdirigerer forespørslene til backend-tjenesten, som så omdirigerer dem til backend-pod-ene med label v1.
Kiali fungerer utmerket sammen med Istio og gir en løsning for visualisering av Mesh. Rett og slett fantastisk.
Canary Deployment
Vår backend har allerede to k8s-deployment, en for v1 og en for v2. Nå trenger vi bare å si til Istio å omdirigere en viss prosentandel av forespørslene til v2.
Trinn 1: 10%
Og alt vi trenger å gjøre er å justere vekten til VirtualService i :
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 
Vi ser at 10% av forespørslene er omdirigert til v2.
Trinn 2: 50%
Og nå er det enkelt å øke det til 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 
Trinn 3: 100%
Nå kan Canary-deployeringen anses å være fullført, og all trafikk dirigeres til v2:

Manuell testing av Canary
La oss si at vi nå sender 10% av alle forespørslene til backend v2. Hva om vi vil teste v2 manuelt for å sikre at alt fungerer som vi forventer?
Vi kan legge til en spesialregel basert på HTTP-overskrifter:
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: 10Nå kan vi bruke curl for å tvinge et forespørsel til v2 ved å sende overskriften:
![]()
Forespørslene uten overskrift vil fortsatt bli administrert med 1/10-forholdet:

Canary for to avhengige versjoner
Nå ser vi på et tilfelle der vi har versjon v2 for både frontend og backend. For begge har vi angitt at 10% av trafikken skal gå til v2:

Vi ser at frontend v1 og v2 begge videresender trafikk i forholdet 1/10 til backend v1 og v2.
Hva om vi måtte videresende trafikk fra frontend-v2 bare til backend-v2, fordi den ikke er kompatibel med v1? For dette vil vi sette 1/10-forholdet for frontend, som styrer hvilken trafikk som går til backend-v2 ved å bruke samsvar på 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: 100Resultatet er det vi trenger:

Forskjeller fra manuell Canary-metode
I den første delen Vi utførte Canary-deployment manuelt, også ved å bruke to k8s-deployments. Der styrte vi forholdet mellom forespørslene ved å endre antall replikas. Denne metoden fungerer, men har alvorlige ulemper.
Istio gir oss muligheten til å definere forholdet mellom forespørslene uavhengig av antall replikas. Det betyr for eksempel at vi kan bruke HPAs (Horizontal Pod Autoscalers — horisontal skalering av pods) uten å måtte konfigurere det i samsvar med den nåværende tilstanden til Canary-deployeringen.
Resultat
Istio fungerer utmerket, og ved å bruke det sammen med Kiali får vi en veldig kraftig kombinasjon. Neste på listen min er kombinasjonen av Spinnaker med Istio for automatisering og Canary-analyse.
Kilde: habr.com
