Paul Brissaud

GitOps sur Kubernetes avec ArgoCD et Kapitan

Devops

#Argocd#Kapitan#Kubernetes#Gitops

Source photo : Unsplash

Le déploiement d'applications sur Kubernetes peut être une tâche complexe et exigeante, surtout lorsqu'il s'agit de gérer des environnements de production avec de multiples microservices et des déploiements fréquents. Face à ces défis, les outils GitOps ont émergé comme une solution prometteuse pour faciliter la gestion du cycle de vie des applications et de l'infrastructure Kubernetes. En adoptant cette méthodologie, les opérations deviennent plus automatisées, plus transparentes et reproductibles, offrant aux équipes informatiques un moyen efficace de déployer et de gérer leurs applications dans divers environnements.

Dans cet article, nous explorerons deux outils populaires, ArgoCD et Kapitan, et verrons comment leur combinaison permet de simplifier le déploiement d'applications sur Kubernetes en suivant l'approche GitOps.

Le problème avec ArgoCD

 

En réalité, il n'y en a pas ! ArgoCD est un excellent outil GitOps pour automatiser le déploiement d'applications Kubernetes à partir d'une source de vérité : un référentiel Git ou des charts Helm. Le problème ne réside pas dans ArgoCD lui-même, mais plutôt dans ce qui se trouve dans cette source de vérité : des fichiers YAML, Kustomize ou des charts Helm.

Je m’explique.

Bien que les manifestes statiques (YAML ou JSON) soient couramment utilisés pour décrire les configurations Kubernetes, ils peuvent poser des problèmes lorsqu'ils sont utilisés avec GitOps. Ils peuvent contenir des informations sensibles telles que des clés d'API ou des mots de passe, ce qui peut représenter un risque de sécurité potentiel pour votre infrastructure. De plus, la maintenance des fichiers YAML peut devenir complexe, surtout lorsque différentes configurations sont nécessaires entre les environnements. Cela peut entraîner la duplication de fichiers ou de dossiers, rendant la gestion des configurations fastidieuse et sujette aux erreurs.

“Oui mais Helm existe !”

Helm est une solution populaire pour la gestion des applications Kubernetes, mais elle présente également quelques inconvénients. La gestion en parallèle de plusieurs fichiers values.yaml pour maintenir différents environnements peut être problématique, car il faut veiller à maintenir leur cohérence, ce qui peut entraîner des erreurs. L’utilisation de charts Helm officiels peut également poser des problèmes, car elles ne couvrent pas toujours vos besoins et les modifications peuvent compliquer le processus de mise à jour. Enfin, la gestion des secrets reste une préoccupation, car il n'est pas toujours facile de garder un référentiel Git propre et dépourvu d'informations sensibles.

 

Y-a-t-il un capitaine à la barre ?

Maintenant que nous avons exploré ArgoCD et les défis liés aux outils existants, il est temps de découvrir comment Kapitan peut résoudre ces problèmes et apporter une nouvelle dimension à votre workflow GitOps.

Le principal atout de Kapitan réside dans sa capacité à éliminer la duplication des données de configuration en les centralisant dans un unique emplacement appelé "inventaire". Cette approche permet d'avoir une vue d'ensemble claire des configurations et facilite leur accès à travers différents outils et langages grâce à l'intégration de Kapitan avec jsonnet, kadet, jinja et Helm.

Le Jsonnet est une extension de JSON qui offre une syntaxe plus flexible et des commentaires pour faciliter la rédaction par les humains. En plus des fonctionnalités de JSON, Jsonnet propose des constructions supplémentaires pour générer, traduire et améliorer les données.

Pour illustrer l'utilisation de Kapitan avec jsonnet, prenons l'exemple concret d'un déploiement de base d’un service Web (Nginx). On part d’un manifest assez simple, puis on insère quelques variables (le tag de l’image, le nombre de replicas et le namespace) venant de l’inventaire Kapitan permettant de le modifier selon nos besoin :

local kap       = import "lib/kapitan.libjsonnet";
local inv       = kap.inventory();
local name      = "my-service";
local namespace = inv.parameters.namespace;
local replicas  = inv.parameters[name].replicas;
local image     = if std.objectHas(inv.parameters[name], 'version') then 'nginx:' + inv.parameters[name].version else 'nginx' ;

