IINF170 - Déploiement Continu/CD - 19/01/2024

Activités du jour

  • Révisions et questions/réponses sur la session précédente

  • Reprise du dépôt de la dernière fois ou travail sur un nouveau dépôt (qui vous sera fourni)

  • Utilisation d’Azure pour :

    • Héberger des images Docker (au lieu de Docker Hub utilisé la dernière fois)
    • Créer un cluster Kubernetes sur AKS (Azure Kubernetes Services)
    • Déployer l’application sur le cluster

Point de départ : pipeline GitLab CI

La dernière fois, nous avions créé un pipeline CI/CD pour GitLab, sous la forme d’un fichier YAML, .gitlab-ci.yml.

Ci-dessous se trouve son contenu commenté. Quelques ajouts mineurs ont été faits, comme le fait de lister toutes les étapes en haut du fichier avec stages, puis d’y faire référence par la suite avec name.

Si vous n’avez pas du tout la même chose, ce n’est pas grave : vous pourrez repartir d’un dépôt qui vous sera fourni.

# Image de base qui sera utilisée dans chaque "stage"
# sauf indication contraire
image: node:alpine

stages:
  - install
  - lint
  - build
  - build_push_image

cache:
  paths:
    - node_modules/
    - dist/

# Installation des dépendances
# référencées dans package.json
install:
  stage: install
  script:
    - yarn #  --> produit un dossier node_modules/

# "Linting" (vérification de règles : absence d'erreurs...)
# Le script "lint" invoque ESLint
lint:
  stage: lint
  needs:
    - install
  script:
    - yarn lint

# Compilation des sources TypeScript
# Le script "build" invoque tsc (TS Compiler)
build:
  stage: build
  needs:
    - lint
  script:
    - yarn build #  --> produit un dossier dist/

# Construction de l'image Docker, en récupérant
# le résultat de l'étape précédente
build_push_image:
  stage: build_push_image
  only:
    - main
  needs:
    - build
  image: docker:latest
  services:
    - docker:dind
  script:
    - docker build -t $DOCKER_HUB_USERNAME/ipi-ci-cd-example .
    # vers Docker Hub
    - docker login -u $DOCKER_HUB_USERNAME -p $DOCKER_HUB_TOKEN
    - docker push $DOCKER_HUB_USERNAME/ipi-ci-cd-example

** ❗ AVANT DE DÉMARRER ❗**

  • SI votre pipeline ressemble à celui ci-dessus, ET que vous avez pu build les images Docker et les pousser vers le Docker Hub, vous pouvez rester sur votre dépôt.
  • SINON, veuillez forker ce dépôt, qui est la continuation de celui que vous aviez forké la dernière fois : https://gitlab.com/bhubert/ipi-cicd-aks-deployment

Plan

Ci-dessous est indiquée la “feuille de route” à suivre, en vue de déployer l’application sur Azure Kubernetes Services.

Cela inclut la préparation du compte Azure et de différents services, en vue du déploiement.

Beaucoup de ces étapes sont préparatoires : on ne les effectuera qu’une fois. Une fois passées, nous pourrons automatiser d’autres opérations dans GitLab CI.

  • Installer Azure CLI
  • Se connecter à Azure avec Azure CLI
  • Créer un groupe de ressources : lié à une certaine localisation géographique (datacenter de Microsoft), il permet de regrouper différentes ressources telles que : registres de conteneurs, clusters Kubernetes, etc.
  • Créer un “principal de service” (Service Principal) pour nous permettre de nous authentifier sur Azure
  • Créer un registre d’images Docker sur le service Azure Container Registry, pour héberger les images que nous déploierons ensuite sur AKS
  • Modifier le pipeline .gitlab-ci.yml pour tester le build et push d’une image vers le registre ACR.
  • Créer un cluster AKS
  • Déployer l’application sur le cluster manuellement, une première fois
  • Modifier le pipeline de façon à mettre à jour le déploiement sur le cluster

Certains aspects vous sembleront peu compréhensibles, mais il s’agit avant tout de suivre les étapes le plus fidèlement possible. Ce n’est pas un cours sur Azure 😊.

Installer Azure CLI et s’authentifier

Commencez par vous authentifier sur le portail Azure : sur la page suivante, cliquez sur Connexion : https://azure.microsoft.com/fr-fr/get-started/azure-portal

Puis téléchargez et installez Azure CLI : page de téléchargement

