ArgoCD: CICD façon GitOps

Introduction

L’écosystème Kubernetes a toujours été accompagné d’un grand nombre d’outils. Les domaines d’applications sont variés et les choix parfois multiples.

Apparaitre dans le landscape de la CNCF (Cloud Native Computing Foundation), servant désormais de poster à bon nombre de DevOps passionnés (ou de Platform Engineer pour rester à la mode), est devenu gage d’une certaine notoriété et d’une possible adoption par un grand nombre d’IT.

Landscape de la CNCF

Cliquez sur l'image pour l'agrandir.

ArgoCD fait partie des heureuses applications CNCF Graduated au même titre que son principal concurrent FluxCD.

Tous deux fonds partis de la catégorie Continuous integration & Delivery avec comme point commun d’avoir choisi la logique GitOps.

Positionnement de ArgoCD dans le landscape CNCF

Cliquez sur l'image pour l'agrandir.

Le GitOps est une approche de gestion des infrastructures et des applications centrées sur Git.

GitOps

Avec l’explosion du As A Code, certains ont choisi de faire de Git leur source unique de vérité. Cela implique que les états désirés des infrastructures et des applications sont tous versionnés dans des repos git.

Plusieurs avantages découlent de l’adoption de cette stratégie:

  • Déploiement automatique: il devient possible de surveiller les repos et d’enclencher automatiquement des changements dès qu’une modification est détectée.
  • Auditabilité et traçabilité: toutes les modifications sont historisées dans Git, assurant un suivi clair et des capacités de rollback simplifiées.
  • Réconciliation automatique: en comparant en permanence l’état d’un système au contenu d’un repo, il devient possible de corriger les écarts et d’être toujours en cohérence avec un statut décrit sous forme de code.
Illustation du gitops: https://codefresh.io/learn/gitops/

Cliquez sur l'image pour l'agrandir.

Illustation du gitops: https://codefresh.io/learn/gitops/

Cliquez sur l'image pour l'agrandir.

Si vous prenez connaissance de ma définition de Kubernetes, vous devriez comprendre que cette philosophie se prête particulièrement à K8S. En effet l’orchestrateur compare en permanence le statut des conteneurs par rapport a un référentiel donné en s’assurant toujours d’avoir une cohérence entre ce qui est exécuté et ce qui est demandé.

Il était donc logique que dans le cadre de l’adoption de Kubernetes dans mon environnement professionnel, il fallait s’accompagner d’un outil de la sorte pour gérer le déploiement des applications.

Le principe de base derrière l’usage d’un tools orienté gitops avec Kubernetes est de pouvoir avoir une gestion du déploiement de ses objets K8S depuis le cluster directement sans avoir à donner des accès externes à d’autres outils de CICD, comme on avait l’habitude de la faire traditionnellement.

Pas besoin, par exemple, d’avoir un Jenkins à qui on doit fournir un compte de service avec les pleins pouvoirs sur le cluster pour qu’il puisse piloter l’API, et de ce fait amener un risque sur la gestion de ce compte et de l’accès associé.

Avec une approche GitOps, l’outil de déploiement tourne au sein du cluster, surveille des repos et n’applique des modifications sur les objets kub que si des changements sont réalisés dans les sources présentes sur les repos en question.

On peut adopter un principe de pull ou l’on vient chercher les informations de déploiement plutôt qu’un principe de push où l’on envoie les informations.

principe de argocd

Cliquez sur l'image pour l'agrandir.

Bien entendu, cela implique que la plateforme Git devienne extrêmement critique. Elle se doit donc d’être particulièrement suivie, avec une politique de gestion adaptée et sécurisée.

Le choix de ArgoCD c’est principalement fait sur la présence d’une GUI, certes non obligatoire, mais bien utile pour visualiser le statut de ses applications…puis lorsqu’on travaille avec des collègues talentueux on remet rarement leur jugement en question (Aurelien, Nicolas...si vous passez par la 😊).

Le but de cet article est donc de détailler le déploiement d’argoCD au sein d’un cluster K8S, en l’occurrence mon cluster de lab dont je décrie l’installation dans mon cookbook dédié.

