Použití Istio+Kiali k provádění a vizualizaci Canary nasazení

Články této série
- (tento článek)
- Canary Deployment pomocí Jenkins-X Istio Flagger
Canary Deployment
Doufáme, že jste si přečetli , kde jsme stručně vysvětlili, co jsou Canary deployments, a ukázali, jak je realizovat pomocí standardních prostředků Kubernetes.
Istio
A předpokládáme, že při čtení tohoto článku již víte, co je Istio. Pokud ne, můžete si o něm přečíst .
Aplikace pro testování

Každý pod obsahuje dva kontejnery: naši aplikaci a istio-proxy.
Použijeme jednoduchou testovací aplikaci s pody frontend-nginx a backend na pythonu. Pod s nginx bude prostě přesměrovávat každý požadavek na pod s backendem a fungovat jako proxy. Podrobnosti lze nalézt v následujících yaml:
Spuštění testovací aplikace samostatně
Pokud chcete následovat můj příklad a použít tuto testovací aplikaci samostatně, podívejte se na .
Počáteční nasazení
Při spuštění prvního nasazení vidíme, že pody naší aplikace mají pouze dva kontejnery, to znamená, že Istio sidecar se zatím pouze zavádí:

A také vidíme Istio Gateway Loadbalancer v namespace istio-system:

Vytvoření provozu
Použijeme následující IP, abychom vygenerovali provoz, který bude přijat frontend pody a přesměrován na backend pody:
while true; do curl -s --resolve 'frontend.istio-test:80:35.242.202.152' frontend.istio-test; sleep 0.1; done
Také přidáme frontend.istio-test do našeho hosts souboru.
Zobrazení Mesh přes Kiali
Nainstalovali jsme testovací aplikaci a Istio společně s Tracing, Grafana, Prometheus a Kiali (více viz ). Tudíž můžeme používat Kiali přes:
istioctl dashboard kiali # admin:admin

Kiali vizualizuje aktuální provoz přes Mesh
Jak vidíme, 100% provozu směřuje na frontendovou službu, poté na pod frontend s label v1, protože používáme jednoduchý nginx-proxy, který přesměrovává požadavky na backendovou službu, která je opět přesměrovává na backend pody s label v1.
Kiali skvěle funguje spolu s Istio a poskytuje hotové řešení pro vizualizaci Mesh. To je prostě skvělé.
Canary Deployment
Náš backend již má dvě k8s nasazení, jedno pro v1 a jedno pro v2. Teď musíme říct Istio, aby přesměrovalo určitý procentní podíl požadavků na v2.
Krok 1: 10%
A všechno, co potřebujeme udělat, je upravit váhu 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 
Vidíme, že 10 % požadavků je přesměrováno na v2.
Krok 2: 50 %
A teď stačí jen zvýšit toto číslo 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 
Krok 3: 100 %
Nyní může být nasazení Canary považováno za dokončené a veškerý provoz je přesměrován na v2:

Manuální testování Canary
Představme si, že nyní posíláme na backend v2 10 % všech požadavků. Co když chceme ručně otestovat v2, abychom se ujistili, že všechno funguje tak, jak očekáváme?
Můžeme přidat speciální odpovídající pravidlo založené na HTTP hlavičkách:
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: 10Nyní pomocí curl můžeme donutit požádat o v2 zasláním hlavičky:
![]()
Požadavky bez hlavičky budou stále řízeny vzorcem 1/10:

Canary pro dvě závislé verze
Nyní se podíváme na případ, kdy máme verzi v2 jak pro frontend, tak pro backend. U obou jsme uvedli, že 10 % provozu by mělo směřovat k v2:

Vidíme, že frontend v1 a v2 oba přesměrovávají provoz v poměru 1/10 na backend v1 a v2.
A co kdybychom potřebovali přesměrovávat provoz z frontend-v2 pouze na backend-v2, protože není kompatibilní s v1? K tomu nastavíme poměr 1/10 pro frontend, který řídí, jaký provoz se dostává na backend-v2 pomocí shody podle 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: 100Výsledkem je to, co potřebujeme:

Rozdíly oproti ručnímu přístupu Canary
V první části Canary deployment jsme prováděli ručně, také s využitím dvou nasazení k8s. Tam jsme spravovali poměr požadavků, měněním počtu replik. Tento přístup funguje, ale má vážné nevýhody.
Istio umožňuje definovat poměr požadavků nezávisle na počtu replik. To znamená, že můžeme například použít HPA (Horizontal Pod Autoscalers — horizontální škálování podů) a není třeba ho nastavovat podle aktuálního stavu Canary nasazení.
Výsledek
Istio funguje skvěle a používání jeho spolu s Kiali nám poskytuje velmi silnou kombinaci. Další, co mě zajímá, je kombinace Spinnakeru s Istio pro automatizaci a Canary analýzu.
Zdroj: habr.com