Une fois l’installation terminée, il nous faut nous authentifier sur Azure via Azure CLI.

Cette page détaille différents mécanismes de connexion à Azure.

Nous en utiliserons deux au cours de notre travail :

  • La connexion interactive en utilisant az login
  • La connexion non-interactive via un principal de service, pour l’utilisation dans la CI GitLab

Ouvrez un shell et lancez : az login.

Une fenêtre de navigateur s’ouvrira. Vous devrez vous connecter à votre compte Microsoft.

Il est possible que vous rencontriez une erreur, si votre compte Microsoft est lié à plusieurs organisations (a priori, il ne doit être lié qu’à l’IPI…).

Voici le type d’erreur qu’on peut rencontrer :

$ az login
A web browser has been opened at https://login.microsoftonline.com/organizations/oauth2/v2.0/authorize. Please continue the login in the web browser. If no web browser is available or if the web browser fails to open, use device code flow with `az login --use-device-code`.
The following tenants don't contain accessible subscriptions. Use 'az login --allow-no-subscriptions' to have tenant level access.
f1a17525-bacf-4c23-a3a1-44d0a0a38449 'World Company Inc.'
The following tenants require Multi-Factor Authentication (MFA). Use 'az login --tenant TENANT_ID' to explicitly login to a tenant.
c08cd9ac-5400-4aa2-b32e-1eabbd073423 'Default Directory'
2f45a4b2-60ee-4b0b-bd0a-ee8c2215ed77 'Big Corp Inc.'
No subscriptions found for yourfullname@gmail.com.

Prévenez-moi si vous rencontrez ce problème, ou lisez les indications du terminal.

Si tout va bien, vous devriez obtenir ce type de message dans le terminal :

[
  {
    "cloudName": "AzureCloud",
    "homeTenantId": "c08cd9ac-5400-4aa2-b32e-1eabbd073423",
    "id": "22dfff83-e6fa-4d4b-a6c3-02ac1c4830a8",
    "isDefault": true,
    "managedByTenants": [],
    "name": "Azure subscription 1",
    "state": "Enabled",
    "tenantId": "c08cd9ac-5400-4aa2-b32e-1eabbd073423",
    "user": {
      "name": "yourfullname@gmail.com",
      "type": "user"
    }
  }
]

Création d’un groupe de ressources.

Références documentaires : Gérer les groupes de ressources Azure à l’aide d’Azure CLI et Définir votre convention de nommage.

Le groupe de ressources nous permettra de créer ensuite :

  • un registre d’images Docker
  • un cluster AKS (Kubernetes)

La commande permettant de créer un groupe de ressources est az group create.

Dans le doute, quand vous ne connaissez pas la façon d’utiliser une commande, ajoutez --help derrière.

Par exemple :

  • az --help vous donne la liste de “sections” d’Azure que vous pouvez contrôler via la CLI.
  • az group --help vous donne la liste des commandes dans la section group.
  • az group create --help vous indique précisément comment utiliser az group create, notamment quels arguments sont acceptés, voire obligatoires.

Deux arguments sont requis pour az group create :

  • --location ou -l suivi d’une localisation géographique. Vous utiliserez francecentral (On peut obtenir la liste des localisations possibles avec az account list-locations).
  • --name ou --resource-group ou -n ou -g suivi d’un nom unique. N’utilisez surtout pas un nom générique comme peuvent le proposer des tutoriels. Utilisez un nom basé par exemple sur vos prénom/nom/organisation.

Exemple pour Gérard Lambert, élève fictif :

az group create -l francecentral -n rg-ipi-cicd-glambert

❗ IMPORTANT ❗ Notez le nom du groupe de ressources que vous avez créé dans un endroit facile à retrouver, vous vous en servirez souvent.

Voici ce que renvoie cette commande si tout se passe bien.

{
  "id": "/subscriptions/22dfff83-e6fa-4d4b-a6c3-02ac1c4830a8/resourceGroups/rg-ipi-cicd-glambert",
  "location": "francecentral",
  "managedBy": null,
  "name": "rg-ipi-cicd-glambert",
  "properties": {
    "provisioningState": "Succeeded"
  },
  "tags": null,
  "type": "Microsoft.Resources/resourceGroups"
}

Création d’un principal de service

Références documentaires : tutoriel Créer un principal du service Azure avec Azure CLI, liste des rôles

