Uporaba Istio+Kiali za izvajanje in vizualizacijo Canary deploymenta

Članki tega cikla
- (ta članek)
- Canary Deployment z uporabo Jenkins-X Istio Flagger
Canary Deployment
Upamo, da ste prebrali , kjer smo na kratko razložili, kaj so Canary deploymenti in pokazali, kako jih izvesti s pomočjo standardnih virov Kubernetes.
Istio
In predpostavljamo, da ob branju tega članka že veste, kaj je Istio. Če ne, lahko preberete o njem .
Aplikacija za teste

Vsak pod vsebuje dva kontejnerja: našo aplikacijo in istio-proxy.
Uporabili bomo preprosto testno aplikacijo s podoma frontend-nginx in backend na python. Pod z nginx bo preprosto preusmerjal vsak zahtevek na pod z backend in deloval kot proxy. Podrobnosti si lahko ogledate v naslednjih yaml datotekah:
Zagon testne aplikacije samostojno
Če želite slediti mojemu primeru in samostojno uporabiti to testno aplikacijo, si oglejte .
Začetni Deployment
Ko zaženemo prvi Deployment, vidimo, da podi naše aplikacije vsebujejo le dva kontejnerja, torej se Istio sidecar še vedno vgrajuje:

Prav tako vidimo Istio Gateway Loadbalancer v namespace-u istio-system:

Ustvarjanje prometa
Uporabili bomo naslednji IP, da generiramo promet, ki ga bodo sprejeli frontend podi in preusmerili na backend pode:
while true; do curl -s --resolve 'frontend.istio-test:80:35.242.202.152' frontend.istio-test; sleep 0.1; done
Dodali bomo tudi frontend.istio-test v naš hosts datoteko.
Ogled Mesh preko Kiali
Namestili smo testno aplikacijo in Istio skupaj z Tracing, Grafano, Prometheusom in Kiali (podrobneje glej ). Tako lahko uporabimo Kiali preko:
istioctl dashboard kiali # admin:admin

Kiali vizualizira trenutni promet preko Mesh
Kot vidimo, 100% prometa pride na frontend storitev, nato na pod frontend-a z oznako v1, saj uporabljamo preprost nginx-proxy, ki preusmerja zahtevke na backend storitev, ki jih nato preusmerja na backend pode z oznako v1.
Kiali deluje odlično skupaj z Istio in ponuja povsem rešitev za vizualizacijo Mesh. Preprosto čudovito.
Canary Deployment
Naš backend že ima dva k8s deploymenta, enega za v1 in enega za v2. Zdaj moramo samo povedati Istio, naj preusmeri določen odstotek zahtevkov na v2.
Korak 1: 10%
In vse, kar moramo storiti, je prilagoditi težo VirtualService v :
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 
Vidimo, da je 10% poizvedb preusmerjeno na v2.
Korak 2: 50%
In zdaj je dovolj, da ga povečamo na 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 
Korak 3: 100%
Zdaj se lahko Canary izvajanje šteje za zaključeno in ves promet se preusmeri na v2:

Ročno testiranje Canary
Recimo, da trenutno pošiljamo na backend v2 10% vseh zahtev. Kaj pa, če želimo ročno testirati v2, da se prepričamo, da vse deluje, kot pričakujemo?
Lahko dodamo posebno ustrezno pravilo, ki temelji na HTTP glavah:
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: 10Zdaj lahko s pomočjo curl prisilimo zahtevo za v2 tako, da pošljemo glavo:
![]()
Zahteve brez glave bodo še vedno upravljane v razmerju 1/10:

Canary za dve odvisni različici
Zdaj bomo obravnavali situacijo, kjer imamo različico v2 tako za frontend kot za backend. Za obe smo določili, da mora 10% prometa iti na v2:

Vidimo, da oba frontend v1 in v2 preusmerjata promet v razmerju 1/10 na backend v1 in v2.
Kaj pa, če bi morali usmerjati promet z frontend-v2 samo na backend-v2, ker ni združljiv z v1? V tem primeru bomo nastavili razmerje 1/10 za frontend, ki nadzira, kateri promet pride na backend-v2 z uporabo ujemanja po 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: 100Kot smo potrebovali, smo tudi dobili:

Razlike v primerjavi z ročnim pristopom Canary
V prvega dela Canary deployment smo izvajali ročno, prav tako smo uporabili dva k8s deployments. Tam smo upravljali razmerje zahtev, s spreminjanjem števila replik. Tak pristop deluje, vendar ima resne pomanjkljivosti.
Istio omogoča določanje razmerja zahtev ne glede na število replik. To pomeni, da lahko na primer uporabimo HPAs (Horizontal Pod Autoscalers — horizontalno skaliranje podov) in ga ni treba nastaviti v skladu s trenutnim stanjem Canary deploya.
Zaključek
Istio deluje odlično in z njegovo uporabo skupaj s Kiali dobimo zelo močno kombinacijo. Naslednja kombinacija, ki me zanima, je Spinnaker z Istio za avtomatizacijo in analitiko Canary.
Izvor: habr.com
