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 :
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.
Voici le déroulement des opérations dans l’ordre :
- La CI, quelle que soit la plateforme, crée une nouvelle image de conteneur ;
- Cette dernière est déposée dans un registre de conteneurs ;
- 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 ;
- 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 ;
- Une fois la validation du développeur, Kargo pousse les modifications dans Git ;
- 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 ;
- Argo CD synchronise les changements sur le cluster Kubernetes ;
- Kargo récupère l’état des objets déployés et permet d’effectuer des tests ;
- 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 :
Kargo demo for the Silicon Chalet Meetup
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 scriptkargo-demo.sh
et doit contenir le labelkargo.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 branchemain
dans le répertoirerepo
;helm-update-image
: On indique ici le fichiervalues
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 temporairechore/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 champprNumberFromStep
soit fusionnée pour déclencher la suite, à savoir le déploiement des modifications à travers Argo CD avec l’étapeargocd-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 :
Le mécanisme de promotion peut s’effectuer directement depuis l’interface ou en ligne de commande avec le CLI 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 :
Voici la nouvelle image déployée avec Argo CD pour l’environnement de testing :
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 :
Avec la Pull Request correspondante :
Durant cette phase de validation, Kargo attend, comme le confirme la petite roue crantée qui continue de tourner pour l’environnement concerné :
Une fois la Pull Request validée, Kargo procédera à la modification de l’image sur l’environnement de production comme ceci :
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.