Kontynuujemy omawianie integracji argo-rollouts z traffic splittingiem w ISTIO. W pierwszej części został omówiony temat Argo Rollouts bez ISTIO. Teraz czas na Argo Rollouts z ISTIO oraz opisanie subset leveli.
W pierwszej części rozpocząłem wprowadzenie najpierw do zwykłego podejścia w ISTIO do Traffic Splitting i zwykłe (proste) podstawy Argo-Rollouts. Teraz wszystko to połączę w całość, co pozwoli osiągnąć ISTIO Traffic Splitting z Argo-Rollouts, właśnie. Argo-Rollouts będzie zaprezentowane w dwóch opcjach: Host-level Traffic Splitting i Subset-level Traffic Splitting.
Słowo od redakcji: Sławek, nasz spec od skomplikowanych rozważań technicznych, dzieli się wiedzą także poza GitHubem. Tym razem prezentuje swoje podejście do instalacji ISTIO z oraz bez Argo Rollouts. A wszystko to z autorskim komentarzem i listą dobrych prkatyk.
Argo Rollouts z ISTIO
Zacznijmy od tego że Argo Rollout w kontekście ISTIO dostarcza 2 odrębne podejścia:
Istio provides two approaches for weighted traffic splitting, both approaches are available as options in Argo Rollouts:
Host-level traffic splitting
Subset-level traffic splitting
Subset-level
Subset-level jest bliższy klasycznemu podejściu ISTIO-way więc od niego zaczniemy
Folder w tym repo z plikami YAML: AR-z-ISTIO-SubsetLevelTrafficSplitting
tworzymy osobny NS, labelujemy go celem istio-injection i zakładamy konieczne obiekty:
kubectl create ns test-ar-istio
kubectl config set-context --current --namespace=test-ar-istio
kubectl -n istio-system get pods -l app=istiod --show-labels | grep rev
kubectl label namespace test-ar-istio istio-injection- istio.io/rev=asm-1162-2 --overwrite
kubectl apply -f deploy-consumer.yaml
kubectl apply -f destination-rule-Server-v1-v2.yaml
kubectl apply -f rollout-deploy-server-ISTIO.yaml
kubectl apply -f service_clusterip-consumer.yaml
kubectl apply -f service_clusterip-Server-v1v2.yaml
kubectl apply -f virtual-service-Server-wagi.yaml
teraz można wykonywac operacje wkoło AR:
kubectl argo rollouts set image test-rollout-istio app07=gimboo/nginx_nonroot3
kubectl argo rollouts promote test-rollout-istio
kubectl argo rollouts abort test-rollout-istioi
podczas testów widać że po SET wagi ustawiane są na 5 do 95:
$ kk get vs
NAME GATEWAYS HOSTS AGE
virtservice-app07 ["mesh","test-ar-istio/mygateway"] ["app07.test-ar-istio.svc.cluster.local","uk.bookinfo7.com"] 9m41s
$ kk get vs virtservice-app07 -o yaml
apiVersion: networking.istio.io/v1beta1
kind: VirtualService
metadata:
name: virtservice-app07
namespace: test-ar-istio
spec:
gateways:
- mesh
- test-ar-istio/mygateway
hosts:
- app07.test-ar-istio.svc.cluster.local
- uk.bookinfo7.com
http:
- name: primary
route:
- destination:
host: app07.test-ar-istio.svc.cluster.local
subset: version-v2
weight: 5
- destination:
host: app07.test-ar-istio.svc.cluster.local
subset: version-v1
weight: 95
zaś po PROMOTE na 100 do 0
$ kk get vs virtservice-app07 -o yaml[...]
http:
- name: primary
route:
- destination:
host: app07.test-ar-istio.svc.cluster.local
subset: version-v2
weight: 0
- destination:
host: app07.test-ar-istio.svc.cluster.local
subset: version-v1
weight: 100
dla przypomnienia w oryginalnym wsadowym pliku dla VS te wartości były zupełnie inne, ale nie ma to już znaczenia bo to AR zarządza od tej pory tymi wagami – innymi słowy modyfikuje nasze obiekty bez naszej wiedzy:
$ kk get vs -o yaml | grep -v apiVer| grep weight
weight: 100
weight: 0
$ kubectl argo rollouts set image test-rollout-istio app07=gimboo/nginx_nonroot2
rollout "test-rollout-istio" image updated
$ kk get vs -o yaml | grep -v apiVer| grep weight
weight: 95
weight: 5
$ kubectl argo rollouts promote test-rollout-istio
rollout 'test-rollout-istio' promoted
$ kk get vs -o yaml | grep -v apiVer| grep weight
weight: 100
weight: 0
zmiany w Traffic-Splitting realizujemy poprzez edycję virtual-service-Server-wagi.yml
http:
- route:
- destination:
host: app07.slawek.svc.cluster.local
subset: version-v2
weight: 100
- destination:
host: app07.slawek.svc.cluster.local
subset: version-v1
weight: 0
to 95/0 bierze się oczwyiście stąd:
kind: Rollout
[...] steps:
- setWeight: 5
Powyższe to podstawy ISTIO-wych podstaw, ale trzeba to mieć przed oczami przy analizie modeli opartych na Argo-Rollout.
Dla przypomnienia – w podejściu klasycznym (bez ARGO-rollout tylko czyste ważenie na istio destination-rules/subsets) mechanizm jest następujący:
- są 2 x deploy-Server , jeden poza label name:app07 ma też label version v1 , drugi ma v2
- jest destination-rule (dla tego deployu SERVER) która ma zdefiniowane 2 subsety – jeden subset żyje na labels:version:v1 a drugi na v2 i
- z kolei VirtualService (dla tego deployu SERVER) ma 1 route a w niej 2 destinations – jedna na subset1 a druga na subset2, jedna ma weight 100 a druga weight 0
w skrócie:
$ cat /virtual-service-Server-wagi.yml
[...]
- route:
- destination:
host: app07.slawek.svc.cluster.local
subset: version-v2
weight: 100
- destination:
host: app07.slawek.svc.cluster.local
subset: version-v1
weight: 0
$ cat /destination-rule-Server-v1-v2.yml
[...]
subsets:
- labels:
version: v1
name: version-v1
- labels:
version: v2
name: version-v2
Tu z kolei różnic między plikami VS i DestinationRule nie ma (pomijając że dla wersji z AR trzeba w DestRule wstawić jakiś label generyczny (np name=app07) +jest jedna drobna bo w VS jak jest route to tu ma name=primary) nie ma znaczenia jak ustawimy wagi w VS.yaml bo AR i tak zaraz przejmie sprawy
po wgraniu naszego destination-rule zostaje ona natychmiast zmodyfikowana przez AR (patrzymy na rollouts-pod-template-hash):
$ kubectl get destinationrules destrule-app07 -o yamlapiVersion: networking.istio.io/v1beta1
kind: DestinationRule
metadata:
name: destrule-app07
namespace: test-ar-istio
spec:
host: app07.test-ar-istio.svc.cluster.local
subsets:
- labels:
name: app07
rollouts-pod-template-hash: 5bfbf9599
name: version-v1
- labels:
name: app07
rollouts-pod-template-hash: 5bfbf9599
name: version-v2
Co ważne – w classic-trybie-istio (gdzie mamy 2 osobne deploye – jeden ma labels na PODach version: v1 , drugi ma v2 ) to nasza DestinationRule jest oparta o te labele version-v1-v2i
tu w AR zaszła zmiana – skoro AR modyfikuje za naszymi plecami naszą dest-rule (dodając jej też extra labele rollouts-pod-template-hash) to wlaśnie na tej labeli różnicowane są PODy:
$ kk get po --show-labels
NAME READY STATUS RESTARTS AGE LABELS
test-rollout-istio-5bfbf9599-dbcd6 2/2 Running 0 21m name=app07,rollouts-pod-template-hash=5bfbf9599,security.istio.io/tlsMode=istio,service.istio.io/canonical-name=test-rollout-istio-5bfbf9599,service.istio.io/canonical-revision=latest,topology.istio.io/network=a-r-02-default
test-rollout-istio-746b5594b8-pv4wr 2/2 Running 0 11m name=app07,rollouts-pod-template-hash=746b5594b8,security.istio.io/tlsMode=istio,service.istio.io/canonical-name=test-rollout-istio-746b5594b8,service.istio.io/canonical-revision=latest,topology.istio.io/network=a-r-02-default
Jednym słowem proces dla Traffic-Splitting wygląda nastepująco:
Dla wersji z gołym ISTIO:
- administrator powołuje 2 deploymenty + przykrywający je k8s-svc. (każdy Deploy ma inny label version=v1/v2)
- do tego dodaje DestinationRule która definiuje 2 subsety bazujące na tych labelach z version
- do tego na koniec dodaje VirtualService w którym w .route.destination odwołuje się do tych 2 subsetów i ma wstawione w te 2 miejsca wstępne wagi
- admin zaczyna administrować TrafficSplitingiem poprzez edycję tego VS wsadzając wagi 100/0, 90/10 itd
Dla wersji z ArgoRollouts-ISTIO
- administrator zamiast 2xDeploy powołuje ROLLOUT w którym:
- wskazuje na VirtService którym AR będzie kręcił via wstawianie wag (dlatego podaje się tam nazwę route – np „primary”)
- wskazuje na DestRule (podaje dla AR jej nazwę, canarySubsetName version=v2 , stableSubsetName version=v1)
- określa steps dla promocji rolloutu oraz pause{}
- emuluje Deploy (wskazuje image, resources itd)
- admin powołuje DestRule (yaml wsadowy (czyli ten z day0) jest inny niż dla gołego ISTIO, nie ma różnicowania, obydwa subsety muszą byc zrobione na czymś co jest takie same dla nich dwóch – potem AR natychmiast i w trybie ciągłym zmienia mu subsety ktore bazują od teraz również na labelach rollouts-pod-template-hash=RANDOM_Number)
- admin powołuje VirtService (również identyczny jak dla scenariusza z gołym ISTIO) ktorym już za chwilę AR będzie zarządzał – ale jedynie kręcąc w nim wagami
- to nie admin ale tym razem AR zaczyna zarządzać TraficSplitingiem poprzez ustawianie wag w VirtService – 100/0 i 95/5 ORAZ poprzez wstawanie do subsetów w naszej DestinationRule warunków opartych na rollouts-pod-template-hash
Tyle w cz. 2 tematu ISTIO. W kolejnej odsłonie wrócimy do zmian w rolloutach – do tej pory zmienialiśmy jedynie obraz (via kubectl argo rollouts set image test-rollout-istio app07=gimboo/nginx_nonroot3).
Sprawdzimy też jak to działa ale z podmianą CM, a zatem wprowadźmy nowy rollout zawierający odwołanie do CM + nowy obiekt CM
CDN…