ArgoCD est bien entendu open source. Il a d’abord été développé en interne chez Intuit, une entreprise américaine spécialisée dans les logiciels financiers, avant d’être proposé à la communauté en octobre 2018.

Il est distribué depuis sous licence Apache 2.0

Avant d’entrer dans le dur, voici le schéma qui va servir de cible d’architecture.

Schéma cible de la solution

Cliquez sur l'image pour l'agrandir.

Installation de ArgoCD

Déploiement des composants de bases

L’installation d’ArgoCD peut se faire de différentes manières. J’ai retenu la méthode officielle, sans passer par helm. (un repo existe, largement utilisé, mais non directement maintenu par les développeurs principaux de argoCD).

Comme à mon habitude, je préfère dédier un namespace à l’outil en me basant sur ma nomenclature. En l’occurrence je créer un namespace prd-argocd-lan destiné à acceuillir tous les objets K8S nécessaires.

kubectl create namespace prd-argocd-lan
Création du namespace

Cliquez sur l'image pour l'agrandir.

La suite est très simple, puisqu’il suffit d’appeler les yamls présents directement dans le repo du projet en n’oubliant pas de préciser le namespace fraichement créé.

kubectl apply -n prd-argocd-lan -f https://raw.githubusercontent.com/argoproj/argo-cd/stable/manifests/install.yaml
Installation de argoCD

Cliquez sur l'image pour l'agrandir.

On contrôle le tout:.

kubectl get pod -n prd-argocd-lan
Controle de l'installation

Cliquez sur l'image pour l'agrandir.

Plusieurs pods sont déployés gérant chacun un composant de argoCD:

Pod Rôle
argocd-application-controller Surveille et synchronise les applications Argo CD
argocd-applicationset-controller Gère la création dynamique des applications via ApplicationSets
argocd-dex-server Gère l’authentification et l'intégration SSO
argocd-notifications-controller Gère l'envoi de notifications et alertes
argocd-redis Fournit un cache pour optimiser les performances
argocd-repo-server Clone les dépôts Git et génère les manifests Kubernetes
argocd-server argocd-server Fournit l'interface web et l’API Argo CD

Publication de la GUI

Malgré que les pods sont tous up, ce n’est pas fini.

De base, ArgoCD ne fournit pas d’ingress pour rendre accessible la GUI/API à l’extérieur du cluster. Il va donc falloir créer l’objet soit même.

Pour cela on identifie déjà le service (svc) qui va nous intéresser pour faire pointer l’Ingress vers ce dernier.

kubectl get svc -n prd-argocd-lan
Identification du service

Cliquez sur l'image pour l'agrandir.

En l’occurrence c’est le svc argocd-server.

Le yaml 01-ing-argocd-front.yaml associé à l’ingress va donc être le suivant:

  
---
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: ing-argocd-default
  namespace: prd-argocd-lan
  labels:
      environment: prd
      network: lan
      application: argocd
  annotations:
    traefik.ingress.kubernetes.io/router.entrypoints: web,websecure
    ingressClassName: traefik-lan
    traefik.ingress.kubernetes.io/router.tls: "true"
spec:
  ingressClassName: traefik-lan
  tls:
  - hosts:
    - argocd.coolcorp.priv
    secretName: sec-certificate-argocd
  rules:
  - host: argocd.coolcorp.priv
    http:
      paths:
      - path: /
        pathType: Prefix
        backend:
          service:
            name: argocd-server
            port:
              number: 80
---
apiVersion: cert-manager.io/v1
kind: Certificate
metadata:
  name: cert-argocd-front
  namespace: prd-argocd-lan
  labels:
      environment: prd
      network: lan
      application: argocd 
spec:
  dnsNames:
    - argocd.coolcorp.priv
  commonName: argocd.coolcorp.priv
  secretName: sec-certificate-argocd
  privateKey:
    algorithm: RSA
    size: 4096
  issuerRef:
    name: clusterissuer-acme2certifier 
    kind: ClusterIssuer
    

