Home >> Blog >> Optimisation du pipeline GitOps Cloud Native avec ArgoCD Image Updater

Optimisation du pipeline GitOps Cloud Native avec ArgoCD Image Updater

09 novembre 2023

By Sami AMOURA.

Optimisation du Pipeline GitOps Cloud-Native avec ArgoCD Image Updater sur OpenShift/Kubernetes

Cet article s’inscrit dans la lignée du précédent blogpost Mise en place d’une chaîne d’intégration continue GitOps Cloud-Native sur OpenShift/Kubernetes publié quelques semaines plus tôt sur le blog de SoKube. Celui-ci montrera comment optimiser davantage le pipeline GitOps Cloud Native avec l’outil ArgoCD Image Updater mis en place dans l’article précédent. Cet outil, encore experimental, faisant partie du projet Argo nous permettra de nous soustraire du stage mettant à jour le repository GitOps de déploiement.

Nous repartirons de l’application simple Fruitz, qui permet d’ajouter et de supprimer une liste de fruits. Dans le précédent article, nous avions corrigé un bug qui empêchait l’utilisateur d’ajouter des fruits dont le nombre de caractères dépassait 6. Nous avions étendu cette limite à 9 à l’aide d’une chaîne d’intégration complète reposant sur Tekton Pipelines pour la partie Intégration Continue (CI) et ArgoCD pour la partie Déploiement Continue (CD).

Dans ce blogpost nous fonctionnerons de la même façon. Nous implémenterons la fonctionnalité permettant l’ajout de fruits dont le nombre de caractères peut être inférieur ou égal à 10 (au lieu de 9 jusqu’à maintenant). Pour ce faire, nous introduirons le plugin ArgoCD Image Updater afin de mettre en place un pipeline GitOps Cloud-Native encore plus avancé.

Le projet ArgoCD Image Updater

Présentation

ArgoCD Image Updater est un outil faisant partie du projet Argo. Il est actuellement en cours de développement actif et est proposé de façon expérimentale. ArgoCD Image Updater est un plugin qui s’intègre à l’outil ArgoCD, il permet notamment de mettre à jour automatiquement l’image d’un pods Kubernetes géré par ArgoCD.

Fonctionnement

L’outil ArgoCD Image Updater permet de vérifier si une nouvelle version de l’application (image du conteneur) est disponible selon un certain modèle prédéfini, mettre à jour automatiquement le repository de déploiement GitOps et utiliser la nouvelle version de l’image au sein du cluster Kubernetes.

Pour cela l’outil va surveiller périodiquement le registre de conteneurs où sont déployées les images des conteneurs et détecter l’arrivée d’une nouvelle version de l’application en se basant sur l’apparition d’un nouveau tag en respectant une des stratégies proposées par ArgoCD Image Updater. Voici la liste des stratégies de mise à jour proposées par l’outil :

  • semver : Mise à jour vers la version autorisée la plus récente en fonction des contraintes définies,
  • latest : Mise à jour vers la dernière version de l’image (dernier tag),
  • name : Mise à jour vers la dernière version basée sur une liste de tag triés par ordre alphabétique,
  • digest : Mise à jour vers la version la plus récente d’un tag muable,
  • Filtrage de tags : Permettant à l’utilisateur de définir lui-même ses propres règles de mise à jour

ArgoCD Image Updater peut alors ensuite mettre à jour automatiquement le repository GitOps de déploiement afin de conserver le principe de source unique de vérité et éviter les conflits de fusions (merges) au sein du dépôt GitOps.

En fonction de la politique de synchronisation définie pour l’application, ArgoCD déploiera automatiquement la nouvelle version de l’image ou marquera l’application comme désynchronisée. Vous pourrez déclencher la mise à jour de l’image manuellement en synchronisant l’application. Grâce à une intégration complète avec ArgoCD, les fonctionnalités avancées telles que la synchronisation ou les gestion RBAC sur les ressources de type application sont entièrement prises en charge. Pour indiquer à une application ArgoCD qu’elle doit utiliser ArgoCD Image Updater, il suffit d’ajouter des annotations Kubernetes.