Le Principal de Service (Service Principal ou SP) nous permettra d’effectuer des opérations depuis GitLab CI, sans avoir à entrer les identifiants de notre compte Azure.

On va l’autoriser à effectuer certaines opérations en notre nom. On peut lui attribuer un “rôle” pour limiter ce qu’il est capable de faire.

La commande à utiliser pour créer un groupe de ressources : az ad sp create-for-rbac (--help pour l’aide)

Le “rbac” dans le dernier argument (Role-Based Access Control) est un mécanisme de contrôle d’accès qui définit les rôles et les autorisations de chaque utilisateur.

Ses éventuels arguments sont optionnels, mais il est intéressant de s’attarder sur la signification de ceux-ci, qui fonctionnent de concert → l’un ne va pas sans l’autre :

  • --role : rôle à attribuer au SP. Ces rôles sont pré-définis. Pour faire simple, nous allons utiliser le rôle Contributor, qui donne beaucoup de droits.
  • --scopes : les “périmètres” auxquels s’applique le SP. Ici, on va devoir associer le SP à notre abonnement (subscription) Azure. On peut utiliser --scope si on n’utilise qu’un seul scope.

Ne saisissez pas (encore) ce qui suit ! Notre commande va ressembler à ceci :

az ad sp create-for-rbac --role Contributor --scope "SCOPE"

<SCOPE> devra être remplacée par une chaîne ressemblant à ceci : /subscriptions/9d4d31c7-1010-45b0-bf57-4661527ebe279d4d31c7-1010-45b0-bf57-4661527ebe27 est le numéro de votre abonnement Azure.

Pour obtenir votre numéro d’abonnement, lancez :

az account show

Vous obtiendrez un résultat similaire à ceci :

{
  "environmentName": "AzureCloud",
  "homeTenantId": "1b482281-e94e-4617-ac3f-e628f4d7f3eb",
  "id": "9d4d31c7-1010-45b0-bf57-4661527ebe27",
  "isDefault": true,
  "managedByTenants": [],
  "name": "Azure subscription 1",
  "state": "Enabled",
  "tenantId": "c08cd9ac-5400-4aa2-b32e-1eabbd073423",
  "user": {
    "name": "yourfullname@gmail.com",
    "type": "user"
  }
}

Ce qui vous intéresse ici est la valeur de id, ici 9d4d31c7-1010-45b0-bf57-4661527ebe27.

La commande complète ressemblera à celle-ci, moyennement remplacement de l’id ci-dessous par le vôtre.

az ad sp create-for-rbac --role Contributor --scope "/subscriptions/9d4d31c7-1010-45b0-bf57-4661527ebe27"

❗ IMPORTANT ❗ Notez bien le résultat de cette commande. Copiez le en lieu sûr, il contient des identifiants qui vous serviront bientôt !

Vous obtiendrez un résultat similaire à ceci :

{
  "appId": "cf39fdbd-d70a-49e4-88b6-edad5ca4dc16",
  "displayName": "azure-cli-2024-01-17-18-44-23",
  "password": "ZO8jw~vFW4Vm3gdjwW2cU3d5bK_BgJVfoIThmGZm",
  "tenant": "7e301642-6fa4-4989-a914-8d6cd6df1146"
}

Seul displayName nous sera inutile ici. Les trois autres, appId, password et tenant nous serviront dans la CI GitLab.

On peut même s’en servir dès maintenant pour la prochaine étape !

Création d’un registre d’images avec ACR

Azure Container Registry permet d’héberger des images Docker → et autres, car Docker utilise un standard de format d’images (OCI), supporté par Azure.

C’est un service comparable au Docker Hub. Nous allons, pour la suite, pousser les images vers notre propre ACR, au lieu d’utiliser Docker Hub.

On va créer un registre (un ACR, donc) avec 9fca686c-9e6d-433f-93b9-a3386fc0defc. Les 3 arguments requis par cette commande sont :

  • -n : le nom de notre registre.
  • -g : le nom de votre groupe de ressources (créé précédemment)
  • -sku : une valeur parmi trois possibles (avec plus ou moins de fonctionnalités, déterminant une tarification)

Il faut trouver un nom pour votre registre. Par exemple, acripiglambert (minuscules uniquement, sans caractères spéciaux !). Ce nom doit être distinctif et unique

Tester le SP précédemment créé ?

