Canary Deployment w Kubernetes #2: Argo Rollouts

Będziemy używać natywnego kontrolera wdrażania Argo Rollouts w k8s oraz GitlabCI do uruchomienia wdrożenia typu Canary w Kubernetes

Canary Deployment w Kubernetes #2: Argo Rollouts

https://unsplash.com/photos/V41PulGL1z0

Artykuły z tej serii

Canary Deployment

Mamy nadzieję, że przeczytałeś pierwszą część, w którym krótko wyjaśnialiśmy, czym są wdrożenia typu Canary. Pokazaliśmy również, jak je zrealizować z użyciem standardowych zasobów Kubernetes.

Argo Rollouts

Argo Rollouts to natywny kontroler wdrażania dla Kubernetes. Oferuje CRD (Custom Resource Definition) dla Kubernetes. Dzięki niemu możemy korzystać z nowej jednostki: Rollout, która zarządza wdrożeniami blue-green i canary z różnymi opcjami konfiguracji.

Kontroler Argo Rollouts, używany przez zasób Rollout, pozwala na użycie dodatkowych strategii wdrażania, takich jak blue-green i canary w Kubernetes. Zasób Rollout oferuje funkcjonalność równoważną Deployment, tylko z dodatkowymi strategiami wdrażania.
Zasób Deployments ma dwie strategie dla wdrożenia: RollingUpdate i Recreate. Pomimo że te strategie są odpowiednie dla większości przypadków, do wdrożeń na serwery w bardzo dużej skali stosuje się dodatkowe strategie, takie jak blue-green lub canary, które nie są dostępne w kontrolerze Deployment. Aby używać tych strategii w Kubernetes, użytkownicy musieli pisać skrypty na swoich Wdrożeniach. Kontroler Argo Rollouts oferuje te strategie jako łatwe do skonfigurowania parametry deklaratywne.
https://argoproj.github.io/argo-rollouts

Istnieje również Argo CI, który zapewnia wygodny interfejs webowy do użycia razem z Rollouts, przyjrzymy się mu w następnym artykule.

Instalacja Argo Rollouts

Po stronie serwera

kubectl create namespace argo-rollouts kubectl apply -n argo-rollouts -f https://raw.githubusercontent.com/argoproj/argo-rollouts/stable/manifests/install.yaml

W naszej repozytorium infrastrukturalnej (patrz poniżej) dodaliśmy już install.yaml jako i/k8s/argo-rollouts/install.yaml. Dzięki temu GitlabCI zainstaluje go w klastrze.

Po stronie klienta (plugin kubectl)

https://argoproj.github.io/argo-rollouts/features/kubectl-plugin

Aplikacja przykład

Dobrą praktyką jest posiadanie oddzielnych repozytoriów dla kodu aplikacji i dla infrastruktury.

Repozytorium dla aplikacji

Kim Wuestkamp/k8s-deployment-example-app

Jest to bardzo proste API w Pythonie + Flask, zwracające odpowiedź w formacie JSON. Zbudujemy pakiet, używając GitlabCI i wypchniemy wynik do Gitlab Registry. W rejestrze mamy dwie różne wersje wydania:

  • wuestkamp/k8s-deployment-example-app:v1
  • wuestkamp/k8s-deployment-example-app:v2

Jedyną różnicą między nimi jest zwracany plik JSON. Używamy tej aplikacji do maksymalnie prostego wizualizowania, z jaką wersją się komunikujemy.

Repozytorium infrastrukturalne

W tym repozytorium będziemy używać GitlabCI do wdrażania w Kubernetes, plik .gitlab-ci.yml wygląda następująco:

image: traherom/kustomize-dockerbefore_script:
   - printenv
   - kubectl versionstages:
 - deploydeploy test:
   stage: deploy
   before_script:
     - echo $KUBECONFIG
   script:
     - kubectl get all
     - kubectl apply -f i/k8s    only:
     - master

Aby go uruchomić samodzielnie, będziesz potrzebować klastra, możesz użyć Gcloud:

gcloud container clusters create canary --num-nodes 3 --zone europe-west3-b
gcloud compute firewall-rules create incoming-80 --allow tcp:80

Musisz zrobić fork https://gitlab.com/wuestkamp/k8s-deployment-example-canary-infrastructure i stworzyć zmienną KUBECONFIG w GitlabCI, która będzie zawierać konfigurację dostępu kubectl do twojego klastra.

Tutaj można przeczytać o tym, jak uzyskać dane uwierzytelniające dla klastra (Gcloud).

Infrastrukturalny Yaml

Wewnątrz repozytorium infrastrukturalnego mamy service:

apiVersion: v1
kind: Service
metadata:
 labels:
   id: rollout-canary
 name: app
spec:
 ports:
 - port: 80
   protocol: TCP
   targetPort: 5000
 selector:
   id: app
 type: LoadBalancer