ℹ️   A noter que ArgoCD Image Update ne supporte que les déploiement Kubernetes basés sur Helm ou Kustomize..

Workflow

Genral workflow

Pipeline GitOps Cloud-Native avancé

La démonstration du pipeline GitOps Cloud-Native basée sur l’outil ArgoCD Image Updater consistera à la mise à jour de l’application Fruitz composée de deux microservices :

  • Le backend développé avec en Java Quarkus : fruitz-quarkus
  • Un frontend reposant sur la technologie Angular

Pour cette démonstration le pipeline GitOps sera réalisé uniquement sur le microservice Java Quarkus Fruitz Quarkus. Il sera composé d’une CI (Intégration Continue) standard orchestrée par OpenShift Pipelines (Tekton) et d’une CD (Déploiement Continue) gérée par OpenShift GitOps ainsi que ArgoCD Image Updater.

Le repository GitOps de déploiement Fruitz Deploy utilisera le package manager Helm pour déployer l’application au sein du cluster OpenShift. Pour respecter le modèle GitOps le code applicatif et celui de déploiement sont hébergés dans deux repositories distincts sur la plateforme GitLab.com.

Voici l’url du repository applicatif : Fruitz Quarkus

Rappel du contexte

Lors du précédent blogpost l’application Fruitz était déployée et nous avions ajoutés 2 fruits supplémentaires :

  • Pear (poire)
  • Pineapple (ananas)

Initial user interface

Reprenons l’application et essayons d’ajouter le fruit Watermelon.

Adding watermelon

Le fruit Watermelon ayant un nombre de caractères égal à 10 et l’application Fruitz étant volontairement limitée à une taille de 9 caractères par fruit, l’ajout de ce nouveau fruit est en échec. Nous pouvons voir les logs de l’erreur depuis l’interface graphique d’ArgoCD :

ArgoCD logs

L’objectif de ce tutoriel est donc de corriger une nouvelle fois le bug et ainsi étendre la limite du nombre de caractères à 10 pour les noms de fruits. Ce processus permettra de mettre en évidence les fonctionnalités de l’outil ArgoCD Image Updater en association avec ArgoCD dans le cadre d’une chaîne d’intégration GitOps Cloud-Native.

Tekton Pipeline

Pour rappel, avant l’intégration de l’outil ArgoCD Image Updater, le pipeline Tekton était composé de 4 tasks :

  • maven-package : packaging de l’application Java,
  • container-image-build-push : conteneurisation de l’application Java et push dans le registre de conteneurs,
  • scan-trivy : scanner de vulnérabilité de l’image conteneur (SAST),
  • update-helm-deployment-repository : mise à jour du repository GitOps de déploiement.

Tekton intial four tasks

Comme décrit dans l’introduction de ce blogpost, l’outil ArgoCD Image Updater va nous permettre de décorréler complètement la CI de la CD. En effet, la CI et la CD ont des cycles de vie indépendants et ArgoCD Image Updater nous permet de nous soustraire du stage update-helm-deployment-repository de mise à jour du repository GitOps de déploiement. C’est ArgoCD Image Updater qui se chargera maintenant lui-même de redéployer la nouvelle version du microservice.

Vous pouvez supprimer la task Tekton via la console OpenShift ou à l’aide de la commande suivante :

oc --namespace cicd delete task update-helm-deployment-repository

Vous devez aussi modifier le pipeline Tekton fruitz-quarkus en supprimant la référence à la task update-helm-deployment-repository :

Pipeline fruitz-quarkus:

apiVersion: tekton.dev/v1beta1
kind: Pipeline
metadata:
  name: fruitz-quarkus
  namespace: cicd