Comme vous le constaterez, j’y intègre la création d’un certificat en deuxième parti du fichier. Je vous invite à suivre mon installation de Cert-Manager et du fonctionnement des ClusterIssuer avec ma PKI interne pour comprendre cette partie du fichier. Cela me permet de générer automatiquement un certificat pour l’URL argocd.coolcorp.priv.

Me concernant j’utilise comme Ingress Controleur, Traefik, et ceci sur une instance en lan. Si tout cela ne vous dit rien, il est préférable de parcourir cette partie de mon cookbook sur les Ingress . Cela vous familiarisera avec les principes associés. Le but étant que depuis l’extérieur, je puisse joindre à la fois la GUI et l’API de ArgoCD. N’hésitez pas à vous référer au schéma d’architecture présent en début d’article.

On applique l’Ingress:

kubectl.exe apply -f 01-ing-argocd-front.yaml
Création de l'ingress et du certificat

Cliquez sur l'image pour l'agrandir.

Malgré que celui-ci soit pris en charge par Traefik, l’accès à ArgoCD n’est toujours pas possible. La faute à sa configuration par défaut qui impose une redirection https en interne et qui entre en conflit avec Traefik et l’ingress associé.

Il faut donc retirer cette redirection en éditant le config map argocd-cmd-params-cm en ajoutant:

  
data:
  server.insecure: "true"
Modification de la configuration de argocd

Cliquez sur l'image pour l'agrandir.

Pour être certains que le paramètre soit pris en compte, on redéploye argocd-server avec la commande:

kubectl rollout restart deployment argocd-server -n prd-argocd-lan

Une fois le pod à nouveau UP, l’interface devrait être accessible, sur l’URL choisie avec le certificat HTTPS provisionné automatiquement.(Tout ce principe est expliqué ici).

Interface de argocd

Cliquez sur l'image pour l'agrandir.

Au premier déploiement, un compte admin avec mot de passe généré aléatoirement est stocké dans un secret.

Pour récupérer son contenu vous pouvez passer directement par la commande suivante (depuis un shell linux par exemple avec WSL).

kubectl -n prd-argocd-lan get secret argocd-initial-admin-secret -o jsonpath="{.data.password}" | base64 -d; echo.
Récupération du mot de passe admin

Cliquez sur l'image pour l'agrandir.

Celle-ci va extraire la valeur en base 64 du password dans le secret pour la convertir en clair dans la foulée.

ArgoCD est bien entendu compatible avec de multiples sources d’authentification, grâce à son composant argocd-dex-server mais je n’irais pas jusque-là dans ce tutoriel d’initiation à ArgoCD.

Accès à la GUI de argocd

Cliquez sur l'image pour l'agrandir.

Accès à la GUI de argocd

Cliquez sur l'image pour l'agrandir.

Gestion des accès pour les comptes de service interne

Il demeure encore d’autres éléments à configurer avant d’aller plus loin: les droits pour les comptes de service utilisés par ArgoCD.

Si grâce à la logique GitOps il n’est pas nécessaire de donner un accès externe au cluster, il faut néanmoins qu’au sein du cluster, ArgoCD puisse piloter les composants et déployer les objets décrits dans les yamls présents au sein des repos.

J’en profite pour indiquer que ArgoCD peut aussi bien traiter des yamls de bases associés aux objets K8S, que du helm ou du Komposer.

Au niveau des droits, on va donc devoir créer deux rôles.

Role pour le sa argocd-application-controller

Le premier pour le déploiement des objets en tant que tel. Forcément il va s’agir d’un rôle avec beaucoup de pouvoir. Pour bien comprendre cette partie, je vous invite à lire mon article sur le fonctionnement de l’authentification et de la notion de RBAC au sein d’un cluster Kub.

Plusieurs stratégies sont possibles, certaines vont réserver argoCD au déploiement d’applications uniquement dans certains namespace, d’autres vont vouloir limiter le type d’objets manipulables ou le type d’actions associées.

Les moins regardants sur la sécurité vont simplement utiliser le rôle par défaut cluster-admin. Avec ce type de role, argoCD pourra accéder à tout et tout faire sans se prendre la tête…je ne dis pas que ce n’est pas bien…je ne dis pas que c’est bien…c’est une question d’acception du risque et de maitrise de sa politique d’accès.