Si Docker ne fonctionne pas (bien) sur votre machine locale, oubliez cette section, et passez directement à la sous-section suivante, “Lancer la commande de création de l’ACR”.

Avant de lancer la commande de création de l’ACR, un petit temps d’arrêt 🛑 !

Il serait logique lancer la commande de création dans le même terminal que celui où on a lancé toutes les commandes az jusqu’ici.

Cependant, il serait intéressant de tester le bon fonctionnement de notre “principal de service” créé précédemment.

Comme nous sommes déjà authentifiés avec Azure CLI, nous allons lancer une autre Azure CLI isolée de notre système, grâce à Docker. Pour cela, exécutez d’abord ceci pour récupérer l’image Docker d’Azure CLI :

docker pull mcr.microsoft.com/azure-cli:latest

Ensuite, lancez :

docker run --rm -it mcr.microsoft.com/azure-cli:latest

Vous devriez voir le “prompt” de votre terminal changer. Quelque chose comme ceci :

$ docker run --rm -it mcr.microsoft.com/azure-cli:latest
47730d3051f7:/#

On a lancé un conteneur en mode interactif (-it) et nous sommes dans son shell.

Lancez la commande suivante pour vous authentifier en utilisant le SP, en remplaçant <appId>, <password> et <tenant> par les valeurs que vous avez obtenues lors de la création du SP :

az login --service-principal -u <appId> -p <password> --tenant <tenant>

Par exemple, pour moi :

az login --service-principal -u cf39fdbd-d70a-49e4-88b6-edad5ca4dc16 -p ZO8jw~vFW4Vm3gdjwW2cU3d5bK_BgJVfoIThmGZm --tenant 7e301642-6fa4-4989-a914-8d6cd6df1146

Vous verrez s’afficher des données JSON en cas de succès :

[
  {
    "cloudName": "AzureCloud",
    // [... COUPÉ ...]
    "user": {
      "name": "9fca686c-9e6d-433f-93b9-a3386fc0defc",
      "type": "servicePrincipal"
    }
  }
]

Vous pouvez continuer sur l’étape suivante !

Lancer la commande de création de l’ACR

Lancez cette commande avec votre groupe de ressources pour créer votre ACR :

az acr create -n acripiglambert -g rg-ipi-cicd-glambert --sku Basic

Une grande quantité de données sont imprimées si la commande réussit. Vous pouvez vérifier que l’ACR existe :

  • via la CLI avec az acr list
  • sur le portail web Azure, en cherchant “container registries” dans la barre de recherche tout en haut.

Uniquement pour celles et ceux qui ont suivi la section précédente : si vous avez exécuté la commande à l’intérieur de l’image Docker Azure CLI, vous pouvez désormais quitter le shell du conteneur avec exit ou la combinaison Ctrl+D.

Tester le push d’une image vers l’ACR

Modifier le pipeline

Il nous reste encore du travail de préparation manuel, pour la partie Kubernetes.

Mais nous pouvons déjà commencer à tester certaines choses dans notre pipeline, comme le push d’images vers l’ACR.

Les modifications qui suivent visent à remplacer le push vers le Docker Hub par un push vers l’ACR.

Le repo qui vous est fourni - ou le vôtre de la dernière fois - contient un bloc semblable à celui-ci, à la fin :

# Construction de l'image Docker, en récupérant
# le résultat de l'étape précédente
build_push_image:
  stage: build_push_image
  only:
    - main
  needs:
    - build
  image: docker:latest
  services:
    - docker:dind
  script:
    - docker build -t $DOCKER_HUB_USERNAME/ipi-ci-cd-example .
    # vers Docker Hub
    - docker login -u $DOCKER_HUB_USERNAME -p $DOCKER_HUB_TOKEN
    - docker push $DOCKER_HUB_USERNAME/ipi-ci-cd-example

Si vous utilisez le repo de la dernière session, faites attention (j’ai changé le nom de la stage build_image en build_push_image).

Placez-vous dans le repo (cloné à partir de votre fork).

Vérifiez qu’il est “clean” avec git status (sinon vous pouvez utiliser git stash ou committer les changements en cours).

Vous allez remplacer uniquement la partie script de ce bloc par ceci (attention à l’indentation quand vous copiez-collez !) :