spec:
  workspaces:
    - name: shared-workspace

  resources:
    - name: git-source-fruitz-application
      type: git
    - name: git-source-fruitz-deployment
      type: git

  params:
    - name: buildRevision
    - name: buildRevisionShort
    - name: buildRevisionBranch

  tasks:
    - name: maven-package
      taskRef:
        name: maven-package
      resources:
        inputs:
          - name: git-source-fruitz-application
            resource: git-source-fruitz-application
      workspaces:
        - name: shared-workspace
          workspace: shared-workspace

    - name: container-image-build-push
      taskRef:
        name: container-image-build-push
      params:
        - name: buildRevision
          value: $(params.buildRevision)
        - name: buildRevisionShort
          value: $(params.buildRevisionShort)
        - name: buildRevisionBranch
          value: $(params.buildRevisionBranch)
        - name: mavenProjectVersion
          value: $(tasks.maven-package.results.mavenProjectVersion)
      resources:
        inputs:
          - name: git-source-fruitz-application
            resource: git-source-fruitz-application
      workspaces:
        - name: shared-workspace
          workspace: shared-workspace
      runAfter:
        - maven-package

    - name: scan-trivy
      taskRef:
        name: scan-trivy
      params:
        - name: dockerImageFullName
          value: $(tasks.container-image-build-push.results.dockerImageFullName)
      workspaces:
        - name: shared-workspace
          workspace: shared-workspace
      runAfter:
        - container-image-build-push

Le pipeline Tekton fruitz-quarkus est maintenant uniquement composé de 3 tasks :

  • maven-package
  • container-image-build-push
  • scan-trivy

Tekton intial four tasks

Installation et configuration de ArgoCD Image Updater

Installation

Il existe deux méthodes pour installer l’outil ArgoCD Image Updater :

  • Dans le même cluster Kubernetes (et le même namespace) qu’où est déployé l’instance ArgoCD à l’aide de manifestes Kubernetes natifs et/ou Kustomize,
  • Dans un cluster Kubernetes différents d’où est déployé l’instance ArgoCD.

Dans ce tutoriel nous installerons ArgoCD Image Updater et ArgoCD (déjà installé) au sein du même cluster. Pour plus d’informations, vous pouvez consulter la documentation officielle.

Pour installer l’outil ArgoCD Image Updater dans le namespace openshift-gitops, entrez les commandes suivantes :

git clone https://github.com/argoproj-labs/argocd-image-updater
cd argocd-image-updater
oc -n openshift-gitops apply -f manifests/install.yaml 

Le manifeste argocd-image-updater/manifests/install.yaml contient l’ensemble des ressources Kubernetes nécessaires au fonctionnement de l’outil (Service Account, RBAC, ConfigMap, Deployment…)

Une fois les objets créés, vous pouvez vérifier que l’installation s’est déroulée correctement à l’aide de la commande suivante :

oc -n openshift-gitops get all -l app.kubernetes.io/name=argocd-image-updater

NAME                                        READY   STATUS    RESTARTS   AGE
pod/argocd-image-updater-764ff8ddb7-45bn6   1/1     Running   0          55s

NAME                                        READY   UP-TO-DATE   AVAILABLE   AGE
deployment.apps/argocd-image-updater        1/1     1            1           55s

NAME                                              DESIRED   CURRENT   READY   AGE
replicaset.apps/argocd-image-updater-764ff8ddb7   1         1         1       55s

Configuration

ArgoCD Image Updater est maintenant installé au sein du cluster mais il est nécessaire d’effectuer certaines configurations pour le rendre fonctionnel. Comme évoqué lors de l’introduction et pour ne pas complexifier les choses nous utilisons GitLab comme Source Code Management aisni que Gitlab Conatainer Registry pour héberger nos images de conteneur.