Personnellement, je vais opter pour la création d’un rôle dédié clusterrole-argocd-default mais qui disposera néanmoins d’un accès très large à mon cluster.

Voici le contenu du fichier 02-clusterrole-argocd-default.yaml associé:

 
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
  name: clusterrole-argocd-default
rules:
  # Gestion des ressources de base
  - apiGroups: ["*"]
    resources:
      - "*"
    verbs: ["get", "list", "watch", "create", "patch", "delete"]
  

Comme vous le notez, j’ai été très généreux…mais au moins mon rôle est dédié à argoCD et il me sera plus facile de le faire évoluer au besoin sans toucher aux rôles par défaut du cluster.

On applique le fichier:

kubectl apply -f 02-clusterrole-argocd-default.yaml
Application du role par défault

Cliquez sur l'image pour l'agrandir.

Il va maintenant falloir associer ce rôle au service account argocd-application-controller. Ce compte de service est créé à l’installation de ArgoCD . C’est lui qui est en charge de piloter le déploiement des objets.

Je créer donc un fichier 03-clusterolebinding-argocd-default.yaml pour faire l’association de mon rôle crée pour l’occasion et du compte de service.

 
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
  name: clusterolebinding-argocd-default
roleRef:
  apiGroup: rbac.authorization.k8s.io
  kind: ClusterRole
  name: clusterrole-argocd-default
subjects:
  - kind: ServiceAccount
    name: argocd-application-controller
    namespace: prd-argocd-lan
  

On applique ensuite simplement le fichier:

kubectl apply -f 03-clusterolebinding-argocd-default.yaml
Mappage du compte avec le role

Cliquez sur l'image pour l'agrandir.

Role pour le sa argocd-server

Le second rôle dont on va avoir besoin est dédié à l’interface web. On va pouvoir se permettre d’avoir un rôle plus réduit, avec uniquement des accès en lecture, puisqu’il s’agira juste de permettre à la GUI d’afficher le contenu des objets.

Ce rôle est décrit dans mon yaml 04-clusterrole-argocd-web.yaml:

 
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
  name: clusterrole-argocd-web
rules:
  # Gestion des ressources de base
  - apiGroups: ["*"]
    resources:
      - "*"
    verbs: ["get", "list", "watch"]
  

Il suffit de l’appliquer:

kubectl apply -f 04-clusterrole-argocd-web.yaml
Création du role pour la partie web

Cliquez sur l'image pour l'agrandir.

On va cette fois-ci créer un clusterolebinding mais qu’on va appliquer au compte de service argocd-server.

Voici le contenu de 05-clusterolebinding-argocd-web.yaml:

 
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
  name: clusterolebinding-argocd-web
roleRef:
  apiGroup: rbac.authorization.k8s.io
  kind: ClusterRole
  name: clusterrole-argocd-web
subjects:
  - kind: ServiceAccount
    name: argocd-server
    namespace: prd-argocd-lan
  

On applique avec la commande kubectl apply -f 05-clusterolebinding-argocd-web.yaml

Mappage du compte avec le role pour le web

Cliquez sur l'image pour l'agrandir.

L’installation est désormais terminée.

Demonstration et usage

Nous allons maintenant pouvoir valider l’installation en réalisant un premier cas d’usage.

L’objectif est de pouvoir déployer une application témoin demoargo dans un namespace spécifique dev-demoargo-lan.

L’application est très basique. Elle est constituée uniquement de trois objets Kubernetes (Deployment/Service/Ingress) chacun représenté par un fichier yaml hébergé dans repo gitlab https://gitlab.com/kub.coolcorp.priv/dev-demoargo-lan.

Il faut donc que ArgoCD surveille ce repo puis déclenche le déploiement des différents éléments sur le cluster en fonction des changements réalisés sur les sources.

Pour cela il peut cloner le repo et exécuter les yamls qui s’y trouvent de manière à que la définition des objets représentant l’application témoin soit toujours identique entre le repo et le cluster K8S.

