Skip to main content

De l'artisanat à l'industrialisation : GitOps multi-env avec Argo CD et Kustomize sur MicroK8s

Posted on:  at 
DevOps & Développement
Picture

🌍 Contexte : Pourquoi ce projet ?

Ce projet est le prolongement logique d'une démarche amorcée plusieurs mois auparavant. Initialement, mon infrastructure était gérée de façon artisanale : quelques fichiers Kubernetes posés dans un repository, un Ingress pour gérer le trafic entrant, un certificat Let’s Encrypt, un déploiement de mon app exposée en interne via un service ClusterIP, ainsi qu'un NodePort pour l'exposition externe.

Mais rapidement, cette approche a montré ses limites :

  • Pas de gestion multi-environnement

  • Pas de vision d'ensemble de l'état du cluster

  • Mises à jour via pipelines mais limitées (uniquement création ou mise à jour de ressources, le reste devant se faire manuellement), sans historique clair

Je voulais un setup plus robuste, plus proche de ce qui se fait en entreprise : versionnement complet de l'infrastructure, déploiement multi-env, GitOps, monitoring plus complet (traces, logs) et sécurité.


🚀 Objectifs techniques

Ce nouveau projet vise à construire une base solide et maintenable pour déployer n'importe quelle application dans un cluster Kubernetes auto-hébergé. Les piliers :

  • GitOps avec Argo CD pour des déploiements déclaratifs

  • Multi-environnement (dev, staging, prod...) via kustomize

  • Certificats TLS gérés automatiquement par cert-manager

  • Ingress NGINX pour l'exposition publique en HTTPS

  • Versionnement complet de l'infra : Ingress, Cert-Manager, Argo CD sont installés via Helm, mais pilotés via Kustomize

  • Namespace par environnement


📊 Stack technique

  • MicroK8s : Kubernetes local optimisé

  • Helm : gestionnaire de chart pour l'installation d'outils comme Argo CD, cert-manager, ingress-nginx

  • Kustomize : overlay d'environnements (dev, prod)

  • Argo CD : moteur GitOps pour le déploiement continue

  • cert-manager + ClusterIssuer Let's Encrypt : certificats TLS publics


📂 Organisation du repo

Le repository est structuré comme suit :

.
├── environments/
│   ├── dev/         # Déploiement dédié au développement
│   ├── staging/     # Environnement de préproduction
│   └── prod/        # Production simulée
├── base/            # Composants K8s communs à tous les environnements

Chaque outil est installé via Helm avec un values.yaml versionné, et les environnements dev/, staging/ et prod/ sont des overlays Kustomize avec des patchs ciblés.

Le repo est disponible ici : github.com/Wooulf/devops-bootcamp-ippon.


⚙️ Installation d'Argo CD avec HTTPS

Argo CD a été installé via Helm dans le namespace argocd, avec cette configuration :

global:
  domain: argocd.woulf.fr

configs:
  params:
    server.insecure: "true"

server:
  certificate:
    enabled: true
    secretName: argocd-tls
    domain: argocd.woulf.fr
    issuer:
      group: cert-manager.io
      kind: ClusterIssuer
      name: letsencrypt-prod

  ingress:
    enabled: true
    ingressClassName: nginx
    annotations:
      nginx.ingress.kubernetes.io/backend-protocol: "HTTP"
    hosts:
      - argocd.woulf.fr
    tls:
      - hosts:
          - argocd.woulf.fr
        secretName: argocd-tls

Pourquoi server.insecure: true ? Car la terminaison TLS est gérée au niveau de l'Ingress. Le trafic interne reste en HTTP, ce qui est acceptable dans un cluster local/VPS non mutualisé.


🌐 Accès public via Ingress

Le certificat TLS est généré automatiquement par cert-manager à partir du ClusterIssuer letsencrypt-prod. Argo CD est maintenant accessible publiquement via https://argocd.woulf.fr.


📁 Premier déploiement avec Argo CD

Le déploiement du portfolio se fait via un Application Argo CD pointant vers le namespace dev. L'Ingress est patché dynamiquement pour chaque environnement via un fichier JSON Kustomize :

environments/dev/kustomization.yaml

namespace: dev
resources:
  - ../../base
patches:
  - path: patch-ingress-host.json
    target:
      kind: Ingress
      name: portfolio-ingress

environments/dev/patch-ingress-host.json

