Aller au contenu

Kargo, déployez d'un environnement à l'autre en mode GitOps

·11 mins
gitops argocd container git kargo cd helm kustomize yaml
Romain Boulanger
Auteur
Romain Boulanger
Ingénieur DevSecOps et Architecte Cloud
Sommaire

Mise à jour de l’article :

10 décembre 2024 :

  • Mise à jour de la version 0.3.1 vers la 1.0.3 de Kargo ;
  • Beaucoup d’ajustements réalisés dans les fichiers de configuration ;
  • Utilisation de la démonstration du meetup du Silicon Chalet. Pour les intéressés sur l’événement, vous pouvez trouvez le support à cette adresse.

Introduction
#

Je vous avais présenté le mois dernier Flamingo qui combine à la fois Argo CD et Flux CD pour tirer parti de ces deux outils et adopter une approche GitOps.

Néanmoins, le GitOps ou les outils ci-dessus ne définissent pas de moyen pour promouvoir les changements qui ont été apportés d’un environnement de développement à un environnement de qualification ou de production.

En effet, Argo CD et Flux CD se chargent de déployer un ou plusieurs environnements cibles sans aucun lien, ni relation entre eux.

Il est toutefois possible d’adopter un Branching Model pour promouvoir ces changements. Si ce terme ne vous parle pas, je vous recommande de consulter cet article.

Heureusement, une solution est apparue il y a quelques mois, même si cette dernière est encore un peu jeune et donc, pas encore prêt pour être utilisée en production, je vous propose dans cet article un tour d’horizon du potentiel de cet outil.

Kargo, la solution
#

Qui n’a jamais rêvé d’appuyer sur un bouton pour porter les modifications d’un environnement à un autre ? L’exemple le plus classique est une nouvelle image de conteneur que l’on teste sur un environnement de développement avant de la déployer sur un environnement de qualification.

C’est exactement ce que permet de faire Kargo, même si ce dernier permet d’aller encore plus loin que la gestion de version des images. Il est capable d’appliquer les différences de configurations de vos objets Kubernetes via un dépôt Git ou de récupérer les dernières versions de vos Charts Helm.

De plus, Kargo fait partie de la même famille qu’Argo CD et c’est un outil 100% open source. En effet, il a été développé par les créateurs d’Argo CD !

De manière synthétique, Kargo est une plateforme de livraison continue qui permet d’orchestrer le cycle de vie des applications sur Kubernetes d’un environnement à l’autre en s’appuyant sur des outils existants.

Eh oui, Kargo travaille en lien direct avec Argo CD où ce dernier s’occupe de ce qu’il sait faire le mieux : déployer les objets Kubernetes.

Fonctionnalités
#

Bien que Kargo soit un outil assez récent, il est doté de plusieurs fonctionnalités :

  • Promotion de configurations ou d’images conteneurisées d’un environnement à l’autre ;
  • Écriture des changements dans Git : Dès qu’un changement est approuvé, Kargo se charge de générer une Pull Request et commit les modifications ;
  • Possibilité d’effectuer des retours en arrière en cas d’erreur ;
  • Création de stratégie de déploiement pour valider le bon fonctionnement d’un environnement notamment avec Argo Rollouts ;
  • Le Canary et l’A/B testing peuvent être utilisés pour déployer sur un environnement cible.

Cette liste est sujette à évoluer dans les futures versions de Kargo. En effet, l’équipe a pour objectif de faire grandir le produit dans des versions futures afin de susciter l’adoption de Kargo dans des environnements de production, même si une première version majeure a été publiée (1.x.x).

Kargo dispose d’une interface utilisateur qui permet de suivre les changements en un coup d’œil :

Interface de Kargo

Cette interface permet aussi de visualiser les images ou configurations associées aux environnements définis. Ce qui permet notamment d’avoir un historique et d’auditer l’ensemble des actions au sein de Kargo.

Enfin, la grande barre noire du haut s’appelle la ligne de fret (Freight) comme pour le transport de marchandise. Vous avez compris le rapport avec Kargo maintenant, non ?

Fonctionnement
#

C’est le moment de discuter du fonctionnement de Kargo et comment ce dernier opère la gestion des environnements notamment dès lors qu’une nouvelle version d’image est disponible.