i rollout.yaml :

apiVersion: argoproj.io/v1alpha1
kind: Rollout
metadata:
 name: rollout-canary
spec:
 replicas: 10
 revisionHistoryLimit: 2
 selector:
   matchLabels:
     id: rollout-canary
 template:
   metadata:
     labels:
       id: rollout-canary
   spec:
     containers:
     - name: rollouts-demo
       image: registry.gitlab.com/wuestkamp/k8s-deployment-example-app:v1
       imagePullPolicy: Always
 strategy:
   canary:
     steps:
     - setWeight: 10
     # Rollouts can be manually resumed by running `kubectl argo rollouts promote ROLLOUT`
     - pause: {}
     - setWeight: 50
     - pause: { duration: 120 } # dwie minuty

Rollout działa tak samo jak Deployment. Jeśli nie zdefiniujemy strategii aktualizacji (jak canary tutaj), będzie zachowywać się jak domyślny rolling-update Deployment.

Określamy dwa kroki w yaml dla wdrożenia canary:

  1. 10% ruchu na canary (czekaj na ręczną zgodę)
  2. 50% ruchu na canary (czekaj 2 minuty, a następnie kontynuuj do 100%)

Wykonywanie wstępnego deployu

Po początkowym wdrożeniu nasze zasoby będą wyglądały tak:

Canary Deployment w Kubernetes #2: Argo Rollouts

I otrzymujemy odpowiedź tylko od pierwszej wersji aplikacji:

Canary Deployment w Kubernetes #2: Argo Rollouts

Wykonujemy wdrożenie canary

Krok 1: 10% ruchu

Aby rozpocząć wdrożenie canary, wystarczy zmienić wersję obrazu, jak zwykle zrobimy to w przypadku wdrożeń:

apiVersion: argoproj.io/v1alpha1
kind: Rollout
metadata:
 name: rollout-canary
spec:
...
 template:
   metadata:
     labels:
       id: rollout-canary
   spec:
     containers:
     - name: rollouts-demo
       image: registry.gitlab.com/wuestkamp/k8s-deployment-example-app:v2
...

I puszczamy zmiany, więc Gitlab CI wykonuje wdrożenie i widzimy zmiany:

Canary Deployment w Kubernetes #2: Argo Rollouts

Teraz, jeśli zwrócimy się do usługi:

Canary Deployment w Kubernetes #2: Argo Rollouts

Świetnie! Jesteśmy w trakcie naszego wdrożenia canary. Możemy zobaczyć postęp, uruchamiając:

kubectl argo rollouts get rollout rollout-canary

Canary Deployment w Kubernetes #2: Argo Rollouts

Krok 2: 50% ruchu:

Teraz przechodzimy do następnego kroku: przekierowanie 50% ruchu. Ustawiliśmy, aby ten krok był uruchamiany ręcznie:

kubectl argo rollouts promote rollout-canary # kontynuuj do kroku 2

Canary Deployment w Kubernetes #2: Argo Rollouts

I nasza aplikacja zwróciła 50% odpowiedzi od nowych wersji:

Canary Deployment w Kubernetes #2: Argo Rollouts

I przegląd rollout:

Canary Deployment w Kubernetes #2: Argo Rollouts

Świetnie.

Krok 3: 100% ruchu:

Ustawiliśmy, aby po 2 minutach krok z 50% kończył się automatycznie i uruchamiał krok ze 100%:

Canary Deployment w Kubernetes #2: Argo Rollouts

I wynik aplikacji:

Canary Deployment w Kubernetes #2: Argo Rollouts

I przegląd rollout:

Canary Deployment w Kubernetes #2: Argo Rollouts

Wdrożenie canary zakończone.

Jeszcze przykłady z Argo Rollouts

Oto kolejne przykłady, na przykład jak skonfigurować podgląd środowiska i porównania oparte na canary:

https://github.com/argoproj/argo-rollouts/tree/master/examples

Wideo o Argo Rollouts i Argo CI

Naprawdę polecam to wideo, pokazuje, jak Argo Rollouts i Argo CI współdziałają:

Odtwarzaj wideo

Podsumowanie

Bardzo podoba mi się pomysł używania CRD, które zarządzają tworzeniem dodatkowych typów deployments lub replicasets, kierowaniem ruchu itd. Praca z nimi przebiega gładko. Następnie chciałbym przetestować integrację z Argo CI.

Jednak wydaje się, że nadchodzi duże połączenie Argo CI i Flux CI, więc mogę poczekać na nową wersję: Argo Flux.

Czy mieli Państwo doświadczenie z Argo Rollouts lub Argo CI?

Przeczytaj również inne artykuły na naszym blogu:

Źródło: habr.com

Kup solidny hosting stron z ochroną przed DDoS, serwery VPS VDS 🔥 Kup solidny hosting stron z ochroną przed DDoS, serwery VPS VDS | ProHoster