Pour pouvoir automatiquement mettre à jour les versions des images et respecter les piliers fondamentaux du GitOps, ArgoCD Image Updater a besoin de pouvoir surveiller la container registry afin de détecter l’apparition de nouvelles versions mais aussi de pouvoir écrire (write-back) dans le repository GitOps de déploiement. Pour ce faire, nous devons permettre à ArgoCD Image Updater de pouvoir se connecter à la container registry mais aussi écrire dans le repository GitLab. Il nous faut créer deux secrets Kubernetes :

  • Un secret de type docker-registry que nous appellerons gitlab-registry-credentials afin de pouvoir se connecter et surveiller notre GitLab container registry
  • Un autre secret nommé git-creds avec la clé privée SSH permettant d’écrire dans le repository GitOps

Dans un premier temps, il faut créer un GitLab access Token et lui attribuer la permission de pouvoir consulter la registry en lecture seule. Dans Preferences → Access Token, créer un token avec le scope read_registry*.

GitLab oken creation

Récupérez le token puis créez le secret gitlab-registry-credentials sur le cluster OpenShift à l’aide des commandes suivantes :

GITLAB_USER_NAME=samiamoura
GITLAB_SECRET_TOKEN=YOUR_PRIVATE_GITLAB_TOKEN
GITLAB_EMAIL_ADDRESS=sami.amoura@sokube.ch

oc create secret docker-registry gitlab-registry-credentials 
  --docker-server=registry.gitlab.com 
  --docker-username=$GITLAB_USER_NAME 
  --docker-password=$GITLAB_SECRET_TOKEN 
  --docker-email=$GITLAB_EMAIL_ADDRESS 
  --namespace openshift-gitops

Créez le secret git-creds contenant la clé privée SSH permettant l’accès au repository GitOps à l’aide des commandes suivantes :

  • Création du fichier contenant la clé privée :
cat << EOF > ./.gitlab-ssh-private-key.key
-----BEGIN OPENSSH PRIVATE KEY-----
...
-----END OPENSSH PRIVATE KEY-----
EOF 

ℹ️   Pensez bien à mettre votre clé privée SSH.

  • Créez le secret OpenShift contenant le clé privée
oc -n openshift-gitops create secret generic git-creds 
  --from-file=sshPrivateKey=./.gitlab-ssh-private-key.key

Il faut maintenant indiquer à ArgoCD Image Updater la configuration de la container registry. Pour ce faire, il faut ajouter/éditer la ConfigMap argocd-image-updater-config et le fichier registries.conf en lui renseignant les informations suivantes :

  • Nom de la container registry : GitLab Container Registry
  • API URL de la container registry : https://registry.gitlab.com
  • Le prefix de la registry : registry.gitlab.com

Les credentials à utiliser : pullsecret:openshift-gitops/gitlab-registry-credentials utilisation de la pullsecret gitlab-registry-credentials dans le namespace openshift-gitops (secrets OpenShift précédemment créés)

Créez/éditez la ConfigMap à l’aide des commandes suivantes :

ConfigMap argocd-image-updater-config :

apiVersion: v1
kind: ConfigMap
metadata:
  name: argocd-image-updater-config
  namespace: openshift-gitops
data:
  registries.conf: |
    registries:
    - name: GitLab Container Registry
      api_url: https://registry.gitlab.com
      prefix: registry.gitlab.com
      credentials: pullsecret:openshift-gitops/gitlab-registry-credentials

Enfin, il faut intégrer ArgoCD Image Updater à ArgoCD pour lui permettre de savoir quelle application ArgoCD utilisera cette nouvelle fonction. Pour ce faire, il suffit simplement d’ajouter des annotations dans le manifeste de l’application ArgoCD fruitz-helm.