{
  "apiVersion": "apps/v1beta1",
  "kind": "Deployment",
  "metadata": {
    "name": name,
    "namespace": namespace
  },
  "spec": {
    "replicas": replicas,
    "template": {
      "metadata": {
        "labels": {
          "app": name
        }
      },
      "spec": {
        "containers": [
          {
            "image": image ,
            "name": name,
          }
        ]
      }
    }
  }
}
Composant Jsonnet

Il suffit ensuite de déclarer une classe associé à ce composant pour permettre de faire le lien entre Kapitan et le jsonnet. On peut aussi y initialiser quelques variables.

parameters:
  my-service:
     replicas: 1
  kapitan:
    compile:
      - output_path: my-service
        input_type: jsonnet
        output_type: json
        input_paths:
          - components/my-service.jsonnet
Fichier de classe

Et puis maintenant, il suffit d’inclure cette classe dans l’environnement voulu (appelé ”target”) et on peut surcharger les variables de classe !

classes:
- my-service

parameters:
  target_name: my-env
  namespace: dev
  my-service:
    replicas: 2
    version: 1.24.0
Fichier d’environnement

Il suffit de compiler cet environnement nommé “my-env” avec la CLI de Kapitan et hop notre manifeste est généré !

{
  "apiVersion": "apps/v1beta1",
  "kind": "Deployment",
  "metadata": {
    "name": "my-service",
    "namespace": "dev"
  },
  "spec": {
    "replicas": "2",
    "template": {
      "metadata": {
        "labels": {
          "app": "my-service"
        }
      },
      "spec": {
        "containers": [
          {
            "image": "nginx:1.24.0" ,
            "name": "my-service",
          }
        ]
      }
    }
  }
}
Manifeste généré

Vous pouvez aussi créer des bibliothèques jsonnet ou en utiliser ( comme kube-libsonnet ou tanka). Elles vous permettent de gagner du temps et de rationaliser le développement de vos configurations. Kapitan propose également des générateurs pour faciliter la création de configurations Kubernetes hautement modulaires et réutilisables. En combinant ces générateurs avec les bibliothèques jsonnet, vous pouvez créer des configurations complexes de manière plus efficace et intuitive.

De plus, en ce qui concerne la gestion des secrets, Kapitan prend également en charge différents backends de gestion de secrets, tels que Vault ou Google Cloud KMS. Cela vous permet de garder votre référentiel GitOps propre et dépourvu d'informations sensibles, tout en garantissant une sécurité renforcée pour vos déploiements.

Les deux outils combinés

Maintenant que nous avons exploré en détail les capacités de Kapitan, voyons comment ce dernier s'intègre parfaitement avec ArgoCD pour former un workflow GitOps complet pour la gestion des applications Kubernetes.

L'approche recommandée par les créateurs de Kapitan consiste à lancer une compilation à chaque changement effectué sur le référentiel Git sans révéler les secrets, puis à stocker les manifestes résultants dans un dossier séparé. Ce processus permet de visualiser clairement les différences entre les versions et de vérifier la validité des manifestes avant leur déploiement. En automatisant ces étapes dans votre infrastructure d'intégration continue (CI), vous pouvez intégrer des vérifications directement dans les Pull Requests pour garantir une gestion cohérente et sécurisée des configurations.

Pour permettre à ArgoCD de dévoiler des secrets lorsqu’ils sont nécessaires dans vos manifestes, il est possible de créer un plugin personnalisé. En créant une image Docker contenant Kapitan et les autres outils nécessaires, vous pouvez déployer cette image en tant que conteneur sidecar du repo-server d'ArgoCD. Les étapes détaillées pour la création de ce plugin sont bien expliquées dans cette documentation.

Une fois les manifestes générés par Kapitan, il vous suffit de déclarer une application ArgoCD pour déployer ces derniers. En indiquant le dossier contenant les manifestes dans votre référentiel Git, ArgoCD peut automatiser le déploiement sur vos différents environnements.

Conclusion

En conclusion, la fusion de Kapitan et ArgoCD représente une approche GitOps puissante et efficace pour la gestion des applications Kubernetes. Avec Kapitan pour centraliser les configurations et sécuriser l'accès aux données, ainsi qu'ArgoCD pour automatiser les déploiements, vous créez un workflow harmonieux et fiable.

Chaque modification apportée à la source de vérité peut être soigneusement analysée avant d'être automatiquement déployée sur vos environnements, renforçant ainsi la cohérence et la fiabilité de vos déploiements.

Alors, qu'attendez-vous ? Prenez le gouvernail avec Kapitan et ArgoCD et profitez des avantages d'un workflow GitOps bien maîtrisé ! Bon déploiement !