GitLAB CI/CD - Mise en place d'un cache partagé

Présentation

Le système de cache de GitLab CI/CD vous permet de partager des fichiers entre différentes étapes (stages). Ces fichiers sont utiles pour l'exécution de cette étape, par exemple, des dépendances de librairies tierces de votre langage / framework favori. Ce mécanisme doit vous permettre d'optimiser les temps d'exécution de votre chaîne d'intégration continue.

Mise en œuvre

GitLab CI/CD permet d'utiliser un espace de stockage au format S3 (ou autre) pour stocker des éléments communs à plusieurs stages dans une pipeline, typiquement des dépendances PHP, Java, NodeJS, ou pour tout autre langage / framework fonctionnant sur ce modèle.

L'utilisation d'un cache vous permet d'optimiser les performances de votre chaîne d'intégration continue en limitant le nombre de fichiers téléchargés, en réduisant le temps d'exécution et en limitant les ressources nécessaires, pour le bien de notre planète.

La mise en place d'un cache partagé n'est utile que si vous utilisez plusieurs runners que vous maitrisez au sein de votre infrastructure, ou encore dans le cadre de runners cloud en autoscaling (nous allons d'ailleurs écrire prochainement un article sur ce sujet). Dans le cas d'un runner unique, son cache disque local sera plus performant qu'un cache réseau.

Naturellement ont pourrait choisir un cache Amazon Web Services S3 (https://aws.amazon.com/fr/s3/) mais les principes d'authentification AWS sont assez contraignants avec des tokens expirant rapidement. Dans le cadre de cet article, il a été retenu d'utiliser le service Scaleway (https://www.scaleway.com/fr/) qui propose du stockage au format S3 à un coût bien maitrisé, de plus, la configuration du service est particulièrement facile et intuitive.

Pomlo n'est en aucun cas affilié à Scaleway, nous avons sélectionné ce fournisseur pour cette mise en œuvre car il nous paraissait le plus pertinent en regard de notre contexte. Libre à vous de transposer le principe décrit ci-dessous à votre fournisseur préféré de service S3.

Prérequis Scaleway

Le premier prérequis est bien évidement de créer un compte Scaleway et d'autoriser un moyen de paiement. Une transaction "test" permettra de valider votre moyen de paiement au via un code apparaissant sur votre relevé de banque.

Définition d'une politique d'accès au stockage S3

Afin de respecter quelques principes basiques de sécurité, nous allons définir une série d'éléments permettant au runner GitLab CI/CD d'accéder au cache S3 de manière adaptée.

Dans le menu de votre "Organisation" vous trouverez une section "IAM" qui permet de gérer les règles d'accès. 

Accès IAM depuis le menu

 

Cette fonctionnalité est aussi accessible depuis la page d'accueil de la console via un bouton d'accès direct.

Accès IAM depuis la page d'accueil

 

Création d'une "policy"

La première étape consiste à définir une politique (policy) que l'on pourra ensuite rattacher à un utilisateur au sens large.

Depuis l'écran de gestion "IAM", choisir l'onglet "Policies".

Onglet policies

Créer une politique que l'on va nommer "ci-storage-access" qui contient une seule règle "ObjectStorageFullAccess". Cette opération s'effectue en 3 étapes simples :

1)

Policy étape 1

 

2)

Policy étape 2

 

3)

Policy étape 3

 

À la fin du processus votre politique d'accès devrait ressembler à cela :

Policy résultat

 

Création d'un utilisateur

Notre policy étant maintenant définie, nous allons créer un utilisateur auquel nous allons rattacher cette règle d'accès.

Dans notre cas, l'accès étant prévu pour un service tiers, le runner GitLab CI/CD, nous allons plus exactement créer une "Application", et non un "Utilisateur" qui correspond plus à un accès configuré pour une personne physique.

Depuis l'écran de gestion "IAM", choisir l'onglet "Applications" :

Onglet Applications

 

Créer une application que l'on va nommer "application-gitlab-ci" qui sera reliée à notre policy "ci-storage-access".

Création application

 

Création d'une clé API

La dernière étape de notre configuration d'accès consiste à générer une clé API pour notre application.

Depuis l'écran de gestion "IAM", choisir l'onglet "Clés API" :

 

Générer une clé API pour l'application "application-gitlab-ci", veillez à ne pas définir d'expiration.

 

Une fois la clé générée, notez (copiez) l'identifiant de la clé et le secret, ils seront utiles plus tard pour le paramétrage des runners GitLab CI/CD.

 

Création de l'espace de stockage

Les prérequis d'accès étants paramétrés, nous allons pouvoir définir notre espace de stockage S3.

L'accès à la gestion du stockage s'effectue depuis le menu à gauche "Stockage > Object Storage.

 

Création d'un bucket

Créer un bucket que l'on va nommer "cache-gitlab-ci-pomlo" (remplacer "pomlo" par le nom de votre entité). Cet écran vous propose également un simulateur de coût très pratique, au moment de l'écriture de cet article, le coût mensuel pour 100GO est de 1.5 €.

 

Une fois votre bucket créé, il reste quelques ajustements à effectuer pour optimiser notre configuration.

 

Création d'un répertoire de stockage (optionnel)

Plutôt que d'envoyer directement les fichiers à la racine du bucket, nous allons définir un dossier qui correspond au groupe de votre instance GitLab. Cette opération est optionnelle et dépend de votre organisation. Pour notre part, nous avons défini dans GitLab CI/CD des "group runners", ceci nous permet de contrôler plus finement quel(s) runner(s) utilise quel dossier de l'espace de stockage.

 

