Déploiement Canary dans Kubernetes #1 : Gitlab CI

Nous utiliserons Gitlab CI et GitOps manuel pour implémenter et utiliser le déploiement Canary dans Kubernetes

Déploiement Canary dans Kubernetes #1 : Gitlab CI

Articles de cette série :

Nous effectuerons le déploiement de Canary manuellement via GitOps et créerons/modifierons les principales ressources Kubernetes. Cet article est principalement destiné à l'introduction avec le fonctionnement du déploiement dans Kubernetes Canary, car il existe des méthodes d'automatisation plus efficaces, que nous examinerons dans les articles suivants.


Déploiement Canary dans Kubernetes #1 : Gitlab CI

https://www.norberteder.com/canary-deployment/

Déploiement canari

Avec la stratégie Canary, les mises à jour sont d'abord appliquées à un sous-ensemble d'utilisateurs uniquement. Grâce à la surveillance, aux données de journal, aux tests manuels ou à d'autres canaux de commentaires, la version est testée avant d'être publiée à tous les utilisateurs.

Déploiement de Kubernetes (mise à jour continue)

La stratégie par défaut pour le déploiement de Kubernetes est la mise à jour continue, dans laquelle un certain nombre de pods sont lancés avec de nouvelles versions des images. S'ils ont été créés sans problème, les pods contenant d'anciennes versions d'images sont terminés et de nouveaux pods sont créés en parallèle.

GitOps