script:
  # Construction d'une variable contenant le nom de l'image et son tag
  # On construit d'abord le nom de l'image en combinant le nom de l'ACR suivi de `.azurecr.io`
  # puis du nom de l'application (ou d'un composant)
  - export IMAGE_NAME="$AZURE_ACR_NAME.azurecr.io/ipi-cicd-deployment-server"
  # On construit ensuite un tag basé sur le nom de la branche et le "sha" du commit"
  # Pour la branche `main` et le commit `6a6c9abe` cela donnera `main-6a6c9abe`
  - export IMAGE_TAG="${CI_COMMIT_REF_NAME}-${CI_COMMIT_SHORT_SHA}"
  # On colle ce tag derrière le nom de l'image
  - export IMAGE_NAME_TAG="${IMAGE_NAME}:${IMAGE_TAG}"
  # On construit l'image en lui apposant ce tag
  - docker build -t $IMAGE_NAME_TAG .
  # On se connecte à l'ACR en utilisant les identifiants du SP
  - docker login "$AZURE_ACR_NAME.azurecr.io" -u $AZURE_CLIENT_ID -p $AZURE_CLIENT_SECRET
  # On pousse l'image vers l'ACR
  - docker push $IMAGE_NAME_TAG

Dans ce bloc, d’où viennent toutes les variables préfixées par CI_ et par AZURE_ ?

  • Celles préfixées par CI_ sont directement disponibles, fournies par GitLab CI.
  • Nous allons devoir créer celles préfixées par AZURE_.

Renseigner les variables d’environnement sur GitLab

Ensuite, rendez-vous sur GitLab, allez sur votre repo, et rendez-vous sous la section Settings > CI/CD, comme indiqué ci-dessous.

GitLab repo CI/CD settings

Dans la page qui s’affiche, allez sous la partie Variables et cliquez Expand (qui devient Collapse)

GitLab repo CI/CD variables

En utilisant Add Variable, vous allez créer les variables suivantes (d’autres viendront plus tard) :

  • AZURE_CLIENT_ID : valeur de appId de votre SP
  • AZURE_CLIENT_SECRET : valeur de password de votre SP
  • AZURE_TENANT_ID : valeur de tenant de votre SP (qu’on ne va pas utiliser immédiatement)
  • AZURE_ACR_NAME : nom de votre ACR (dans mon exemple, acripiglambert).

Pousser le pipeline

Faites un git add .gitlab-ci.yml, puis un commit puis poussez.

Attendez que tous les jobs passés sur la CI 🤞.

Pour vérifier que votre image a bien été poussée, vous pouvez :

  • Utiliser az acr repository list suivi de -n et du nom de votre ACR. Par ex az acr repository list -n acripiglambert,
  • Ou aller sur le portail Azure, chercher Container Registries, cliquer sur le nom de votre registre, puis dans la barre latérale de la nouvelle vue, aller sous Services > Repositories.

Allez voir le journal du job de build/push de l’image. Peu avant la ligne docker login ... (en vert), vous trouverez une ligne comme celle-ci :

#10 naming to acripiglambert.azurecr.io/ipi-cicd-deployment-server:test-acr-01-838e4120 done

Notez le nom + tag qui vous est donné — dans mon exemple acripiglambert.azurecr.io/ipi-cicd-deployment-server:test-acr-01-838e4120. Il vous resservira plus tard.

Créer le cluster AKS et s’y connecter

Références documentaire :

Créer le cluster

La commande suivante permet de créer un cluster. Le dernier argument est optionnel mais nous permettra de choisir une taille de VM soit petite (et donc peu chère), et suffisante pour notre usage.

az aks create --resource-group <resourceGroup> --name <clusterName> --node-count <nodeCount> --generate-ssh-keys --attach-acr <acrName> --node-vm-size <vmSize>

Nous allons l’adapter en remplaçant :

  • <resourceGroup> par le nom de notre groupe de ressources,
  • <clusterName> par le nom que l’on veut donner à notre cluster, par exemple ipiCicdAKSCluster
  • <nodeCount> par le nombre de noeuds du cluster : 1 suffira pour l’instant.
  • <acrName> par le nom de notre ACR.
  • <vmSize> par une taille de machine virtuelle, à choisir dans une longue liste.

Ainsi, pour mon continuer sur mon propre exemple :

az aks create --resource-group rg-ipi-cicd-glambert --name aks-ipi-cicd-cluster --node-count 1 --generate-ssh-keys --attach-acr acripiglambert --node-vm-size Standard_B2s