Purge des objets obsolètes

Afin de libérer de l'espace et optimiser les coûts, nous allons définir une règle de vie des objets stockés afin de les purger automatiquement après un certain délai.

Dans notre cas, nous allons créer une règle de purge pour les objets plus anciens que 90 jours. Ce chiffre sera à adapter au contexte de votre projet et devra être mis en relation avec les signatures de cache définies dans la chaîne d'intégration continue (pipeline), nous verrons ce point au dernier chapitre.

Depuis l'écran de gestion de votre bucket, choisir l'onglet "Règles de cycle de vie" :

 

Créer une règle que l'on va nommer "purge-j90" :

 

Puis définir la règle à proprement parler :

 

Puis valider la création de la règle.

 

À ce stade, la configuration du stockage est terminée et il peut être utilisé pour gérer le cache CI/CD.

 

Configuration du runner GitLab CI/CD

Comme indiqué en préambule, vous devez avoir un accès à la configuration de votre runner pour mettre en place la configuration du cache.

Le fichier de configuration peut varier selon les installations mais il y a une forte probabilité qu'il se trouve sous /etc/gitlab-runner/config.toml.

Munissez-vous de votre éditeur de texte préféré et ajouter une section runners.cache qui s'apparente à l'exemple suivant :


  name = "my_runner.acme.org-my_description"
  url = "https://gitlab.com/"   # Url de votre instance Gitlab
  #...
  [runners.cache]
    MaxUploadedArchiveSize = 0
    Type = "s3"
    Shared = true
    [runners.cache.s3]
      ServerAddress = "cache-gitlab-pomlo-ci.s3.fr-par.scw.cloud" # my_bucket.s3.my_location.scw.cloud, url à récupérer dans l'écran "Réglages du bucket"
      AccessKey = "********"    # API key from IAM
      SecretKey = "********"    # API secret from IAM
      BucketLocation = "fr-par" # ajuster selon le choix de la région
      BucketName = "my_folder"  # my_folder correspond à la configuration optionnelle du répertoire de stockage
      Insecure = false

 

Attention ! cette configuration est à reproduire pour chaque runner déclaré dans le fichier de configuration config.toml.

 

Le runner doit être relancé pour prendre en compte la configuration, ceci s'effectue avec la commande gitlab-runner restart.

 

Utilisation du cache dans un fichier de configuration GitLab CI/CD

Pour utiliser efficacement le cache dans une pipeline, il est primordial de définir une clé de cache qui permettra de gérer correctement les répertoires que l'on souhaite mettre en cache.

Vous devrez donc vous poser plusieurs questions :

  • Quels sont les répertoires que je veux mettre en cache ? Il s'agit généralement d'un répertoire dans lequel votre système de gestion de dépendances télécharge les librairies tierces.
  • Comment puis-je identifier le contenu de ce(s) répertoire(s )et ainsi définir la clé de cache sur cet identifiant ?

GitLab et nos gestionnaires de dépendances ont dû se causer car c'est assez simple à mettre en œuvre !

 

Exemple d'un projet NodeJS :

cache:
  key:
    files:
      - package-lock.json
  paths:
    - node_modules/

La clé de cache est ici basée sur la signature du fichier package-lock.json, dès qu'une dépendance va changer, ce fichier sera mis à jour et une nouvelle clé de cache sera ainsi définie pour les pipelines suivantes.

 

Exemple d'un projet PHP + NodeJS

cache:
  key:
    files:
      - composer.lock
      - yarn.lock
  paths:
    - vendor/
    - node_modules/

La clé de cache est ici basée sur la signature de deux fichiers, dès lors que l'un des deux change, une nouvelle clé de cache est définie.

 

Attention, à ce jour GitLab CI/CD ne peut baser la clé de cache que sur deux fichiers au maximum.

 

Exemple d'exécution d'un pipeline :

... Stage initialization
Restoring cache
Checking cache for 0_package-lock-fbf4d73800548dbea2dd7c47f5676a4bc38b38bb-non_protected...
Downloading cache.zip from https://xxxxxxx.s3.fr-par.scw.cloud/xxxxxxx/project/123456789/0_package-lock-fbf4d73800548dbea2dd7c47f5676a4bc38b38bb-non_protected 
Successfully extracted cache
... Some Tasks
Saving cache for successful job
Creating cache 0_package-lock-fbf4d73800548dbea2dd7c47f5676a4bc38b38bb-non_protected...
node_modules/: found 26085 matching artifact files and directories 
Uploading cache.zip to https://xxxxxxx.s3.fr-par.scw.cloud/xxxxxxx/project/123456789/0_package-lock-fbf4d73800548dbea2dd7c47f5676a4bc38b38bb-non_protected 
Created cache
... Stage finalization

 

Dans les fichiers de configuration GitLab CI/CD, il est possible de définir une politique de gestion du cache, push, pull ou push/pull (par défaut). Se reporter à la documentation GitLab CI/CD si besoin.

 

Pour aller plus loin

Cet article a initialement été écrit comme documentation interne suite à la mise en application sur deux plateformes de production, ceci pour partager et promouvoir la cuture DevOps à l'ensemble de nos développeurs.

N'hésitez pas à nous remonter vos commentaires et retours d'expérience via le formulaire de contact ci-dessous.

Un article complémentaire sera certainement publié dans le futur sur la suite de l'optimisation de notre chaîne d'intégration continue, stay tuned !