Nous allons utiliser Gitlab CI et GitOps manuel pour implémenter et utiliser le déploiement canari dans Kubernetes.

Articles de ce cycle :
- (cet article)
- Déploiement Canari avec Istio
- Déploiement Canari avec Jenkins-X Istio Flagger
Nous effectuerons le déploiement canari manuellement via GitOps et la création/modification des ressources principales de Kubernetes. Cet article est principalement destiné à introduire comment fonctionne le déploiement canari dans Kubernetes, car il existe des méthodes d'automatisation plus efficaces que nous examinerons dans les articles suivants.

Déploiement Canary
Avec la stratégie canari de mise à jour, les mises à jour ne sont d'abord appliquées qu'à une partie des utilisateurs. Grâce à la surveillance, aux données des journaux, aux tests manuels ou à d'autres canaux de retour d'information, la version est testée avant son déploiement pour tous les utilisateurs.
Kubernetes Deployment (mise à jour progressive)
La stratégie par défaut pour Kubernetes Deployment est la mise à jour progressive, où un certain nombre de pods avec de nouvelles versions d'images sont lancés. S'ils se créent sans problème, les pods avec les anciennes versions d'images sont arrêtés et de nouveaux pods sont créés en parallèle.
GitOps
Nous utilisons GitOps dans cet exemple, car nous :
- utilisons Git comme source unique de vérité
- utilisons les opérations Git pour la construction et le déploiement (aucune commande, sauf git tag/merge, n'est nécessaire)
Exemple
Adoptons une bonne pratique : avoir un seul dépôt pour le code des applications et un pour l'infrastructure.
Dépôt pour les applications
C'est une API très simple en Python+Flask, qui renvoie une réponse au format JSON. Nous construirons le paquet via GitlabCI et publierons le résultat dans le registre Gitlab. Dans le registre, nous avons deux versions différentes des releases :
wuestkamp/k8s-deployment-example-app:v1wuestkamp/k8s-deployment-example-app:v2
La seule différence entre elles est le changement du fichier JSON renvoyé. Nous utilisons cette application pour visualiser de manière très simple avec quelle version nous interagissons.
Dépôt d'infrastructure
Dans ce dépôt, nous allons déployer via GitlabCI dans Kubernetes, .gitlab-ci.yml se présente 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 le lancer par 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:80Vous devez faire un fork et créer une variable KUBECONFIG dans GitlabCI, qui contiendra la configuration d'accès kubectl à votre cluster.
Pour savoir comment obtenir les informations d'identification du cluster (Gcloud), vous pouvez consulter .
Yaml d'infrastructure
Dans le dépôt d'infrastructure, nous avons un service :
apiVersion: v1
kind: Service
metadata:
labels:
id: app
name: app
spec:
ports:
- port: 80
protocol: TCP
targetPort: 5000
selector:
id: app
type: LoadBalancerEt 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: 100MiEt 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: 100MiRemarquez que l'app-deploy n'a pas encore de réplicas définis.
Exécution du déploiement initial
Pour lancer le déploiement initial, vous pouvez exécuter le pipeline GitlabCI manuellement dans la branche master. Ensuite, kubectl il doit afficher ce qui suit :

Nous voyons app un déploiement avec 10 réplicas et app-canary avec 0. Il y a aussi un LoadBalancer auquel nous pouvons accéder via curl par l'IP externe :
while true; do curl -s 35.198.149.232 | grep label; sleep 0.1; done

Nous voyons que notre application de test renvoie uniquement “v1”.
Exécution du déploiement Canary
Étape 1 : déployer la nouvelle version pour une partie des utilisateurs
Nous avons défini le nombre de réplicas à 1 dans le fichier deploy-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: 100MiDans le fichier deploy.yaml nous avons changé le nombre de réplicas à 9 :
kind: Deployment
metadata:
name: app
spec:
replicas: 9
selector:
matchLabels:
id: app
...Nous poussons ces modifications dans le dépôt, à partir duquel le déploiement sera lancé (via GitlabCI) et voyons au final :

Notre Service pointera vers les deux déploiements, car les deux ont le sélecteur app. En raison de la distribution aléatoire par défaut dans Kubernetes, nous devons voir des réponses différentes sur environ 10% des requêtes :

L'état actuel de notre application (GitOps, pris de Git comme Single Source Of Truth) est la présence de deux déploiements avec des réplicas actifs, un pour chaque version.
~10% des utilisateurs découvrent la nouvelle version et la testent involontairement. Il est maintenant temps de vérifier s'il y a des erreurs dans les journaux et les données de surveillance pour identifier des problèmes.
Étape 2 : déployer la nouvelle version pour tous les utilisateurs
Nous avons décidé que tout s'était bien passé et maintenant nous devons déployer la nouvelle version pour tous les utilisateurs. Pour cela, nous mettons simplement à jour deploy.yaml en installant la nouvelle version de l'image et le nombre de réplicas, égal à 10. Dans deploy-canary.yaml Nous définissons le nombre de réplicas sur zéro. Après le déploiement, le résultat sera le suivant :

En résumé
Pour moi, lancer le déploiement manuellement de cette manière aide à comprendre à quel point il peut être facilement configuré avec k8s. Étant donné que Kubernetes permet de mettre à jour tout via l'API, ces étapes peuvent être automatisées à l'aide de scripts.
Une autre chose à mettre en œuvre est le point d'entrée du testeur (LoadBalancer ou via Ingress), par lequel on peut accéder uniquement à la nouvelle version. Il peut être utilisé pour une visualisation manuelle.
Dans les prochains articles, nous examinerons d'autres solutions automatisées qui mettent en œuvre la plupart de ce que nous avons fait.
Lisez aussi d'autres articles sur notre blog :
Source : habr.com