ArgoCD arrive avec ses propres objets, permettant de manipuler la solution directement à base de fichiers yaml sans avoir à utiliser la GUI. Personnellement je réserve cette dernière à un usage de monitoring et de suivi plus qu’à un usage d’administration.

Object AppProject

Le premier objet ArgoCD qui nous intéresse est l’objet AppProject. C’est une entité qui sert à regrouper plusieurs applications à déployer sous une même politique d’accès et de permission. Il permet de:

  • Définir quelles applications peuvent être déployées, sur quels clusters et à partir de quels dépôts Git
  • Limiter l’utilisation de certains types de ressources (interdire par exemple les ClusterRoles)
  • Définir la politique RBAC pour savoir qui peut gérer les applications associées à ce projet.

Dans mon exemple je vais créer un AppProject appproject-demoargo-lan, celui-ci sera limité à l’exploration de mon repo https://gitlab.com/kub.coolcorp.priv/dev-demoargo-lan.

Voici le contenu du fichier 01-appproject-demoargo-lan.yaml:

apiVersion: argoproj.io/v1alpha1
kind: AppProject
metadata:
  name: appproject-demoargo-lan
  namespace: prd-argocd-lan  # Le namespace où ArgoCD est installé
spec:
  description: "Projet demo pour déployer des applications depuis GitLab"
  sourceRepos:
    - git@gitlab.com:kub.coolcorp.priv/dev-demoargo-lan.git  # Limiter aux repos autorisés
  destinations:
    - namespace: '*'
      server: https://kubernetes.default.svc  # Autoriser les déploiements sur ce cluster
  clusterResourceWhitelist:
    - group: "*"
      kind: "*"
  namespaceResourceBlacklist:
    - group: "*"
      kind: "PodExecOptions"  # (Optionnel) Bloquer certains types de ressources

  

J’applique la création de l’AppProject

kubectl apply -f 01-appproject-demoargo-lan.yaml
Application de l'objet AppProject

Cliquez sur l'image pour l'agrandir.

Ajout du repo via la CLI

Si à travers ce fichier, on limite l’AppProject à l’usage du repo de démo, celui-ci n’est pour l’instant pas connu de ArgoCD.

Il va donc falloir l’enregistrer dans ArgoCD, en fournissant les accès associés.

Pour cela, je vais commencer par créer une clef privée à partir d’un outil comme puttygen par exemple. Je vais réserver cette clef privée à ArgoCD. Elle devient par principe extrêmement critique ! Veillez à avoir une politique de gestion appropriée.

Création de la clef privée/clef public pour l'accès au repo

Cliquez sur l'image pour l'agrandir.

Une fois créé, je vais déclarer la clef publique correspondante dans mon compte gitlab pour autoriser l’accès au repo au possesseur de la clef privée.

Intégration de la clef public à GitLab

Cliquez sur l'image pour l'agrandir.

Il reste à renseigner le repo et la clef privée au sein d’ArgoCD.

On va exploiter l’une des secondes façons d’interagir avec ArgoCD après les yamls: la CLI (command line interface).

Vous pouvez télécharger cette dernière sous forme d’un simple exe directement sur le site du projet.

Il faut récupérer le binaire associé à son client. Comme d’autres outils pour K8S, à l’image de velero par exemple, le binaire va se baser sur la configuration de kubectl déployée sur votre poste de travail. Vous pourrez donc utiliser n’importe quels clusters déclarés dans votre fichier. Pour rappel n’hésitez pas à parcourir mon article sur les accès à un cluster Kubernetes pour être à l’aise avec ce point.

Récupération de la CLI

Cliquez sur l'image pour l'agrandir.

Je vous conseille d’ajouter l’exe dans votre path afin de pouvoir l’appeler depuis n’importe quel emplacement.

Binaire de la CLI

Cliquez sur l'image pour l'agrandir.

Il faut d’abord s’authentifier auprès de l’instance argoCD via la commande argocd login url_argo_cd

Authentification avec la CLI

Cliquez sur l'image pour l'agrandir.

Pour la démo, je n’ai pas créé de compte particulier, je vais donc m’appuyer sur le compte admin par défaut utilisé précédemment pour tester l’accès à la GUI.