Voici les annotations à ajouter ainsi que leur description :

  • argocd-image-updater.argoproj.io/write-back-method : permet d’indiquer comment mettre à jour les images d’une applications ainsi que les credentials à utiliser. Deux méthodes sont proposées :
    • git : approche déclarative (GitOps) à privilégier qui permet de créer un commit dans le repository GitOps avec les tags des nouvelles images
    • argocd : approche impérative qui permet de modifier directement l’application ArgoCD dans au sein du cluster Kubernetes ou en utilisant l’API ArgoCD
  • argocd-image-updater.argoproj.io/image-list : permet de définir quelle image doit être mise à jour et surveillée dans la container registry et permet de lui attribuer un alias
  • argocd-image-updater.argoproj.io/<image_alias>.update-strategy : permet de définir le type de stratégie de mise à jour
  • argocd-image-updater.argoproj.io/<image_alias>.helm.image-tag : permet de définir le chemin de la clé yaml spécifiant le tag de l’image qui doit être mise à jour (remplacé) dans le fichier values.yaml Helm lorsque ArgoCD Image Updater détecte une nouvelle version de l’image.

Modification du manifest de l’application ArgoCD fruitz-helm avec l’ajout des annotations :

ConfigMap argocd-image-updater-config :

apiVersion: argoproj.io/v1alpha1
kind: Application
metadata:
  name: fruitz-helm
  annotations:
    # Ajout des annotations suivantes
    argocd-image-updater.argoproj.io/write-back-method: git:secret:openshift-gitops/git-creds
    argocd-image-updater.argoproj.io/image-list: backend=registry.gitlab.com/sokube-io/sample-apps/fruitz/fruitz-quarkus/fruitz-quarkus
    argocd-image-updater.argoproj.io/backend.update-strategy: latest
    argocd-image-updater.argoproj.io/backend.helm.image-tag: backend.image.tag
  labels:
    owner: sokube
    scope: fruitz
  namespace: openshift-gitops
spec:
  project: fruitz-deployment
  syncPolicy:
    automated:
      prune: true
      selfHeal: true    
    syncOptions:
      - CreateNamespace=true
  source:
    path: helm
    targetRevision: redhat-opentour-geneva
    repoURL: 'git@gitlab.com:sokube-io/sample-apps/fruitz/fruitz-deploy.git'
    helm:
      valueFiles:
        - values.yaml
  destination:
    server: https://kubernetes.default.svc
    namespace: fruitz

Voici la description détaillée des annotations ajoutées :

  • argocd-image-updater.argoproj.io/write-back-method: git:secret:openshift-gitops/git-creds : Utilisation de la méthode git avec le secret kubernetes git-creds précédemment créé dans le namespace openshift-gitops
  • argocd-image-updater.argoproj.io/image-list: backend=registry.gitlab.com/sokube-io/sample-apps/fruitz/fruitz-quarkus/fruitz-quarkus : Définition l’alias backend pour l’image registry.gitlab.com/sokube-io/sample-apps/fruitz/fruitz-quarkus/fruitz-quarkus et activation de la détection des changements liés à celle-ci (surveillance de l’apparition de nouveaux tags).
  • argocd-image-updater.argoproj.io/backend.update-strategy: latest : Utilisation de la stratégie de type latest pour l’alias backend (défini dans l’annotation précédente). Cette stratégie consiste à détecter dans la container registry le tag le plus récent de l’image correspondant à l’alias bakend afin de synchroniser le repository GitOps.
  • argocd-image-updater.argoproj.io/backend.helm.image-tag: backend.image.tag : Attribution de l’alias backend (défini plus haut), au chemin YAML de la clé correspondante au champ tag de l’image du microservice fruitz-quarkus (Microservice Java Quarkus) dans le fichier Helm values.yaml. Cela dépend de la structure de votre fichier values.yaml et de la structure de votre Helm Chart. Dans notre cas le champ tag de l’image correspondant au microservice fruitz-quarkus (Microservice Java Quarkus) est accessible dans la section backend → image → tag : backend.image.tag.

Fichier helm values.yaml avec structure correspondante au microservice fruitz-quarkus :

Helm values structure

La liaison entre ArgoCD Image Updater et AgroCD est maintenant fonctionnelle, nous allons pouvoir tester notre pipeline GitOps Cloud Native avec ce nouvel outil.

