Continuous deployment
Vous avez probablement remarqué que nous avons automatisé la création d'une image Docker, et qu'elle réside maintenant dans notre registre de conteneurs sur Gitlab.
Maintenant, ce que nous voulons faire, c'est exécuter la bonne commande kubectl pour télécharger cette image dans notre cluster Kubernetes.
Est-ce qu'on peut automatiser ce processus dans notre .gitlab-ci.yml ? Oui !
Publier un image de prod
Nous allons ajouter une étape à notre pipeline: publish pour élever notre image déjà créée et testée (avec nos tests e2e) au statut de production, en créant un tag.
D'abord, nous allons protéger nos tags dans Gitlab, en précisant que seulement des tags d'un certain format puissent être déployé en production.
Naviguez dans Settings → Repository → Protected Tags. Tapez *.*.* dans la barre de recherche, puis cliquer sur "Create wildcard tag". Sélectionner le role Maintainers (seulement les utilisateurs privilégiés auront le droit à déployer); puis cliquer sur "Protect".
Retournez à votre .gitlab-ci.yaml, et ajoutez une phase publish :
stages:
- test
- build
- e2e-test
- publishOn ajoute une tâches de plus, qui sera prise en compte seulement si on crée un nouveau tag sur notre branch main. La première tâche va re-tagger notre image Docker avec la version précisé dans le nom de notre tag.
publish-job:
stage: publish
tags:
- general
rules:
# Only if we create a tag
- if: $CI_COMMIT_TAG
image: docker:20.10.16
services:
- name: docker:20.10.16-dind
alias: docker
variables:
IMAGE_TAG: $CI_REGISTRY_IMAGE/api-$CI_COMMIT_REF_NAME:$CI_COMMIT_SHORT_SHA
LATEST_TAG: $CI_REGISTRY_IMAGE/api-prod:$CI_COMMIT_TAG
script:
- docker login -u $CI_REGISTRY_USER -p $CI_REGISTRY_PASSWORD $CI_REGISTRY
# Créer l'image docker
- docker build --pull -t $IMAGE_TAG -f ./config/docker/Dockerfile.prod .
# Retagger l'image avec le tag fourni
- echo "Retagging docker image..."
- docker tag $IMAGE_TAG $LATEST_TAG # Elever notre image au tag "latest"
- echo "Push image with latest tag..."
- docker push $LATEST_TAG # Envoyer l'image à notre Container Repository
- echo "Done."Ajoutez cette tâche à votre pipeline, et ensuite créez un tag sur votre code dans Code → Tags. Normalement le tag représente la version, par exemple 1.0.1 :

Retournez dans Build → Pipelines, vous verrez le dernier pipeline aura recommencé avec une nouvelle tâche pour publier l'image avec le nom de notre tag. Une fois fini, naviguez dans Deploy → Container Registry. Vous verrez une nouveau dépôt api-prod qui contiendra toutes nos images de production.
Configurer l'accès k8s au Gitlab
Auparavant, nous avons déployé notre api manuellement via Docker Hub, en utilisant un dépôt public.
Cependant, Kubernetes doit maintenant accéder à notre registre de conteneurs privé GitLab pour récupérer les images nouvellement construites.
Nous devons configurer un accès pour k8s.
Commencez par créer un jeton d'accès que k8s pourra utiliser pour extraire des images de notre registre de conteneurs. Naviguez dans Settings → Access Tokens →, et créez un jeton d'accès uniquement pour k8s :
Pas de date d'expiration
Role :
DeveloperScope :
read_registry

Copiez le jeton d'accès.
Retournez à votre Dev Container. Nous allons modifier notre configuration k8s pour pouvoir s'identifier auprès de notre GitLab :
Créons un secret sur le cluster qui permet de nous identifier sur GitLab :
Supprimer un secret
Si jamais vous vous êtes trompé de secret, il faut le supprimer et créer de nouveau :
Ensuite, nous allons modifier notre fichier deployment.k8s.yaml (la modification sur le 2 dernières lignes) :
Appliquer ce fichier en emettant :
Tout est prêt ! K8s sait désormais récupérer des images de notre GitLab.
Déployer sur k8s
Nous allons ajouter une étape à notre pipeline: deploy pour déployer notre image dans le cluster.
La tâche correspondante va connecter à notre cluster, et mettre à jour l'image utilisé par notre déploiement :
Prenez note de la phrase when: manual - j'ai choisi de faire la tâche manuellement, pour être sur de ne pas se tromper !!
Pour connecter à notre cluster, il faudrait s'identifier avec notre fichier kubeconfig. Il faudrait le fournir à GitLab en tant que secret avec le nom KUBECONFIG_PROD.
Naviguez dans **Settings → CI/CD → Variables **:

On ajoute notre variable KUBECONFIG_PROD :

Le type de variable est File, on le nomme KUBECONFIG_PROD, et on colle les contenus de kubeconfig.yaml que je vous ai passé.
Et, c'est tout bon, tout devrait être configuré.
Pour valider si tout fonctionne :
Attendez que les tests sont terminés sans problème
Créez un nouveau tag, et attendez que le build soit fait
Manuellement déclencher le déploiement en retournant dans la pipeline, entrant dans la tâche "deploy", et en lançant le job.
Comment savoir si notre image a été déployée ? Retournez à votre DevContainer, et tapez dans le terminal :
Parmis les détails, vous devez voir l'image qui portera désormais la version que vous avez précisé dans le tag sur Gitlab !
Vérifiez que votre API fonctionne toujours :
Testons notre pipeline CI/CD
Nous allons modifier notre endpoint /info pour retourner une information supplémentaire. Dans src/controllers/InfoController.ts
Utilisez votre compte git pour faire un commit et push, créez un tag, et déployer l'image sur le cluster.
Une fois que le pipeline se termine, testons notre API:
CI/CD Rocks !
Debogger
N'oubliez pas d'utiliser les outils kubectl pour déboguer votre deploiement.
Par exemple, vous ne voyez pas votre modification dans le résultat ?
Vérifiez que la bonne image est précisé avec
kubectl get deploymentsVérifiez que les pods tournent correctement avec
kubectl get pods. Si vous voyez un état d'erreur, typeImage Pull ErrorouImage Pull Backoffil se trouve que k8s n'arrive pas à récupérer l'image de Gitlab. Vérifier bien d'avoir fourni les bons codes d'accès dans le chapitre précédente !
Le .gitlab-ci.yml
.gitlab-ci.ymlVoici le fichier complet :
Mis à jour