ArgoCD et Helm : Gestion des values privées pour des charts externes
ArgoCD et Helm : Gestion des values privées pour des charts externes

ArgoCD et Helm : Gestion des values privées pour des charts externes

Contexte et problématique

Kubernetes utilise un format simple, le YAML, pour configurer le déploiement des différents objets qui composent une application. Mais la gestion des différents fichiers YAML de plusieurs applications devient vite une usine à gaz car leur modification devient coûteuse et fastidieuse, surtout pour suivre l'évolution des API des objets Kubernetes.

Pour résoudre cette problématique, il y a eu l'apparition du Kustomize avec son système de base commune et d’overlays avec des patchs pour chaque environnement. Cette solution permet d'éviter la duplication des configurations, mais il ajoute un couplage fort entre les environnements de déploiement d’une application donnée.

Au contraire, Helm s’utilise comme gestionnaire de parquets (package manager) pour Kubernetes, comme cela se fait pour les langages de programmation. Avec son système de templating et values, il permet d'avoir une factorisation des configurations et une indépendance entre les environnements. Ci-dessous une illustration pour une installation avec séparation des fichiers values (pour plus de détails sur je vous invite à regarder le site web helm) :

  • helm upgrade -i app_release helm_repo/helm_chart --version chart_version -f values_DEV.yaml -n app_namespace
  • helm upgrade -i app_release helm_repo/helm_chart --version chart_version -f values_QA.yaml -n app_namespace
  • helm upgrade -i app_release helm_repo/helm_chart --version chart_version -f values_PROD.yaml -n app_namespace

On a ainsi une solution qui nous permet de déployer et faire évoluer une application sur chacun des environnements de façon indépendante.

Mais il reste à industrialiser le déploiement de ces applications de façon automatique au moyen d’un système de CI/CD.

Dans cet article nous allons utiliser la solution GitOps ArgoCD qui permet de synchroniser la configuration de l'application, depuis un dépôt git vers un cluster Kubernetes.

Ci-dessous l'architecture de l’Argo CD :

image

Source : https://argo-cd.readthedocs.io/en/stable/assets/argocd_architecture.png

ArgoCD supporte plusieurs manières de définir les manifestes Kubernetes, Helm inclus. Mais attention : les versions antérieures à 2.6.0 exigent que les fichiers values soient dans le même dépôt Git que le chart.

apiVersion: argoproj.io/v1alpha1
kind: Application
metadata:
  name: my-app
  namespace: argocd
spec:
  destination:
    namespace: my-app-namespace
    server: https://kubernetes_server_endpoint
  project: argocd-project
  source:
    chart: helm_chart
    helm:
      valueFiles:
        - values.yaml #Fichier values doit exister dans le repo du chart
    repoURL: https://helm_repo_url
    targetRevision: chart_version

Cette limitation pose un souci pour les charts externes qu’on ne gère pas mais qu’on voudrait personnaliser au moyen de valeurs privées.

Pour résumer, on va illustrer le besoin dans le schéma suivant :

image

On va voir les différentes solutions possibles pour répondre à ce besoin et voir les caractéristiques de chacune.

Solution 1 : Clone de la chart externe

Cette solution consiste à cloner le dépôt chart externe dans dépôt privé et ajouter les fichiers values des ENVs dans ce dépôt cloné.

Par contre, cette solution pose pas mal de points de blocage, à savoir :

  • La maintenance et la mise à jour des modifications du dépôt original deviennent difficiles voir ingérables avec le temps.
  • Le dépôt de conf devient décentralisé, il faudra donc avoir pour chaque chart un dépôt Git dédié.
  • Un releasing en plus à gérer pour le dépôt cloné
  • Le mélange entre chart (dev) et values (conf) qui empêche sa réutilisation pour autres projets

Solution 2 : Helm Dependency

Cette solution consiste à créer un chart privée qui dépend du chart externe en utilisant le mécanisme de dépendance de Helm.

Ci-dessous un bout de conf pour déclarer la dépendance d’un chart externe :

# Chart.yaml
dependencies:
- name: app1
  version: "chart_version"
  repository: "https://public_repo_URL/app1"

Et comme pour la première solution, il faut ajouter les fichiers values des ENVs dans le repo privé.

Cette solution a un gros avantage sur celle du clone : il est plus facile de suivre les évolutions du dépôt distant, car il suffit de changer la version dans la configuration des dépendances pour être à jour.