[
  {
    "op": "replace",
    "path": "/spec/tls/0/hosts/0",
    "value": "dev.woulf.fr"
  },
  {
    "op": "replace",
    "path": "/spec/rules/0/host",
    "value": "dev.woulf.fr"
  }
]

🧠 Définition de l'Application Argo CD

Pour connecter Argo CD à mon dépôt Git et lui indiquer quoi synchroniser dans le cluster, j'ai créé une ressource Kubernetes de type Application :

apiVersion: argoproj.io/v1alpha1
kind: Application
metadata:
  name: portfolio-dev
  namespace: argocd
spec:
  project: default
  source:
    repoURL: https://github.com/Wooulf/devops-bootcamp-ippon
    targetRevision: HEAD
    path: environments/dev
  destination:
    server: https://kubernetes.default.svc
    namespace: dev
  syncPolicy:
    automated:
      prune: true
      selfHeal: true
    syncOptions:
      - CreateNamespace=true

🔍 Comment ça fonctionne

  1. source.repoURL + path + targetRevision
    Argo CD surveille le répertoire environments/dev du dépôt Git https://github.com/Wooulf/devops-bootcamp-ippon. Toute modification (commit, push) dans ce dossier déclenche une synchronisation automatique.

  2. destination
    L’application est déployée dans le cluster local (MicroK8s) via l’URL https://kubernetes.default.svc, dans le namespace dev.

  3. syncPolicy.automated

    • automated: synchronisation automatique sans action manuelle.
    • prune: suppression des ressources obsolètes qui ne sont plus déclarées dans Git.
    • selfHeal: restauration automatique si une ressource est modifiée manuellement dans le cluster.
  4. syncOptions.CreateNamespace=true
    Le namespace dev est créé automatiquement s’il n’existe pas encore, rendant le déploiement autonome et idempotent.

🔁 Résultat final

  • Déploiement GitOps complet et automatique dans l’environnement dev
  • Conformité assurée en permanence entre Git et le cluster
  • Mise à jour ou suppression de ressources pilotée uniquement depuis le dépôt Git
  • Namespace dev créé dynamiquement sans préconfiguration manuelle

Le portfolio dev est maintenant déployé automatiquement avec la dernière image Docker taggée latest, et accessible via https://dev.woulf.fr.


🧨 Problèmes rencontrés (et résolus)

  • Certificats auto-signés persistants : dus à un conflit entre plusieurs objets Certificate, causé par la présence d’annotations cert-manager.io/cluster-issuer sur l’Ingress et une section server.certificate dans les values.yaml. 👉 Solution : ne garder que la config server.certificate.

  • Certificat temporaire utilisé même après provisionnement Let's Encrypt : comportement par défaut de cert-manager. Il faut juste patienter que le bon cert soit émis.

  • microk8s qui "perd" les addons (helm, dns, etc.) après reboot : nécessité de relancer les activations.

  • ClusterIssuer non appliqué après reboot : il faut le re-pusher si non persisté.

  • Erreurs d’accès HTTPS alors que tout semblait bon : souvent liées au certificat temporaire ou à une mauvaise terminaison TLS (que j'ai arrêté à l'ingress après coup).

Ces problématiques m'ont aussi amené à réfléchir à l'intérêt d'introduire un outil comme Ansible en complément d'Argo CD. Là où Argo veille à la conformité du state Kubernetes avec les manifests Git, Ansible pourrait m'aider à m'assurer que l'état global du système hôte (MicroK8s, add-ons actifs, prérequis réseau, etc.) est également conforme à mes attentes.


🧾 En résumé

Dans cet article, j’ai amorcé la transition vers une infrastructure GitOps multi-environnement, avec :

  • L’installation d’Argo CD via Helm dans un namespace dédié

  • La gestion du HTTPS avec cert-manager et un ClusterIssuer Let’s Encrypt

  • La résolution de problèmes classiques liés aux certificats (self-signed, temporaires, double création de certificat)

  • L’exposition d’Argo CD en HTTPS via Ingress NGINX

  • Le premier déploiement GitOps d’une application (portfolio) dans l’environnement dev, patché dynamiquement via kustomize


🔜 À venir dans le prochain article

On poursuivra en intégrant Argo CD Image Updater pour assurer la mise à jour automatique des images déployées, en ajoutant une couche de sécurité avec SealedSecrets pour protéger le token d'API permettant d'interagir avec Argo CD. On verra aussi comment rendre ce système autonome, sans intervention manuelle, toujours dans une logique GitOps.