On peut vérifier qu’on n’est correctement connecté avec la commande:

argocd version
Vérification de la connexion à ArgoCD

Cliquez sur l'image pour l'agrandir.

De là on vient ajouter le repo souhaité:

argocd repo add git@url_repo --ssh-private-key-path path\vers\la_clef_privee --insecure-skip-server-verification --project nom_AppProject
Déclaration du repo à ArgoCD

Cliquez sur l'image pour l'agrandir.

Attention la clef privée doit être au format ssh.

Export au format SSH depuis puttygen

Cliquez sur l'image pour l'agrandir.

L’ AppProject est prêt, le repo est déclaré et ArgoCD dispose des accès nécessaires.

Controle du repo dans la GUI de ArgoCD

Cliquez sur l'image pour l'agrandir.

Object Application

La dernière étape consiste a déclarer le second objet utile à notre démo: l’ Application.

Attention, je parle de l’objet argoCD Application. Son nom est assez parlant puisqu’il représente une application déployée et synchronisée à partir d’un dépôt git.Il défini:

  • La source: où se trouve la configuration
  • La destination: le cluster/namespace ou l’application doit être déployée
  • Le mode de synchronisation: automatique (ArgoCD va régulièrement contrôler le statu du repo) ou manuelle (c’est à l’utilisateur de lancer la synchro)

Voici le contenu de mon fichier 02-app-demoargo-lan.yaml:

apiVersion: argoproj.io/v1alpha1
kind: Application
metadata:
  name: app-demoargo-lan
  namespace: prd-argocd-lan
spec:
  project: appproject-demoargo-lan
  source:
    repoURL: git@gitlab.com:kub.coolcorp.priv/dev-demoargo-lan.git
    targetRevision: HEAD  # Révision ou branche (HEAD, main, etc.)
    path: "."
  destination:
    server: https://kubernetes.default.svc  # Cluster cible
    namespace: dev-demoargo-lan  # Namespace où déployer l'application
  syncPolicy:
    automated:
      prune: true  # Supprime les ressources obsolètes non présentes dans le repo
      selfHeal: true # Corrige les dérives entre le cluster et Git
    syncOptions:
      - CreateNamespace=true  # Créer automatiquement le namespace cible si nécessaire
    

Attention à l’option path. Si vos fichiers sont directement à la racine du repo, il faut bien mettre "." et non laisser l’emplacement vide.

J’applique le fichier: kubectl apply -f 02-app-demoargo-lan.yaml

Déploiement de l'objet Application

Cliquez sur l'image pour l'agrandir.

Résultat et manipulation de la GUI

Immédiatement après ma commande, si l’on regarde la GUI, on va pouvoir observer la création de l’Application avec tout le mécanisme de déploiements des objets de notre démo qui va se mettre en place.

La GUI de ArgoCD est très bien faite à ce niveau. Elle schématise très bien l’application déployée. Il est possible d’explorer chaque objet pour connaitre son contenu et son statut.

Exemple de la vue offerte par la GUI

Cliquez sur l'image pour l'agrandir.

Exploration du contenu d'un objet

Cliquez sur l'image pour l'agrandir.

De même on peut lister tout l’historique des déploiements et suivre les modifications.

historique visible dans la GUI

Cliquez sur l'image pour l'agrandir.

Après quelques minutes seulement, on peut lister les ressources du namespace dev-demoargo-lan.

Namespace que je n’ai pas eu à créer, puisque argoCD l’a fait pour moi.

kubectl get all -n dev-demoargo-lan
Listing de tous les objets

Cliquez sur l'image pour l'agrandir.

Tous les objets sont présents et l’application démo est déployée. ArgoCD a bien fait son travail.

Apparition de l'application dans la GUI

Cliquez sur l'image pour l'agrandir.

Erreur possible sur les ingress

Attention néanmoins, pour certaines configurations comme la mienne, il se peut que l’objet Ingress reste en status processing indéfiniment, alors que l’objet est bien déployé et fonctionnel.

Cela est dû à un souci d’interprétation de l’objet par ArgoCD, l’ingress controler n’appliquant pas un paramètre attendu au niveau de l’option « Status : » dans la définition de l’objet.

