Comprendre le Custom Tooling dans Argo CD

Comprendre le Custom Tooling dans Argo CD

Après un certain temps après avoir écrit le premier article, où je manipule habilement jsonnet et GitLab, j'ai réalisé que les pipelines, c'est bien, mais excessivement compliqués et peu pratiques.

Dans la plupart des cas, il faut une tâche standard : "générer YAML et le placer dans Kubernetes". Argo CD s'en charge très bien.

Argo CD permet de connecter un dépôt Git et de synchroniser son état dans Kubernetes. Par défaut, il prend en charge plusieurs types d'applications : Kustomize, charts Helm, Ksonnet, Jsonnet brut ou simplement des répertoires contenant des manifests YAML/JSON.

La plupart des utilisateurs de cet ensemble seront satisfaits, mais pas tous. Pour satisfaire les besoins de chacun, Argo CD permet d'utiliser des outils personnalisés.

Je suis principalement intéressé par la possibilité d'ajouter le support de qbec et git-crypt, qui ont été pleinement abordés dans l'article précédent.

Avant de commencer la configuration, il faut d'abord comprendre comment fonctionne Argo CD.

Pour chaque application ajoutée, il y a deux phases :

  • init — préparation initiale avant le déploiement, ici tout peut se produire : téléchargement des dépendances, décompression des secrets, etc.
  • generate — exécution de la commande de génération des manifests, la sortie doit être un flux YAML valide, c'est exactement ce qui sera appliqué dans le cluster.

Il est à noter qu'Argo applique cette approche à tout type d'applications, y compris pour Helm. Ainsi, dans Argo CD, Helm ne se charge pas du déploiement des releases dans le cluster, il est uniquement utilisé pour générer des manifests.

De son côté, Argo sait gérer nativement les hooks Helm, ce qui permet de ne pas perturber la logique d'application des releases.

QBEC

Qbec permet de décrire facilement les applications à l'aide de jsonnet, et en plus, il a la capacité de rendre des charts Helm. Comme Argo CD sait gérer correctement les hooks Helm, utiliser cette fonction avec Argo CD permet d'obtenir des résultats encore plus précis.

Pour ajouter le support de qbec dans argocd, deux choses sont nécessaires :

  • dans la configuration d'Argo CD, votre plugin personnalisé et les commandes pour générer des manifests doivent être définis.
  • Les binaires nécessaires doivent être disponibles dans l'image argocd-repo-server.

Le premier problème se résout assez facilement :

# cm.yaml
data:
  configManagementPlugins: |
    - name: qbec
      generate:
        command: [sh, -xc]
        args: ['qbec show "$ENVIRONMENT" -S --force:k8s-namespace "$ARGOCD_APP_NAMESPACE"']

