Déploiements canaries automatiques avec Flagger et Istio


Le CD est reconnu comme une pratique de développement de logiciels d'entreprise, il est le résultat d'une évolution naturelle des principes CI établis. Cependant, les CD sont encore assez rares, probablement en raison de la complexité de la gestion et de la peur des déploiements infructueux qui affectent la disponibilité du systÚme.


Flagger est un opérateur Kubernetes open source qui vise à éliminer les relations confuses. Il automatise la promotion des déploiements canaries à l'aide des compensations de trafic Istio et des métriques Prometheus pour analyser le comportement des applications lors du déploiement géré.


Vous trouverez ci-dessous un guide étape par étape sur la façon de configurer et d'utiliser Flagger dans Google Kubernetes Engine (GKE).


Configurer le cluster Kubernetes


Vous commencez par créer un cluster GKE avec un complément Istio (si vous n'avez pas de compte GCP, vous pouvez vous inscrire ici pour recevoir des crédits gratuits).


Connectez-vous à Google Cloud, créez un projet et activez sa facturation. Installez l' utilitaire de ligne de commande gcloud et personnalisez votre projet avec gcloud init .


Définissez le projet, la zone de calcul et la zone par défaut (remplacez PROJECT_ID par votre projet):


 gcloud config set project PROJECT_ID gcloud config set compute/region us-central1 gcloud config set compute/zone us-central1-a 

Activez le service GKE et créez un cluster avec les modules complémentaires HPA et Istio:


 gcloud services enable container.googleapis.com K8S_VERSION=$(gcloud beta container get-server-config --format=json | jq -r '.validMasterVersions[0]') gcloud beta container clusters create istio \ --cluster-version=${K8S_VERSION} \ --zone=us-central1-a \ --num-nodes=2 \ --machine-type=n1-standard-2 \ --disk-size=30 \ --enable-autorepair \ --no-enable-cloud-logging \ --no-enable-cloud-monitoring \ --addons=HorizontalPodAutoscaling,Istio \ --istio-config=auth=MTLS_PERMISSIVE 

La commande ci-dessus crĂ©era un pool de nƓuds par dĂ©faut qui comprend deux machines virtuelles n1-standard-2 (vCPU: 2, RAM 7,5 Go, disque: 30 Go). IdĂ©alement, il vaut la peine d'isoler les composants Istio de leurs charges de travail, mais il n'y a pas de moyen facile d'exĂ©cuter des pods Istio dans un pool de nƓuds dĂ©diĂ©. Les manifestes Istio sont considĂ©rĂ©s comme en lecture seule, et GKE annulera toutes les modifications, telles que la liaison Ă  un nƓud ou la dĂ©connexion d'un foyer.


Configurez les informations d'identification pour kubectl :


 gcloud container clusters get-credentials istio 

Créez la liaison de rÎle d'administrateur de cluster:


 kubectl create clusterrolebinding "cluster-admin-$(whoami)" \ --clusterrole=cluster-admin \ --user="$(gcloud config get-value core/account)" 

Installez l'outil de ligne de commande Helm :


 brew install kubernetes-helm 

Homebrew 2.0 est désormais également disponible pour Linux .


Créez un compte de service et une liaison de rÎle de cluster pour Tiller:


 kubectl -n kube-system create sa tiller && \ kubectl create clusterrolebinding tiller-cluster-rule \ --clusterrole=cluster-admin \ --serviceaccount=kube-system:tiller 

Développez Tiller dans l' kube-system :


 helm init --service-account tiller 

Vous devriez envisager d'utiliser SSL entre Helm et Tiller. Pour plus d'informations sur la sécurisation d'une installation Helm, voir docs.helm.sh


Confirmer les paramĂštres:


 kubectl -n istio-system get svc 

AprĂšs quelques secondes, GCP devrait attribuer une adresse IP externe pour le service istio-ingressgateway .


Configuration de la passerelle d'entrée Istio


Créez une adresse IP statique appelée istio-gateway utilisant l'adresse IP de la passerelle Istio:


 export GATEWAY_IP=$(kubectl -n istio-system get svc/istio-ingressgateway -ojson | jq -r .status.loadBalancer.ingress[0].ip) gcloud compute addresses create istio-gateway --addresses ${GATEWAY_IP} --region us-central1 

Vous avez maintenant besoin d'un domaine Internet et d'un accÚs à votre registraire DNS. Ajoutez deux entrées A (remplacez example.com par votre domaine):


 istio.example.com A ${GATEWAY_IP} *.istio.example.com A ${GATEWAY_IP} 

Vérifiez que le caractÚre générique DNS fonctionne:


 watch host test.istio.example.com 

Créez une passerelle commune Istio pour fournir des services en dehors du maillage de service sur HTTP:


 apiVersion: networking.istio.io/v1alpha3 kind: Gateway metadata: name: public-gateway namespace: istio-system spec: selector: istio: ingressgateway servers: - port: number: 80 name: http protocol: HTTP hosts: - "*" 

Enregistrez la ressource ci-dessus sous public-gateway.yaml, puis appliquez-la:


 kubectl apply -f ./public-gateway.yaml 

Aucun systÚme de production ne devrait fournir de services sur Internet sans SSL. Pour protéger la passerelle Istio avec cert-manager, CloudDNS et Let's Encrypt, veuillez lire la documentation de Flagger GKE.


Installation de Flagger


Le complĂ©ment GKE Istio n'inclut pas l'instance Prometheus, qui nettoie le service de tĂ©lĂ©mĂ©trie Istio. Étant donnĂ© que Flagger utilise les mĂ©triques HTTP Istio pour effectuer une analyse canari, vous devez dĂ©ployer la configuration Prometheus suivante similaire Ă  celle fournie avec le schĂ©ma officiel Istio Helm.


 REPO=https://raw.githubusercontent.com/stefanprodan/flagger/master kubectl apply -f ${REPO}/artifacts/gke/istio-prometheus.yaml 

Ajoutez le référentiel Flagger Helm:


 helm repo add flagger https://flagger.app 

Développez Flagger dans l' istio-system istio istio-system activant les notifications Slack:


 helm upgrade -i flagger flagger/flagger \ --namespace=istio-system \ --set metricsServer=http://prometheus.istio-system:9090 \ --set slack.url=https://hooks.slack.com/services/YOUR-WEBHOOK-ID \ --set slack.channel=general \ --set slack.user=flagger 

Vous pouvez installer Flagger dans n'importe quel espace de noms s'il peut communiquer avec le service Istio Prometheus via le port 9090.


Flagger dispose d'un tableau de bord Grafana pour l'analyse des canaris. Installez Grafana dans l' istio-system :


 helm upgrade -i flagger-grafana flagger/grafana \ --namespace=istio-system \ --set url=http://prometheus.istio-system:9090 \ --set user=admin \ --set password=change-me 

Développez Grafana via une passerelle ouverte en créant un service virtuel (remplacez example.com par votre domaine):


 apiVersion: networking.istio.io/v1alpha3 kind: VirtualService metadata: name: grafana namespace: istio-system spec: hosts: - "grafana.istio.example.com" gateways: - public-gateway.istio-system.svc.cluster.local http: - route: - destination: host: flagger-grafana 

Enregistrez la ressource ci-dessus sous grafana-virtual-service.yaml puis appliquez-la:


 kubectl apply -f ./grafana-virtual-service.yaml 

Lorsque vous accĂ©dez Ă  http://grafana.istio.example.com dans un navigateur, vous devez ĂȘtre redirigĂ© vers la page de connexion Grafana.


Déploiement d'applications Web avec Flagger


Flagger déploie Kubernetes et, si nécessaire, la mise à l'échelle automatique horizontale (HPA), puis crée une série d'objets (déploiements Kubernetes, services ClusterIP et services virtuels Istio). Ces objets ouvrent l'application dans le maillage du service et gÚrent l'analyse et la promotion des canaris.



Créez un espace de noms de test avec l'implémentation d'Istio Sidecar activée:


 REPO=https://raw.githubusercontent.com/stefanprodan/flagger/master kubectl apply -f ${REPO}/artifacts/namespaces/test.yaml 

Créez un outil de mise à l'échelle horizontale automatique de déploiement et de foyer:


 kubectl apply -f ${REPO}/artifacts/canaries/deployment.yaml kubectl apply -f ${REPO}/artifacts/canaries/hpa.yaml 

Déployez un service de test de charge pour générer du trafic lors de l'analyse canari:


 helm upgrade -i flagger-loadtester flagger/loadtester \ --namepace=test 

Créez une ressource canari personnalisée (remplacez example.com par votre domaine):


 apiVersion: flagger.app/v1alpha3 kind: Canary metadata: name: podinfo namespace: test spec: targetRef: apiVersion: apps/v1 kind: Deployment name: podinfo progressDeadlineSeconds: 60 autoscalerRef: apiVersion: autoscaling/v2beta1 kind: HorizontalPodAutoscaler name: podinfo service: port: 9898 gateways: - public-gateway.istio-system.svc.cluster.local hosts: - app.istio.example.com canaryAnalysis: interval: 30s threshold: 10 maxWeight: 50 stepWeight: 5 metrics: - name: istio_requests_total threshold: 99 interval: 30s - name: istio_request_duration_seconds_bucket threshold: 500 interval: 30s webhooks: - name: load-test url: http://flagger-loadtester.test/ timeout: 5s metadata: cmd: "hey -z 1m -q 10 -c 2 http://podinfo.test:9898/" 

Enregistrez la ressource ci-dessus sous podinfo-canary.yaml puis appliquez-la:


 kubectl apply -f ./podinfo-canary.yaml 

En cas de succÚs, l'analyse ci-dessus sera effectuée dans les cinq minutes, avec des métriques HTTP vérifiées toutes les demi-minutes. Vous pouvez déterminer le temps minimum requis pour vérifier et promouvoir un déploiement canari à l'aide de la formule suivante: interval * (maxWeight / stepWeight) . Les champs CRD des Canaries sont documentés ici .


En quelques secondes, Flagger créera des objets canaris:


 # applied deployment.apps/podinfo horizontalpodautoscaler.autoscaling/podinfo canary.flagger.app/podinfo # generated deployment.apps/podinfo-primary horizontalpodautoscaler.autoscaling/podinfo-primary service/podinfo service/podinfo-canary service/podinfo-primary virtualservice.networking.istio.io/podinfo 

Ouvrez un navigateur et accédez à app.istio.example.com , vous devriez voir le numéro de version de l' application de démonstration .


Analyse et promotion automatique des canaris


Flagger implĂ©mente une boucle de contrĂŽle qui dĂ©place progressivement le trafic vers les canaris, tout en mesurant les principaux indicateurs de performance, par exemple, le taux de rĂ©ussite des requĂȘtes HTTP, la durĂ©e moyenne des requĂȘtes et les performances du foyer. Sur la base de l'analyse, le canari KPI progresse ou est interrompu, et les rĂ©sultats de l'analyse sont publiĂ©s dans Slack.



Le déploiement Canary démarre lorsque l'un des objets suivants change:


  • DĂ©ployer PodSpec (image de conteneur, commande, ports, env, etc.)
  • Les ConfigMaps sont montĂ©s en tant que volumes ou convertis en variables d'environnement
  • Les secrets sont montĂ©s en tant que volumes ou convertis en variables d'environnement

Lancement d'un déploiement canari lors de la mise à jour d'une image de conteneur:


 kubectl -n test set image deployment/podinfo \ podinfod=quay.io/stefanprodan/podinfo:1.4.1 

Flagger découvre que la version de déploiement a changé et commence à l'analyser:


 kubectl -n test describe canary/podinfo Events: New revision detected podinfo.test Scaling up podinfo.test Waiting for podinfo.test rollout to finish: 0 of 1 updated replicas are available Advance podinfo.test canary weight 5 Advance podinfo.test canary weight 10 Advance podinfo.test canary weight 15 Advance podinfo.test canary weight 20 Advance podinfo.test canary weight 25 Advance podinfo.test canary weight 30 Advance podinfo.test canary weight 35 Advance podinfo.test canary weight 40 Advance podinfo.test canary weight 45 Advance podinfo.test canary weight 50 Copying podinfo.test template spec to podinfo-primary.test Waiting for podinfo-primary.test rollout to finish: 1 of 2 updated replicas are available Promotion completed! Scaling down podinfo.test 

Pendant l'analyse, les rĂ©sultats des canaris peuvent ĂȘtre suivis Ă  l'aide de Grafana:



Remarque: si de nouvelles modifications sont appliquées au déploiement pendant l'analyse canari, Flagger redémarrera la phase d'analyse.


Faites une liste de tous les "canaris" de votre cluster:


 watch kubectl get canaries --all-namespaces NAMESPACE NAME STATUS WEIGHT LASTTRANSITIONTIME test podinfo Progressing 15 2019-01-16T14:05:07Z prod frontend Succeeded 0 2019-01-15T16:15:07Z prod backend Failed 0 2019-01-14T17:05:07Z 

Si vous avez activé les notifications Slack, vous recevrez les messages suivants:



Restauration automatique


Pendant l'analyse canari, vous pouvez gĂ©nĂ©rer des erreurs HTTP 500 synthĂ©tiques et un dĂ©lai de rĂ©ponse Ă©levĂ© pour vĂ©rifier si Flagger arrĂȘtera le dĂ©ploiement.


Créez un sous-test et procédez comme suit:


 kubectl -n test run tester \ --image=quay.io/stefanprodan/podinfo:1.2.1 \ -- ./podinfo --port=9898 kubectl -n test exec -it tester-xx-xx sh 

Génération d'erreur HTTP 500:


 watch curl http://podinfo-canary:9898/status/500 

Génération de retard:


 watch curl http://podinfo-canary:9898/delay/1 

Lorsque le nombre de vérifications infructueuses atteint la valeur seuil, le trafic est redirigé vers le canal principal, canary est mis à l'échelle à zéro et le déploiement est marqué comme infructueux.


Les erreurs canariennes et les pics de retard sont enregistrés en tant qu'événements Kubernetes et enregistrés par Flagger au format JSON:


 kubectl -n istio-system logs deployment/flagger -f | jq .msg Starting canary deployment for podinfo.test Advance podinfo.test canary weight 5 Advance podinfo.test canary weight 10 Advance podinfo.test canary weight 15 Halt podinfo.test advancement success rate 69.17% < 99% Halt podinfo.test advancement success rate 61.39% < 99% Halt podinfo.test advancement success rate 55.06% < 99% Halt podinfo.test advancement success rate 47.00% < 99% Halt podinfo.test advancement success rate 37.00% < 99% Halt podinfo.test advancement request duration 1.515s > 500ms Halt podinfo.test advancement request duration 1.600s > 500ms Halt podinfo.test advancement request duration 1.915s > 500ms Halt podinfo.test advancement request duration 2.050s > 500ms Halt podinfo.test advancement request duration 2.515s > 500ms Rolling back podinfo.test failed checks threshold reached 10 Canary failed! Scaling down podinfo.test 

Si vous avez activé les notifications Slack, vous recevrez un message lorsque la date limite est atteinte ou lorsque le nombre maximal d'échecs de vérification pendant l'analyse est atteint:



En conclusion


Le lancement d'un maillage de services, comme Istio, en plus de Kubernetes fournira des métriques, des journaux et des protocoles automatiques, mais le déploiement des charges de travail dépend toujours d'outils externes. Flagger cherche à changer cela en ajoutant les capacités de livraison progressive d'Istio.


Flagger est compatible avec n'importe quelle solution Kubernetes CI / CD, et l'analyse des canaris peut ĂȘtre facilement Ă©tendue Ă  l'aide de webhooks pour effectuer des tests d'intĂ©gration / d'acceptation du systĂšme, des tests de stress ou tout autre test utilisateur. Parce que Flagger est dĂ©claratif et rĂ©actif aux Ă©vĂ©nements Kubernetes, il peut ĂȘtre utilisĂ© sur les pipelines GitOps avec Weave Flux ou JenkinsX . Si vous utilisez JenkinsX, vous pouvez installer Flagger avec des modules complĂ©mentaires jx.


Flagger est pris en charge par Weaveworks et fournit des déploiements canaries vers Weave Cloud . Le projet est testé sur GKE, EX et métal nu avec kubeadm.


Si vous avez des suggestions pour améliorer Flagger, veuillez envoyer une question ou un RP à GitHub à stefanprodan / flagger . Les contributions sont plus que bienvenues!


Merci Ray Tsang .

Source: https://habr.com/ru/post/fr444808/


All Articles