J’ai moi-même rencontré ce problème avec Traefik. En l’état, on trouve pas mal de contournement dont vous trouverez une bonne partie de leur description dans ce topic.

Néanmoins dans mon cas, seul l’astuce consistant à modifier la conf de argoCD pour contourner le check par défaut de l’objet Ingress a fonctionné.

Pour cela, il faut éditer la configmap argocd-cm.

kubectl edit configmap argocd-cm -n prd-argocd-lan

Puis ajouter cette configuration dans la section data:

data:
  resource.customizations: |
    networking.k8s.io/Ingress:
      health.lua: |
        hs = {}
        hs.status = "Healthy"
        hs.message = "Skip health check for Ingress"
        return hs

Attention, ce contournement bypass le check de l'état de l'ingress...il peut y'avoir des effets de bord...mais c'est la seule solution trouvée pour l'instant. On peut ensuite relancer le déployement des composants argoCD.

kubectl rollout restart deployment -n prd-argocd-lan argocd-server kubectl rollout restart deployment -n prd-argocd-lan argocd-repo-server

À voir dans votre situation si cette modification est nécessaire ou non.

Synthèse et bilan

Quoiqu’il en soit une fois la première synchro terminée, on peut essayer de la relancer pour forcer ArgoCD à se reconnecter au repo et à comparer le statut des objets.

Tant que rien n’a été modifié à la source, ArgoCD ne fait strictement rien.

Par contre, si on s’amuse par exemple à changer une valeur dans le yaml rattaché au Deployment de notre application témoin, dès qu’on relance une synchro, ArgoCD identifie immédiatement le changement et procède au redéploiement de l’objet pour à nouveau être en conformité avec le contenu du repo.

C’est un concept extrêmement puissant, car vos mises en production reviennent au final à faire des changements dans votre repos. Vos développeurs peuvent gérer directement le déploiement de leur application sans à avoir le moindre accès au cluster Kubernetes.

En jouant avec les objets ArgoCD AppProject/Application, vous pouvez créer des espaces de travail et de déploiement maitrisés, limités à certains repo, à certains objets, à certaines branches.

Pour rappel voici les éléments que nous avons manipulés dans cette démo:

AppProject Application Repo
Définis des règles de gestion pour un ensemble d'applications Définis une application spécifique avec sa source et sa destination Définis le repo git contenant les sources et les accès associés
Contrôle les accès aux dépôts, aux clusters et aux ressources Gère le déploiement d’une application spécifique Gère les accès au repo source
Utilisé pour organiser et sécuriser les applications Utilisé pour synchroniser un déploiement avec Git Utilisé pour les accès au repo source
Manipulé avec un yaml et la branche API argoproj.io/v1alpha1 Manipulé avec un yaml et la branche API argoproj.io/v1alpha1 Manipulé avec la CLI

Déclenchement par webhook

Un dernier point intéressant reste à traiter: le déclenchement automatique par webhook.

En effet dans notre exemple, c’est argoCD qui se connecte au repo soit en forçant la synchro soit en automatisant sa connexion. Par défaut, ArgoCD vérifie les sources toutes les trois minutes.

Maintenant il reste possible avec des solutions comme GitLab de créer un webhook, c’est-à-dire que GitLab est en mesure de prévenir argoCD d’une modification au sein du repo afin que argoCD puisse déclencher une synchronisation.

La méthode peut changer fonction de votre gestionnaire Git, mais la plupart des solutions du marché sont compatible.

Dans le cas de gitlab, il suffit d’aller dans les paramètres du repo et d’activer un webhook.

Activation du webhook dans gitlab

Cliquez sur l'image pour l'agrandir.

De là on indique l’URL à contacter en cas d’action sur le repo.

Configuration du webhook

Cliquez sur l'image pour l'agrandir.

Je ne vais pas rentrer dans le détail, mais dans mon cas c’est un peu spécial. Mon instance argoCD est hébergée dans mon lab en interne, alors que j’utilise Gitlab en cloud.

Pour que GitLab contacte argoCD, il faudrait que j’expose ce dernier sur le web, ce qui n’est pas forcement mon objectif de départ.