(la commande init n'est pas utilisée)

$ kubectl -n argocd patch cm/argocd-cm -p "$(cat cm.yaml)"

Pour ajouter des binaires, il est proposé de compiler une nouvelle image, ou utiliser un truc avec un conteneur init:

# deploy.yaml
spec:
  template:
    spec:
      # 1. Define an emptyDir volume which will hold the custom binaries
      volumes:
      - name: custom-tools
        emptyDir: {}
      # 2. Use an init container to download/copy custom binaries into the emptyDir
      initContainers:
      - name: download-tools
        image: alpine:3.12
        command: [sh, -c]
        args:
        - wget -qO- https://github.com/splunk/qbec/releases/download/v0.12.2/qbec-linux-amd64.tar.gz | tar -xvzf - -C /custom-tools/
        volumeMounts:
        - mountPath: /custom-tools
          name: custom-tools
      # 3. Volume mount the custom binary to the bin directory (overriding the existing version)
      containers:
      - name: argocd-repo-server
        volumeMounts:
        - mountPath: /usr/local/bin/qbec
          name: custom-tools
          subPath: qbec
        - mountPath: /usr/local/bin/jsonnet-qbec
          name: custom-tools
          subPath: jsonnet-qbec

$ kubectl -n argocd patch deploy/argocd-repo-server -p "$(cat deploy.yaml)"

Voyons à quoi ressemblera le manifeste de notre application :

apiVersion: argoproj.io/v1alpha1
kind: Application
metadata:
  name: qbec-app
  namespace: argocd
spec:
  destination:
    namespace: default
    server: https://kubernetes.default.svc
  project: default
  source:
    path: qbec-app
    plugin:
      env:
        - name: ENVIRONMENT
          value: default
      name: qbec
    repoURL: https://github.com/kvaps/argocd-play
  syncPolicy:
    automated:
      prune: true

Dans la variable ENVIRONMENT nous passons le nom de l'environnement pour lequel nous devons générer les manisfestes.

appliquons et voyons ce que nous avons obtenu :

Comprendre le Custom Tooling dans Argo CD

l'application est déployée, excellent !

git-crypt

Git-crypt permet de configurer un chiffrement transparent du dépôt. C'est un moyen simple et sécurisé de stocker des données sensibles directement dans git.

Avec l'implémentation de git-crypt, cela s'est avéré plus compliqué.

Théoriquement, nous pourrions exécuter git-crypt unlock à l'étape init de notre plugin personnalisé, mais ce n'est pas très pratique, car cela ne permettrait pas d'utiliser les méthodes de déploiement natives. Par exemple, dans le cas de Helm et Jsonnet, nous perdons l'interface graphique flexible qui simplifie la configuration des applications (fichiers values et autres).

C'est pourquoi nous souhaitions effectuer le déchiffrement du dépôt à une étape encore plus précoce, lors du clonage.

Étant donné qu'Argo CD ne fournit actuellement pas la possibilité de décrire des hooks pour la synchronisation du dépôt, nous avons dû contourner cette limitation avec un astucieux script shell qui remplace la commande git :

#!/bin/sh
$(dirname $0)/git.bin "$@"
ec=$?
[ "$1" = fetch ] && [ -d .git-crypt ] || exit $ec
GNUPGHOME=/app/config/gpg/keys git-crypt unlock 2>/dev/null
exit $ec

Argo CD exécute git fetch à chaque fois avant l'opération de déploiement. C'est à cette commande que nous attacherons l'exécution git-crypt unlock pour déverrouiller le dépôt.

Pour les tests, vous pouvez utiliser mon image docker dans laquelle tout le nécessaire est déjà présent :

$ kubectl -n argocd set image deploy/argocd-repo-server argocd-repo-server=docker.io/kvaps/argocd-git-crypt:v1.7.3

Nous devons maintenant réfléchir à la façon dont Argo va déchiffrer nos dépôts. C'est-à-dire générer une clé gpg pour lui :

$ kubectl exec -ti deploy/argocd-repo-server -- bash

$ printf "%sn" 
    "%no-protection" 
    "Key-Type: default" 
    "Subkey-Type: default" 
    "Name-Real: VOTRE NOM" 
    "Name-Email: VOTRE EMAIL@example.com" 
    "Expire-Date: 0" 
    > genkey-batch 

$ gpg --batch --gen-key genkey-batch
gpg: AVERTISSEMENT : propriété non sécurisée sur le dossier utilisateur ' /home/argocd/.gnupg'
gpg: clé de boîtier ' /home/argocd/.gnupg/pubring.kbx' créée
gpg: /home/argocd/.gnupg/trustdb.gpg : trustdb créée
gpg: clé 8CB8B24F50B4797D marquée comme entièrement digne de confiance
gpg: répertoire ' /home/argocd/.gnupg/openpgp-revocs.d' créé
gpg: certificat de révocation stocké sous ' /home/argocd/.gnupg/openpgp-revocs.d/9A1FF8CAA917CE876E2562FC8CB8B24F50B4797D.rev'

Conservons le nom de la clé 8CB8B24F50B4797D pour les étapes suivantes. Exécutons la clé elle-même :

$ gpg --list-keys
gpg: AVERTISSEMENT : propriété dangereuse sur le répertoire personnel '/home/argocd/.gnupg'
/home/argocd/.gnupg/pubring.kbx
-------------------------------
pub   rsa3072 2020-09-04 [SC]
      9A1FF8CAA917CE876E2562FC8CB8B24F50B4797D
uid           [ultime] VOTRE NOM <VOTRE EMAIL@example.com>
sub   rsa3072 2020-09-04 [E]

$ gpg --armor --export-secret-keys 8CB8B24F50B4797D

Et ajoutons-le sous forme de secret séparé :

# argocd-gpg-keys-secret.yaml
apiVersion: v1
kind: Secret
metadata:
  name: argocd-gpg-keys-secret
  namespace: argocd
stringData:
  8CB8B24F50B4797D: |-
    -----BEGIN PGP PRIVATE KEY BLOCK-----

    lQVYBF9Q8KUBDACuS4p0ctXoakPLqE99YLmdixfF/QIvXVIG5uBXClWhWMuo+D0c
    ZfeyC5GvH7XPUKz1cLMqL6o/u9oHJVUmrvN/g2Mnm365nTGw1M56AfATS9IBp0HH
    O/fbfiH6aMWmPrW8XIA0icoOAdP+bPcBqM4HRo4ssbRS9y/i
    =yj11
    -----END PGP PRIVATE KEY BLOCK-----

$ kubectl apply -f argocd-gpg-keys-secret.yaml

La seule chose qui nous reste à faire est de le passer dans le conteneur argocd-repo-server, pour cela, nous allons modifier le déploiement :

$ kubectl -n argocd edit deploy/argocd-repo-server

Et remplacer l'existant gpg-keys volume par projected, où nous indiquerons notre secret :

   spec:
     template:
       spec:
         volumes:
         - name: gpg-keys
           projected:
             defaultMode: 420
             sources:
             - secret:
                 name: argocd-gpg-keys-secret
             - configMap:
                 name: argocd-gpg-keys-cm

Argo CD télécharge automatiquement les clés gpg depuis ce répertoire au démarrage du conteneur, de cette manière il chargera aussi notre clé privée.

vérifions :

$ kubectl -n argocd exec -ti deploy/argocd-repo-server -- bash
$ GNUPGHOME=/app/config/gpg/keys gpg --list-secret-keys
gpg: AVERTISSEMENT : propriété dangereuse sur le répertoire personnel '/app/config/gpg/keys'
/app/config/gpg/keys/pubring.kbx
--------------------------------
sec   rsa2048 2020-09-05 [SC] [expire : 2021-03-04]
      ED6285A3B1A50B6F1D9C955E5E8B1B16D47FFC28
uid           [ultime] Anon Ymous (clé de signature d'ArgoCD) <noreply@argoproj.io>

sec   rsa3072 2020-09-03 [SC]
      9A1FF8CAA917CE876E2562FC8CB8B24F50B4797D
uid           [ultime] VOTRE NOM <VOTRE EMAIL@example.com>
ssb   rsa3072 2020-09-03 [E]

Super, la clé est chargée ! Maintenant, il nous suffit d'ajouter Argo CD à notre dépôt en tant que collaborateur et il pourra automatiquement le déchiffrer à la volée.

Importons la clé sur l'ordinateur local :

$ gpg --armor --export-secret 8CB8B24F50B4797D > 8CB8B24F50B4797D.pem
$ gpg --import 8CB8B24F50B4797D.pem

Configurons le niveau de confiance :

$ gpg --edit-key 8CB8B24F50B4797D
trust
5

Ajoutons argo en tant que collaborateur à notre projet :

$ git-crypt add-gpg-user 8CB8B24F50B4797D

Liens sur le sujet:

Source : habr.com

Acheter un hébergement fiable pour les sites avec protection DDoS, serveurs VPS VDS 🔥 Acheter un hébergement fiable pour les sites avec protection DDoS, serveurs VPS VDS | ProHoster