Cette commande va prendre du temps pour s’exécuter. C’est normal !

Une fois le cluster créé, vous pourrez confirmer qu’il existe bien avec :

  • az aks list
  • ou via le portail Azure, en cherchant “kubernetes services”

Se connecter au cluster

kubectl permet d’interagir avec un cluster Kubernetes. Nous en aurons besoin pour effectuer des opérations : déploiement initial, interrogation de l’état du cluster, des déploiements, des pods, etc.

Installez la commande kubectl avec :

az aks install-cli

Il faut ensuite permettre à kubectl de se connecter à votre cluster AKS.

Lancez cette commande, en l’adaptant à vos paramètres, pour récupérer des identifiants, qui seront ensuite stockés sur votre machine locale.

az aks get-credentials --resource-group <resourceGroup> --name <aksCluster>

Si tout va bien, vous obtiendrez un affichage semblable à ceci :

$ az aks get-credentials --resource-group rg-ipi-cicd-glambert --name aks-ipi-cicd-cluster
Merged "aks-ipi-cicd-cluster" as current context in /Users/username/.kube/config

Vous pouvez ensuite, par exemple, interroger les noeuds du cluster, avec la commande kubectl get nodes, qui produit un résultat semblable à ceci :

$ kubectl get nodes
NAME                                STATUS   ROLES   AGE   VERSION
aks-nodepool1-11947721-vmss000000   Ready    agent   7m    v1.27.7

Préparer l’application pour le déploiement

Explications rapides sur Kubernetes

Pour déployer une application sur un cluster Kubernetes, vous allez avoir besoin d’un manifeste : un fichier qui décrit les “objets” Kubernetes qui vont composer votre application.

Sans entrer dans les détails (Kubernetes est un très vaste sujet !), voici de succintes explications des bases :

  • Un cluster Kubernetes est composé de noeuds :

    • les noeuds du control plane qui exécutent les composants formant Kubernetes
    • les working nodes, les noeuds sur lesquels vous allez déployer votre application
  • Sur vos working nodes, vos conteneurs vont être déployés dans des pods.

  • Vous n’allez pas créer les pods vous-mêmes : vous allez créer des déploiements.

  • Un déploiement permet de déployer un ou plusieurs pods à partir d’une image, et avec la possibilité de les répliquer (pour la répartition de charge, et la tolérance aux pannes).

  • Si un pod crashe, Kubernetes va s’occuper d’en recréer un autre.

  • Un service permet de router du trafic réseau vers les pods d’un déploiement.

Le manifeste permet de spécifier un état désiré, et Kubernetes va faire en sorte de faire des ajustements en permanence, pour maintenir cet état, ou le retrouver.

Télécharger et adapter le manifeste

Téléchargez un manifeste de base en suivant ce lien, et placez le fichier aks-config.yml à la racine de votre dépôt (ou dans un sous répertoire, par exemple k8s ou aks).

Vous allez devoir changer une ligne, la ligne 19, qui, dans le fichier de base, est ceci :

image: myacrname.azurecr.io/ipi-cicd-deployment-server:main-838e4120

Il faut changer myacrname pour le nom de votre ACR, et le tag en toute fin au tag de l’image que vous avez poussée vers l’ACR.

Vous pouvez retrouver le nom de l’image complète + tag dans le log du “job” GitLab de build + push de l’image (quelques lignes au-dessus de docker login).

Pour terminer cette phase de préparation, committez ce fichier.

Effectuer un premier déploiement manuellement

Une fois la configuration aks-config.yml adaptée à vos paramètres, lancez le déploiement avec cette commande :

kubectl apply -f aks-config.yml

Résultat attendu :

$ kubectl apply -f aks-config.yml
deployment.apps/server created
service/server created

Vous pouvez lancer cette commande pour vérifier l’état du service server :

kubectl get service server --watch

Elle va produire ce résultat :

NAME     TYPE           CLUSTER-IP     EXTERNAL-IP   PORT(S)        AGE
server   LoadBalancer   10.0.148.218   <pending>     80:32749/TCP   10s

Au bout d’un moment, une adresse IP s’affichera sous EXTERNAL-IP : ce sera l’adresse IP publique de votre application, que vous pourrez saisir dans la barre d’adresse de votre navigateur, précédée de http:// (et non https://). Par exemple, dans mon cas : http://20.19.13.40.

