
La CD (Continuous Delivery) est reconnue comme une pratique de logiciels d'entreprise, résultat de l'évolution naturelle des principes établis du CI (Continuous Integration). Cependant, la CD reste un phénomÚne assez rare, probablement en raison de la complexité de la gestion et de la peur des déploiements échoués qui affectent la disponibilité du systÚme.
est un opérateur Kubernetes open source dont l'objectif est d'éliminer les interrelations complexes. Il automatise la promotion des déploiements canary utilisant le décalage de trafic d'Istio et les métriques de Prometheus pour analyser le comportement de l'application pendant le déploiement contrÎlé.
Voici un guide étape par étape pour configurer et utiliser Flagger sur Google Kubernetes Engine (GKE).
Configuration du cluster Kubernetes
Vous commencez par crĂ©er un cluster GKE avec lâextension Istio (si vous n'avez pas de compte GCP, vous pouvez vous inscrire pour obtenir des crĂ©dits gratuits).
Connectez-vous à Google Cloud, créez un projet et activez la facturation pour celui-ci. Installez l'outil de ligne de commande et configurez votre projet avec gcloud init.
Définissez le projet par défaut, la région de calcul et la zone (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-aActivez le service GKE et créez un cluster avec HPA et les extensions 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_PERMISSIVELa commande ci-dessus crĂ©era un pool de nĆuds par dĂ©faut incluant deux VM n1-standard-2 (vCPU : 2, RAM 7,5 Go, disque : 30 Go). IdĂ©alement, il serait prĂ©fĂ©rable d'isoler les composants Istio de vos charges de travail, mais il n'existe pas de moyen simple pour 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 toute modification, comme l'attribution Ă un nĆud ou le dĂ©tachement d'un pod.
Configurez les identifiants pour kubectl:
gcloud container clusters get-credentials istioCréez une liaison de rÎle de super 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 :
brew install kubernetes-helmHomebrew 2.0 est maintenant également disponible pour .
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:tillerDéployez Tiller dans le namespace kube-system:
helm init --service-account tillerVous devriez envisager dâutiliser SSL entre Helm et Tiller. Pour plus dâinformations sur la sĂ©curisation de lâinstallation de Helm, voir
Confirmez les paramĂštres :
kubectl -n istio-system get svcDans quelques secondes, GCP doit attribuer une adresse IP externe au service istio-ingressgateway.
Configuration de la passerelle d'entrée Istio
Créez une adresse IP statique nommée istio-gateway, en 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-central1Vous avez maintenant besoin d'un domaine Internet et d'un accĂšs Ă votre registraire DNS. Ajoutez deux enregistrements A (remplacez example.com par votre domaine) :
istio.example.com A ${GATEWAY_IP}
*.istio.example.com A ${GATEWAY_IP}Assurez-vous que le caractÚre générique DNS fonctionne :
watch host test.istio.example.comCréez une passerelle Istio publique pour fournir des services en dehors du service mesh via 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.yamlAucun systĂšme de production ne doit fournir des services en ligne sans SSL. Pour sĂ©curiser la passerelle d'entrĂ©e Istio Ă l'aide de cert-manager, CloudDNS et Letâs Encrypt, veuillez lire Flagger GKE.
Installation de Flagger
Le dĂ©ploiement GKE Istio ne comprend pas d'instance Prometheus, qui gĂšre le nettoyage du service de tĂ©lĂ©mĂ©trie Istio. Ătant donnĂ© que Flagger utilise les mĂ©triques Istio HTTP pour rĂ©aliser des analyses canary, vous devez dĂ©ployer la configuration Prometheus suivante, similaire Ă celle fournie avec le schĂ©ma Istio Helm officiel.
REPO=https://raw.githubusercontent.com/stefanprodan/flagger/master
kubectl apply -f ${REPO}/artifacts/gke/istio-prometheus.yamlAjoutez le dépÎt Flagger Helm :
helm repo add flagger [https://flagger.app](https://flagger.app/)Déployez Flagger dans le namespace istio-system, en 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=flaggerVous pouvez installer Flagger dans n'importe quel namespace s'il peut interagir avec le service Istio Prometheus via le port 9090.
Flagger dispose dâun tableau de bord Grafana pour lâanalyse canary. Installez Grafana dans le namespace 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-meExpose Grafana via an open gateway by creating a virtual service (replace example.com with your domain):
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-grafanaSave the above resource as grafana-virtual-service.yaml, then apply it:
kubectl apply -f ./grafana-virtual-service.yamlWhen navigating to http://grafana.istio.example.com in your browser, you should be directed to the Grafana login page.
Deploying Web Applications with Flagger
Flagger deploys Kubernetes and, if needed, horizontal pod autoscaling (HPA), then creates a series of objects (Kubernetes deployments, ClusterIP services, and Istio virtual services). These objects expose the application in the service mesh and manage canary analysis and promotion.
Create a test namespace with Istio Sidecar injection enabled:
REPO=https://raw.githubusercontent.com/stefanprodan/flagger/master
kubectl apply -f ${REPO}/artifacts/namespaces/test.yamlCreate a deployment and pod autoscaler:
kubectl apply -f ${REPO}/artifacts/canaries/deployment.yaml
kubectl apply -f ${REPO}/artifacts/canaries/hpa.yamlDeploy a test load service to generate traffic during the canary analysis:
helm upgrade -i flagger-loadtester flagger/loadtester
--namepace=testCreate a custom canary resource (replace 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/"Save the above resource as podinfo-canary.yaml, then apply it:
kubectl apply -f ./podinfo-canary.yamlThe analysis mentioned above, if successful, will run for five minutes with HTTP metrics checked every half a minute. You can calculate the minimum time required for checking and promoting the canary deployment using the following formula: interval * (maxWeight / stepWeight). The fields of the Canary CRD are documented .
In a few moments, Flagger will create canary objects:
# 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/podinfoOuvrez votre navigateur et accédez à app.istio.example.com, vous devez voir le numéro de version .
Analyse et promotion canary automatiques
Flagger met en Ćuvre un cycle de gestion qui dĂ©place progressivement le trafic vers le canary tout en mesurant les indicateurs clĂ©s de performance, tels que le taux de succĂšs des requĂȘtes HTTP, la durĂ©e moyenne des requĂȘtes et la disponibilitĂ© du pod. Sur la base de l'analyse des KPI, le canary est soit promu, soit interrompu, et les rĂ©sultats de l'analyse sont publiĂ©s sur Slack.
Le déploiement canary est lancé lors de la modification de l'un des objets suivants :
- Déploiement PodSpec (image de conteneur, commande, ports, environnements, 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 canary lors de la mise à jour de l'image du conteneur :
kubectl -n test set image deployment/podinfo
podinfod=quay.io/stefanprodan/podinfo:1.4.1Flagger détecte que la version du déploiement a changé et commence à l'analyser :
kubectl -n test describe canary/podinfo
ĂvĂ©nements :
Nouvelle révision détectée podinfo.test
Mise à l'échelle de podinfo.test
En attente de la fin du déploiement de podinfo.test : 0 des 1 répliques mises à jour sont disponibles
Avancer le poids canary de podinfo.test 5
Avancer le poids canary de podinfo.test 10
Avancer le poids canary de podinfo.test 15
Avancer le poids canary de podinfo.test 20
Avancer le poids canary de podinfo.test 25
Avancer le poids canary de podinfo.test 30
Avancer le poids canary de podinfo.test 35
Avancer le poids canary de podinfo.test 40
Avancer le poids canary de podinfo.test 45
Avancer le poids canary de podinfo.test 50
Copie de la spécification du modÚle de podinfo.test vers podinfo-primary.test
En attente de la fin du déploiement de podinfo-primary.test : 1 des 2 répliques mises à jour sont disponibles
Promotion terminĂ©e ! Mise Ă l'Ă©chelle vers le bas de podinfo.testLors de l'analyse, les rĂ©sultats du canary peuvent ĂȘtre suivis Ă l'aide de Grafana :
Notez que si de nouveaux changements sont appliqués au déploiement pendant l'analyse canary, Flagger redémarrera la phase d'analyse.
Dressez la liste de tous les « canaris » dans 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:07ZSi vous avez activé les notifications Slack, vous recevrez les messages suivants :
Rétrogradation automatique
Lors de l'analyse canary, il est possible de générer des erreurs HTTP 500 synthétiques et une forte latence de réponse pour vérifier si Flagger interrompt le déploiement.
Créez un pod de test et effectuez l'action suivante :
kubectl -n test run tester
--image=quay.io/stefanprodan/podinfo:1.2.1
-- ./podinfo --port=9898
kubectl -n test exec -it tester-xx-xx shGénération d'erreurs HTTP 500 :
watch curl http://podinfo-canary:9898/status/500Génération de latence :
regarder curl http://podinfo-canary:9898/delay/1Lorsque le nombre d'échecs de vérification atteint le seuil, le trafic est renvoyé vers le canal principal, le canary est redimensionné à zéro et le déploiement est marqué comme échoué.
Les erreurs de canary et les pics de latence sont enregistrés en tant qu'événements Kubernetes et consignés par Flagger au format JSON :
kubectl -n istio-system logs deployment/flagger -f | jq .msg
Démarrage du déploiement canary pour podinfo.test
Avancer le poids canary podinfo.test 5
Avancer le poids canary podinfo.test 10
Avancer le poids canary podinfo.test 15
ArrĂȘter l'avancement de podinfo.test taux de rĂ©ussite 69.17% < 99%
ArrĂȘter l'avancement de podinfo.test taux de rĂ©ussite 61.39% < 99%
ArrĂȘter l'avancement de podinfo.test taux de rĂ©ussite 55.06% < 99%
ArrĂȘter l'avancement de podinfo.test taux de rĂ©ussite 47.00% < 99%
ArrĂȘter l'avancement de podinfo.test taux de rĂ©ussite 37.00% 500ms
ArrĂȘter l'avancement de podinfo.test durĂ©e de la requĂȘte 1.600s > 500ms
ArrĂȘter l'avancement de podinfo.test durĂ©e de la requĂȘte 1.915s > 500ms
ArrĂȘter l'avancement de podinfo.test durĂ©e de la requĂȘte 2.050s > 500ms
ArrĂȘter l'avancement de podinfo.test durĂ©e de la requĂȘte 2.515s > 500ms
Rollback podinfo.test seuil d'échecs atteint 10
Canary échoué ! Redimensionnement de podinfo.testSi vous avez activé les notifications Slack, vous recevrez un message lorsque le délai d'exécution sera dépassé ou lorsque le nombre maximal d'échecs de vérification sera atteint pendant l'analyse :
En conclusion
Lancement de service mesh, par exemple, 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 vise à changer cela en ajoutant des capacités Istio .
Flagger est compatible avec toutes les solutions CI/CD pour Kubernetes, et l'analyse canary peut ĂȘtre facilement Ă©tendue Ă l'aide de pour exĂ©cuter des tests d'intĂ©gration/systĂšme, des tests de charge ou toute autre vĂ©rification personnalisĂ©e. Ătant donnĂ© que Flagger est dĂ©claratif et rĂ©agit aux Ă©vĂ©nements Kubernetes, il peut ĂȘtre utilisĂ© dans des pipelines GitOps avec ou . Si vous utilisez JenkinsX, vous pouvez installer Flagger avec des plugins jx.
Flagger est pris en charge par et permet des déploiements canary sur . Le projet est testé sur GKE, EKS et sur matériel nu avec kubeadm.
Si vous avez des suggestions pour améliorer Flagger, veuillez poser une question ou soumettre un PR sur GitHub à l'adresse . Les contributions sont plus que bienvenues !
Merci .
Source : habr.com