Nous utilisons GitOps dans cet exemple car nous :

  • utiliser Git comme source unique de vérité
  • nous utilisons Git Operations pour la construction et le déploiement (aucune commande autre que git tag/merge n'est nécessaire)

Exemple

Prenons une bonne pratique : disposer d'un référentiel pour le code d'application et d'un autre pour l'infrastructure.

Référentiel d'applications

Il s'agit d'une API Python+Flask très simple qui renvoie une réponse au format JSON. Nous allons construire le package via GitlabCI et transférer le résultat vers le registre Gitlab. Dans le registre, nous avons deux versions différentes :

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

La seule différence entre eux est la modification du fichier JSON renvoyé. Nous utilisons cette application pour visualiser le plus facilement possible avec quelle version nous communiquons.

Référentiel d'infrastructure

Dans ce navet nous allons déployer via GitlabCI sur Kubernetes, .gitlab-ci.yml est comme suit:

image: traherom/kustomize-docker

before_script:
   - printenv
   - kubectl version

stages:
 - deploy

deploy test:
   stage: deploy
   before_script:
     - echo $KUBECONFIG
   script:
     - kubectl get all
     - kubectl apply -f i/k8s

   only:
     - master

Pour l'exécuter vous-même, vous aurez besoin d'un cluster, vous pouvez utiliser Gcloud :

gcloud container clusters create canary --num-nodes 3 --zone europe-west3-b

gcloud compute firewall-rules create incoming-80 --allow tcp:80

Tu dois bifurquer https://gitlab.com/wuestkamp/k8s-deployment-example-canary-infrastructure et crée une variable KUBECONFIG dans GitlabCI, qui contiendra la configuration d'accès kubectl à votre cluster.

Vous pouvez lire comment obtenir les informations d'identification pour un cluster (Gcloud) ici.

Infrastructure Yaml

Dans le référentiel d'infrastructure, nous avons le service :

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

Et le déploiement dans deploy.yaml:

apiVersion: apps/v1
kind: Deployment
metadata:
 name: app
spec:
 replicas: 10
 selector:
   matchLabels:
     id: app
     type: main
 template:
   metadata:
     labels:
       id: app
       type: main
   spec:
     containers:
     - image: registry.gitlab.com/wuestkamp/k8s-deployment-example-app:v1
       name: app
       resources:
         limits:
           cpu: 100m
           memory: 100Mi

Et un autre déploiement dans deploy-canary.yaml:

kind: Deployment
metadata:
 name: app-canary
spec:
 replicas: 0
 selector:
   matchLabels:
     id: app
     type: canary
 template:
   metadata:
     labels:
       id: app
       type: canary
   spec:
     containers:
     - image: registry.gitlab.com/wuestkamp/k8s-deployment-example-app:v2
       name: app
       resources:
         limits:
           cpu: 100m
           memory: 100Mi

Notez que le déploiement d’applications n’a pas encore de réplicas définis.

Effectuer le déploiement initial

Pour démarrer le déploiement initial, vous pouvez démarrer le pipeline GitlabCI manuellement sur la branche principale. Après cela kubectl devrait afficher ce qui suit :

Déploiement Canary dans Kubernetes #1 : Gitlab CI

Nous voyons app déploiement avec 10 répliques et app-canary avec 0. Il existe également un LoadBalancer auquel nous pouvons accéder via curl via IP externe :

while true; do curl -s 35.198.149.232 | grep label; sleep 0.1; done

Déploiement Canary dans Kubernetes #1 : Gitlab CI

Nous voyons que notre application de test ne renvoie que « v1 ».

Exécution du déploiement Canary

Étape 1 : publier une nouvelle version pour certains utilisateurs

Nous définissons le nombre de réplicas à 1 dans le fichier déployer-canary.yaml et l'image de la nouvelle version :

kind: Deployment
metadata:
 name: app-canary
spec:
 replicas: 1
 selector:
   matchLabels:
     id: app
     type: canary
 template:
   metadata:
     labels:
       id: app
       type: canary
   spec:
     containers:
     - image: registry.gitlab.com/wuestkamp/k8s-deployment-example-app:v2
       name: app
       resources:
         limits:
           cpu: 100m
           memory: 100Mi

En fichier deploy.yaml nous avons changé le nombre de répliques à 9 :

kind: Deployment
metadata:
 name: app
spec:
 replicas: 9
 selector:
   matchLabels:
     id: app
...

Nous poussons ces modifications vers le référentiel à partir duquel le déploiement va démarrer (via GitlabCI) et voyons le résultat :

Déploiement Canary dans Kubernetes #1 : Gitlab CI

Notre service pointera vers les deux déploiements, puisque les deux disposent du sélecteur d'application. En raison de la randomisation par défaut de Kubernetes, nous devrions voir des réponses différentes pour environ 10 % des requêtes :

Déploiement Canary dans Kubernetes #1 : Gitlab CI

L'état actuel de notre application (GitOps, tiré de Git as a Single Source Of Truth) est la présence de deux déploiements avec des réplicas actifs, un pour chaque version.

Environ 10 % des utilisateurs se familiarisent avec une nouvelle version et la testent involontairement. Il est maintenant temps de vérifier les erreurs dans les journaux et les données de surveillance pour détecter les problèmes.

Étape 2 : Publier la nouvelle version pour tous les utilisateurs

Nous avons décidé que tout s'était bien passé et nous devons maintenant déployer la nouvelle version auprès de tous les utilisateurs. Pour ce faire, nous mettons simplement à jour deploy.yaml installation d'une nouvelle version de l'image et le nombre de répliques égal à 10. Dans deploy-canary.yaml nous remettons le nombre de répliques à 0. Après déploiement, le résultat sera le suivant :

Déploiement Canary dans Kubernetes #1 : Gitlab CI

Résumant

Pour moi, exécuter le déploiement manuellement de cette manière permet de comprendre avec quelle facilité il peut être configuré à l'aide de k8. Puisque Kubernetes vous permet de tout mettre à jour via une API, ces étapes peuvent être automatisées via des scripts.

Une autre chose qui doit être implémentée est un point d'entrée de testeur (LoadBalancer ou via Ingress) via lequel seule la nouvelle version est accessible. Il peut être utilisé pour la navigation manuelle.

Dans les prochains articles, nous découvrirons d’autres solutions automatisées qui mettent en œuvre la plupart de ce que nous avons fait.

Lisez également d'autres articles sur notre blog:

Source: habr.com

Ajouter un commentaire