Execution du pipeline

Afin de tester la nouvelle version du pipeline GitOps Cloud Native nous allons mettre à jour le microservice fruitz-quarkus afin de pouvoir ajouter des fruits avec un nombre de caractères inférieur ou égale à 10.

Mise à jour du microservice fruitz-quarkus

Mise à jour du repository fruitz-quarkus en augmentant la limite du nombre de caractères de 9 à 10 :

Update fruitz limit

Execution du nouveau pipeline GitOps Cloud Native

La mise à jour du repository fruitz-quarkus a déclenché l’execution d’un nouveau pipeline avec uniquement 3 tasks au lieu de 4 avant le déploiement de ArgoCD Image updater. En effet, comme expliqué en introduction la task de mise à jour du repository GitOps de déploiement a été supprimée.

Tekton tasks success

Tekton pipeline success

Nous pouvons constater que le pipeline a été exécuté avec succès.

Dans la container registry nous pouvons voir qu’une nouvelle version de l’image registry.gitlab.com/sokube-io/sample-apps/fruitz/fruitz-quarkus/fruitz-quarkus a été publiée par la task container-image-build-push du pipeline Tekton, avec le tag 1.0-SNAPSHOT-07a0170.

Tketon pipeline success

Dans le repository GitOps nous pouvons constater la création d’un nouveau fichier .argocd-source-fruitz-helm.yaml à la racine du projet. C’est ArgoCD Image Updater qui a créé ce nouveau fichier lors d’un nouveau commit avec les paramètres renseignés (annotations) dans le manifeste de l’application ArgoCD fruitz-helm.

ArgoCD Image Updater Helm file

Dans ce fichier on peut voir les que la clé helm.parameters.name contient les paramètres suivants :

  • image.name : registry.gitlab.com/sokube-io/sample-apps/fruitz/fruitz-quarkus/fruitz-quarkus
  • backend.image.tag : 1.0-SNAPSHOT-07a0170d

Ce sont ces paramètres qui seront utilisés par ArgoCD pour redéployer/mettre à jour l’application au sein du cluster Kubernetes/OpenShift, en surchargeant les paramètres initialement présents dans le fichier Helm values.yaml.

ArgoCD Image Updater automatic update

ArgoCD a détecté une nouvelle modification au sein du repository GitOps, il va donc s’occuper de redéployer la nouvelle version de l’application avec la nouvelle image registry.gitlab.com/sokube-io/sample-apps/fruitz/fruitz-quarkus/fruitz-quarkus:1.0-SNAPSHOT-07a0170d

New updated pod

New updated podwith commit ID

Nous pouvons à présent essayer d’ajoute rune nouvelle fois le fruit Watermelon et constater que cela fonctionne. Le fruit est bien ajouté à la liste des fruits.

Il est aussi possible de vérifier quelle version est déployée en interrogeant un endoint spécifique au microservice. Nous voyons qu’il s’agit bien de la version 1.0-SNAPSHOT-07a0170d.

New updated podwith commit ID

Dans ce nouveau tutoriel, nous avons pu voir comment mettre en place un pipeline GitOps Cloud Native avancé sur la plateforme OpenShift. Cet article introduit le plugin ArgoCD Image Updater et nous démontre comment l’utiliser en association avec les outils ArgoCD et Tekton pipelines. Finalement, le projet ArgoCD Image Updater nous permet de simplifier encore plus la mise en place de nos pipelines CI/CD ainsi que de découpler au maximum la CI de la CD qui possèdent des cycles de vie indépendants. Il est encore en phase expérimentale et donc, encore sujet à des évolutions, mais nul doute qu’il sera bientôt disponible pour accompagner nos CI/CD de production.

SoKube peut vous aider !

Consultez les liens suivants liés à cet article de blog et découvrez comment SoKube peut vous aider :

Laisser un commentaire

  Edit this page