En attendant, vous pouvez, dans une autre fenêtre de terminal, interroger d’autres paramètres du cluster.

Par exemple, listez les pods avec kubectl get pods (ici le résultat une fois le pod en état de marche, et sans redémarrage dû à un plantage) :

$ kubectl get pods
NAME                      READY   STATUS    RESTARTS   AGE
server-6fb969586f-g5ftc   1/1     Running   0          7m

Vous pouvez obtenir le log d’un pod avec kubectl logs <podName>. Par exemple, en prenant la colonne NAME de l’affichage ci-dessus : kubectl logs server-6fb969586f-g5ftc.

$ kubectl logs server-6fb969586f-g5ftc

> ipi-cicd-node-ts-ecommerce@1.0.0 start
> node dist/index

Server is running on port 3000
GET / 200 5.173 ms - 13
GET / 200 0.574 ms - 13
GET / 200 0.596 ms - 13

Les lignes GET / 200 correspondent à des requêtes effectuées par Kubernetes vers les pods pour vérifier leur état de santé (correspondant aux parties startupProbe, readinessProbe et livenessProbe du manifeste aks-config.yml).

Note : une autre façon de récupérer l’adresse publique d’un pod est de lancer cette la commande ci-dessous.

kubectl get svc server -o jsonpath='{.status.loadBalancer.ingress[0].ip}'

Modifier le pipeline GitLab

Afin de mettre à jour le déploiement lorsque vous publiez vos changements sur main, il va falloir modifier le pipeline.

Note : c’est un workflow simplifié pour l’instant. Dans un environnement de production en entreprise, on peut avoir un workflow plus complexe. Par exemple, builder et pousser les images vers le registre Docker quand un tag spécifique est poussé (par ex. deploy). Et mettre à jour d’abord un environnement de pré-production. Vaste sujet, qu’on tâchera d’aborder une prochaine fois !

Reprenez votre fichier .gitlab-ci.yml.

Au début, sous stages, ajoutez la ligne deploy. Le bloc stages doit ressembler à ceci :

stages:
  - install
  - lint
  - build
  - build_push_image
  - deploy

Ajoutez à la fin du fichier, ajoutez ce bloc :

deploy:
  stage: deploy
  # Utiliser l'image Docker Azure CLI
  image: mcr.microsoft.com/azure-cli:latest
  # Seulement sur la branche main
  only:
    - main
  script:
    - echo "Deploying ${CI_COMMIT_REF_NAME}@${CI_COMMIT_TAG}"
    # Se connecter à Azure via le SP
    - az login --service-principal -u $AZURE_CLIENT_ID -p $AZURE_CLIENT_SECRET --tenant $AZURE_TENANT_ID
    # Installer kubectl
    - az aks install-cli
    - export IMAGE_NAME="$AZURE_ACR_NAME.azurecr.io/ipi-cicd-deployment-server"
    - export IMAGE_TAG="${CI_COMMIT_REF_NAME}-${CI_COMMIT_SHORT_SHA}"
    - export IMAGE_NAME_TAG="${IMAGE_NAME}:${IMAGE_TAG}"
    - az aks get-credentials --resource-group $AZURE_RESOURCE_GROUP --name $AZURE_AKS_NAME
    # IMPORTANT !
    # Cette ligne va mettre à jour l'image utilisée par le déploiement `server`, avec le nouveau tag
    # (donc la nouvelle version de l'image) ce qui aura pour effet de mettre à jour l'app déployée
    - kubectl set image deployment/server server=$IMAGE_NAME_TAG

Il va vous falloir renseigner, dans Settings > CI/CD, deux nouvelles variables :

  • AZURE_RESOURCE_GROUP : nom de votre groupe de ressources
  • AZURE_AKS_NAME : nom de votre cluster

Committez et poussez, et suivez l’état des jobs !

Améliorations

Plusieurs pistes d’amélioration sont possibles.

Notamment, on pourrait faire en sorte d’effectuer la mise à jour du déploiement AKS uniquement quand un certain tag associé à un numéro de version (par ex. v1.0.1) est poussé vers le dépôt GitLab.

On va voir cela ensemble.

Fin

IMPORTANT : nettoyer avant de partir !

Pour ne pas consommer inutilement votre crédit Azure, il va être important, une fois tout terminé, de supprimer tout ce qu’on a créé :

  • le cluster AKS
  • le registre ACR
  • le groupe de ressources