C’est un problème courant dans des architectures hybrides ou certains outils onprem doivent être joint par des outils SaaS.

Pour régler cette problématique, il est fortement conseillé de passer par des reverse proxy ou des api gateway chargés de contrôler un minimum les communications entrantes.

Pour mon usage personnel, je ne me suis basé que sur des configurations avancées de Traefik pour limiter les IPs publics autorisées à se connecter (j’ai verrouillé sur les plages d’IP de GitLab Cloud) et mis en place des règles de réécriture pour rediriger le trafic.

En résumé, mon instance argoCD répondant en interne à l’URL argocd.coolcorp.priv est joignable depuis l’extérieur, mais sur l’URL argocd.coolcorp.fr, uniquement depuis les IP publics de GitLab et en passant par une première instance Traefik en DMZ qui renvoie vers ma seconde instance Trafik en LAN en transitant par un firewall. Je ferais sans doute un article dédié à Traefik pour donner différents exemples de ce qu’il est possible de faire avec ce formidable outil…mais ce n’est pas le sujet de ce tutoriel.

Sécurisation de l'exposition de argoCD

Cliquez sur l'image pour l'agrandir.

Ceci m’assure un minimum de sécurité en limitant l’exposition de mon instance ArgoCD tout en m’offrant la capacité d’utiliser l’option webhook de gitlab.

Revenons à cette option justement, comme expliqué juste au-dessus, l’URL que gitlab devra joindre est https://argocd.coolcorp.fr/api/webhook.

Bien entendu, il ne s’agit pas de simplement se présenter à cette URL pour déclencher argoCD, un mécanisme d’authentification est nécessaire sous forme d’un token.

génération du token

Cliquez sur l'image pour l'agrandir.

Celui-ci est libre dans son formalisme, mais je vous conseille de retenir un token complexe. Lorsque gitlab se présentera à ArgoCD il fournira ce token dans les header de la requête dans le champs X-Gitlab-Token (Attention donc aux configurations des reverses proxy éventuels utilisés pour exposer ArgoCD...qui peuvent perdre ce header).

Encore faut-il que ce token soit connu de ArgoCD. Pour ça il faut éditer le secret argocd-secret et l’ajouter sous la forme:

data:
...

  # gitlab webhook secret
  webhook.gitlab.secret: votre_token

Le fait d’utiliser le champ stringData vous n’avez pas à fournir sa valeur en bas64.

Il sera automatiquement converti à l’enregistrement du secret.

Veuillez noter qu’il est possible d’exploiter des secrets distincts si nécessaires.

Côté gitlab, il ne reste plus qu’a indiquer sur quel évènement on souhaite déclencher le webhook et donc prévenir argocd.

En l’occurrence dans la démo ce qui nous intéresse c’est tout ce qui va concerner les push.

Il est possible de tester le webhook pour s’assurer que tout est OK et que Gitlab communique bien avec ArgoCD.

Si telle est le cas, il ne reste plus qu’a faire le test final.

On modifie en local un des fichiers associés à notre application démo, on push notre modification sur le repo…et immédiatement après argoCD se déclenche, détecte la mise à jour du composant et le redéploie.

Push d'une modification

Cliquez sur l'image pour l'agrandir.

La synchro se lance

Cliquez sur l'image pour l'agrandir.

Conclusion

Lorsqu’on exploite une plateforme Kubernetes, adopter une stratégie GitOps à travers des outils comme ArgoCD est un choix extrêmement pertinent pour gérer le déploiement continu de ses applications.

ArgoCD est un outil reconnu, fiable et disposant d’une GUI convivial pour suivre le statut de ses déploiements.

Il serait dommage de passer à côté de ce type d’architecture. Au-delà de l’outil, c’est la logique GitOps qu’il est pertinent de retenir . GitOps peut s’appliquer à d’autre écosystème que Kubernetes et peut être la stratégie par défaut retenu dans un IT. À chacun de voir quelle implémentation il décide de choisir, l’important dans le CICD étant toujours de comprendre ce que l’on fait et pourquoi on le fait.