Workflow avec Kargo

Voici le déroulement des opérations dans l’ordre :

  1. La CI, quelle que soit la plateforme, crée une nouvelle image de conteneur ;
  2. Cette dernière est déposée dans un registre de conteneurs ;
  3. En fonction des configurations définies, Kargo vient analyser le dépôt Git contenant les objets Kubernetes (1) et recherche les potentielles nouvelles images (2) associées ;
  4. En fonction des nouvelles images récupérées, le développeur a le choix de promouvoir ou non ces changements sur le premier environnement configuré, qui sera développement dans ce cas-ci ;
  5. Une fois la validation du développeur, Kargo pousse les modifications dans Git ;
  6. Avec l’action précédente, Argo CD se déclenche et détecte une mise à jour des fichiers de l’environnement de développement ;
  7. Argo CD synchronise les changements sur le cluster Kubernetes ;
  8. Kargo récupère l’état des objets déployés et permet d’effectuer des tests ;
  9. Si tout est bon, le développeur a la possibilité d’approuver les changements pour l’environnement suivant.

Du côté de l’installation, Kargo se déploie de préférence avec un chart Helm et il est recommandé de l’installer au plus proche d’Argo CD car il est en interaction directe avec ce dernier.

Place à l’action
#

L’exemple qui va être utilisé sera la démonstration que j’ai eu l’occasion de dérouler lors du meetup GitOps du Silicon Chalet. Vous pouvez retrouver le code associé sur GitHub juste en dessous :

axinorm/siliconchalet-kargo-demo

Kargo demo for the Silicon Chalet Meetup

Shell
0
0

Cette démonstration utilise un chart Helm à déployer entre plusieurs environnements avec des fichiers values-*.yaml pour chaque environnement défini. Pour ceux qui préfèrent un exemple avec du Kustomize, je vous conseille de suivre le quickstart officiel de Kargo.

Je vous laisse bien évidemment consulter le README.md pour mettre en place votre environnement et le cluster Kubernetes associé.

Dans la suite, je vais expliquer les différents objets associés à Kargo. Vous pouvez retrouver ces derniers dans le dossier kargo/configurations.

Pour commencer la mise en place de la chaîne de déploiement d’environnements, on crée un Project qui est le socle pour définir la pipeline :

apiVersion: kargo.akuity.io/v1alpha1
kind: Project
metadata:
  name: siliconchalet
spec:
  promotionPolicies:
  - stage: development
    autoPromotionEnabled: true

L’objet Project créera un namespace du même nom au sein du cluster, cet objet Kubernetes est assez simple. Comme vous pouvez le voir, il est possible de définir des politiques pour les promotions (promotionPolicies) si vous souhaitez que celles-ci soient automatiques pour certains environnements.

Comme cela a été évoqué plus haut, Kargo permet de chaîner un ou plusieurs environnements en fonction de votre cycle de déploiement. Ces environnements sont matérialisés en objet Kubernetes sous le nom de Stage, mais avant de créer cet objet, il faut mettre en place un Warehouse pour écouter, par exemple, sur de nouvelles versions d’image.

apiVersion: kargo.akuity.io/v1alpha1
kind: Warehouse
metadata:
  name: siliconchalet-app
  namespace: siliconchalet
spec:
  subscriptions:
  - image:
      repoURL: public.ecr.aws/nginx/nginx
      imageSelectionStrategy: SemVer
      semverConstraint: ~1.27.0

C’est le cas ici, on souhaite récupérer les versions associées à l’image public.ecr.aws/nginx/nginx suivant la contrainte semver ~1.27.0.

Kargo permet de travailler avec plusieurs types de sources au sein de l’objet Warehouse, c’est le cas des registres d’images, dépôts de code Git ou encore des registres de charts Helm.

apiVersion: kargo.akuity.io/v1alpha1
kind: Stage
metadata:
  name: development
  namespace: siliconchalet