Mais elle a aussi quelques inconvénients, à savoir :

  • Décentralisation des repos de conf comme la solution du clonage précédente.
  • Chart passe-plat et mélange entre chart et values.
  • Releasing à gérer pour le repo privé.
  • Gérer les authentifications pour les dépôts dependencies est difficile dans ArgoCD.

Solution 3 : kustomize helmCharts

Kustomize offre une fonctionnalité, via le champ helmCharts, pour permettre de générer  des manifestes à partir d'une chart Helm en passant un fichier value, comme indiqué dans l'extrait de configuration kustomize suivant :

apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization
helmCharts:
- name: chart_name
  includeCRDs: true
  namespace: my-app-namespace
  valuesFile: values.yaml
  releaseName: release_name
  version: chart_version
  repo: https://helm_repo_url

L’avantage de cette méthode est qu’il n'y aura pas besoin de dépôt en plus pour héberger le chart. Mais malheureusement, le support des fonctionnalités Helm est très limité, par exemple l’usage des plugins Helm (comme celui de gestion des secrets), ou la gestion d’authentification pour des dépôts Helm distants.

Solution 4 : Helm-git plugin

Helm possède un système de plugins pour étendre ses fonctionnalités, sans avoir à modifier son code source. Parmi la liste des plugins on trouve Helm-git qui permet de récupérer les fichiers de values directement d’un dépôt GIT (privé ou public). Ce plugin se base sur la config Git pour l’authentification et supporte donc les protocoles SSH et HTTP selon les formes suivantes :

  • HTTP: git+https://[provider.com]/[user]/[repo]@[path/to/charts][?[ref=git-ref][&sparse=0][&depupdate=0]]
  • SSH: git+ssh://git@[provider.com]/[user]/[repo]@[path/to/charts][?[ref=git-ref][&sparse=0][&depupdate=0]]

Ci-dessous l’utilisation de ce plugin au niveau de la représentation (CRD) d’une application au  niveau Argo CD.

apiVersion: argoproj.io/v1alpha1
kind: Application
metadata:
  name: my-app
  namespace: argocd
spec:
  destination:
    namespace: my-app-namespace
    server: https://kubernetes_server_endpoint
  project: argocd-project
  source:
    chart: helm_chart
    helm:
      valueFiles:
      - git+ssh://git@githost.com/repo_uri/@path/to/values.yaml?ref=git-ref # référencement absolu du values.yaml dans un dépôt git
    repoURL: https://helm_repo_url
    targetRevision: chart_version

Cette solution a comme prérequis l’installation du plug-in helm-git dans argoCD en personnalisant l’image Docker de base ou avec l’ajout d’un initContainer, et d’avoir fait le nécessaire pour configurer l’authentification Git au niveau argoCD.

Globalement, cette solution répond au besoin avec modification acceptable au niveau argo CD (installation du plug-in et configuration de l’authentification Git).

Elle tourne déjà en production chez l’un de nos clients avec une gestion de plus 1000 applications.

Solution 5 : Utilisation multi-sources

La version 2.6.0 d’argoCD introduit la possibilité d’avoir des multi-sources au niveau de représentation (CRD) d’une application, ce qui répond pleinement à la problématique de gestion des values privées pour des charts externes.

Ci-dessous la représentation de notre application en utilisant cette fonctionnalité :

apiVersion: argoproj.io/v1alpha1
kind: Application
metadata:
  name: my-app
  namespace: argocd
spec:
  destination:
    namespace: my-app-namespace
    server: https://kubernetes_server_endpoint
  project: argocd-project
  sources:
  - chart: helm_chart
    helm:
      valueFiles:
      - $values_repo/path/to/values.yaml?ref=git-ref
    repoURL: https://helm_repo_url
    targetRevision: chart_version
  - ref: values_repo
    repoURL: git+ssh://git@githost.com/vaules_repo_uri/
    targetRevision: git_ref

Comme on peut le constater, cette solution apparaît comme la solution idéale car elle répond à la problématique.

Mais elle est toujours en bêta (jusqu'à la date de création de cet article) et elle n’est valable que pour les installations d’argoCD en version 2.6.0 et plus.

Pour résumer

Si vous avez une installation d’argoCD avec une version inférieure à 2.6.0, je vous recommande la solution 4.

Mais à partir de la 2.6.0, il faut garder la solution 4 pour les déploiements en production, et expérimenter la solution 5 dans vos environnements hors production jusqu’à jusqu'à sa stabilisation.

Merci pour votre lecture. Cet article vous a plu ? Partagez le sur vos réseaux 😉

Abdelouahab EL OUAZZANY - Mai 2023

image