spec:
  requestedFreight:
  - origin:
      kind: Warehouse
      name: siliconchalet-app
    sources:
      direct: true
  promotionTemplate:
    spec:
      steps:
      - uses: git-clone
        config:
          repoURL: ${REPOSITORY_URL}
          checkout:
          - branch: main
            path: ./repo
      - uses: helm-update-image
        as: update-image
        config:
          path: ./repo/values-development.yaml
          images:
          - image: public.ecr.aws/nginx/nginx
            key: image.tag
            value: Tag
      - uses: git-commit
        as: commit
        config:
          path: ./repo
          messageFromSteps:
          - update-image
      - uses: git-push
        config:
          path: ./repo
          targetBranch: main
      - uses: argocd-update
        config:
          apps:
          - name: siliconchalet-app-development
            sources:
            - repoURL: ${REPOSITORY_URL}

Voici un exemple pour générer un environnement de development à travers Kargo. Au sein du dépôt de code, l’exemple s’appuie sur un chart Helm disponible dans le dossier helm/.

Ce chart, référencé par la variable REPOSITORY_URL est assez basique, on y trouve un Deployment avec la fameuse image public.ecr.aws/nginx/nginx associée à une ConfigMap permettant de monter du contenu html et pour finir, un Service pour rendre accessible l’application.

À noter que la création d’un Secret est nécessaire si le dépôt de code contenant les sources Helm n’est pas public. Celui-ci est automatiquement créé par le script kargo-demo.sh et doit contenir le label kargo.akuity.io/cred-type: git.

Tout d’abord, au sein de ce Stage, le bloc requestedFreight permet de lier le Warehouse défini plus haut pour écouter sur les nouvelles versions d’image. Tandis que le bloc promotionTemplate défini toutes les étapes pour mettre à jour cette version d’image :

  • git-clone : On clone le dépôt de code Helm avec la branche main dans le répertoire repo ;
  • helm-update-image : On indique ici le fichier values de l’environnement avec le tag de l’image à modifier ;
  • git-commit : Permet de réaliser un commit persistant les modifications de l’étape précédente ;
  • git-push : Push l’ensemble des modifications sur la branche définie, main dans ce cas précis ;
  • argocd-update : Dernière phase, Argo CD est déclenché pour mettre à jour et déployer la modification effectuée dans l’Application siliconchalet-app-development.

L’ensemble des instructions possibles est défini dans la documentation, n’hésitez pas à y jeter un coup d’œil.

Vous vous souvenez, dans l’objet Project, il a été spécifié que ce Stage development serait promu automatiquement avec l’option autoPromotionEnabled: true. Ces différentes étapes seront donc exécutées sans action de la part d’un utilisateur.

Il est temps d’aller plus loin et de créer les environnements de testing et production !

apiVersion: kargo.akuity.io/v1alpha1
kind: Stage
metadata:
  name: testing
  namespace: siliconchalet
spec:
  requestedFreight:
  - origin:
      kind: Warehouse
      name: siliconchalet-app
    sources:
      stages:
      - development
  promotionTemplate:
    spec:
      steps:
      - uses: git-clone
        config:
          repoURL: ${REPOSITORY_URL}
          checkout:
          - branch: main
            path: ./repo
      - uses: helm-update-image
        as: update-image
        config:
          path: ./repo/values-testing.yaml
          images:
          - image: public.ecr.aws/nginx/nginx
            key: image.tag
            value: Tag
      - uses: git-commit
        as: commit
        config:
          path: ./repo
          messageFromSteps:
          - update-image
      - uses: git-push
        config:
          path: ./repo
          targetBranch: main
      - uses: argocd-update
        config:
          apps:
          - name: siliconchalet-app-testing
            sources:
            - repoURL: ${REPOSITORY_URL}

Pour l’environnement de testing, pas de grand changement. Celui-ci dépend bien de l’étape précédente development comme indiqué dans le champ sources du bloc requestedFreight. À noter que celui-ci demandera une approbation d’un utilisateur pour faire la modification jusqu’au déploiement de l’environnement.

apiVersion: kargo.akuity.io/v1alpha1
kind: Stage
metadata:
  name: production
  namespace: siliconchalet
spec:
  requestedFreight:
  - origin:
      kind: Warehouse
      name: siliconchalet-app
    sources:
      stages:
      - testing
  promotionTemplate:
    spec:
      steps:
      - uses: git-clone
        config:
          repoURL: ${REPOSITORY_URL}
          checkout:
          - branch: main
            path: ./repo
      - uses: helm-update-image
        as: update-image
        config:
          path: ./repo/values-production.yaml
          images:
          - image: public.ecr.aws/nginx/nginx
            key: image.tag
            value: Tag
      - uses: git-commit
        as: commit
        config:
          path: ./repo
          messageFromSteps:
          - update-image
      # Pushing into a new branch
      - uses: git-push
        as: push
        config:
          path: ./repo
          targetBranch: chore/production/update-image
      # Creating a Pull Request
      - uses: git-open-pr
        as: open-pr
        config:
          provider: github
          repoURL: ${REPOSITORY_URL}
          sourceBranchFromStep: push
          targetBranch: main
      # Waiting until merge
      - uses: git-wait-for-pr
        as: wait-for-pr
        config:
          provider: github
          repoURL: ${REPOSITORY_URL}
          prNumberFromStep: open-pr
      - uses: argocd-update
        config:
          apps:
          - name: siliconchalet-app-production
            sources:
            - repoURL: ${REPOSITORY_URL}

Pour l’environnement de production, c’est assez différent, j’ai choisi d’ouvrir une Pull request pour demander la revue des modifications par plusieurs personnes, et, être sûr des changements appliqués sur ce type d’environnement:

  • git-push : Pousse les changements sur une branche temporaire chore/production/update-image ;
  • git-open-pr : Création automatique d’une Pull Request en spécifiant la branche source et cible ;
  • git-wait-for-pr : Dans cette étape, Kargo va attendre que la Pull Request spécifiée dans le champ prNumberFromStep soit fusionnée pour déclencher la suite, à savoir le déploiement des modifications à travers Argo CD avec l’étape argocd-update.

Voici à l’heure actuelle ce que permet de faire Kargo, c’est assez complet et beaucoup plus avancé que ce que j’avais pu réaliser dans les versions précédentes.

Pour illustrer le tout, voici quelques images des différentes actions.

On commence par la pipeline associée à Kargo :

Une Pipeline sur Kargo

Le mécanisme de promotion peut s’effectuer directement depuis l’interface ou en ligne de commande avec le CLI kargo :

La promotion au sein de Kargo

Comme dit plus haut, la promotion viendra effectuer un commit directement dans votre dépôt de code et aura comme effet de déclencher le déploiement au sein d’Argo CD :

GitHub diff

Voici la nouvelle image déployée avec Argo CD pour l’environnement de testing :

Kargo avec Argo CD

Kargo avec Argo CD, nouvelle image

Pour l’environnement de production, comme vu plus haut, celui-ci ouvre une Pull Request et attend que cette dernière soit validée. C’est ce que l’on peut voir quand on consulte les détails à travers Kargo :

Attente de la validation de la Pull Request

Avec la Pull Request correspondante :

Pull Request

Durant cette phase de validation, Kargo attend, comme le confirme la petite roue crantée qui continue de tourner pour l’environnement concerné :

Environnement de production en attente

Une fois la Pull Request validée, Kargo procédera à la modification de l’image sur l’environnement de production comme ceci :

Environnement de production déployé

Et voilà le travail, vous avez réalisé votre première pipeline avec Kargo, bravo !

Quelques mots pour conclure
#

Plutôt que de bidouiller une chaîne CI/CD à base de diff et de sed pour promouvoir vos changements, Kargo apporte avec lui un manque souvent exprimé quand on parle d’outils GitOps : l’orchestration entre environnements.

Encore une fois, Kargo est encore très jeune, mais je trouve personnellement qu’il a un grand potentiel. Quitte à être, plus tard, indispensable avec toute installation d’Argo CD.

Certaines fonctionnalités importantes ne sont pas encore implémentées comme la gestion des utilisateurs et des rôles, comme le propose Argo CD mais patience, cela ne devrait plus trop tarder.

N’hésitez pas à suivre les versions et mises à jour de Kargo sur le GitHub.

Articles connexes

Approche GitOps avec Flamingo, le meilleur des deux mondes
·8 mins
gitops flamingo flux argocd cd kubernetes
Argo CD, la gestion simplifiée de vos déploiements sur Kubernetes
·7 mins
ci/cd automation code argocd kubernetes docker helm yaml
Mettre à l'échelle facilement sur Kubernetes avec Keda
·7 mins
kubernetes keda yaml rabbitmq scale cron helm