Lassen Sie uns mit Custom Tooling in Argo CD arbeiten

Lassen Sie uns mit Custom Tooling in Argo CD arbeiten

Nach einer Weile, nachdem ich meinen ersten Artikelgeschrieben hatte, wo ich geschickt mit Jsonnet und GitLab hantierte, wurde mir klar, dass Pipelines zwar gut sind, aber übermäßig komplex und unpraktisch.

In den meisten Fällen gibt es eine typische Aufgabe: „YAML generieren und in Kubernetes ablegen“. Genau das erledigt Argo CD hervorragend.

Argo CD ermöglicht es, ein Git-Repository anzuschließen und dessen Zustand in Kubernetes zu synchronisieren. Standardmäßig unterstützt es verschiedene Arten von Anwendungen: Kustomize, Helm-Charts, Ksonnet, nacktes Jsonnet oder einfach Verzeichnisse mit YAML/JSON-Manifests.

Die meisten Benutzer dieses Sets werden damit auskommen, aber nicht alle. Um die Bedürfnisse aller zu befriedigen, gibt es in Argo CD die Möglichkeit, Custom-Tools zu verwenden.

In erster Linie interessiert mich die Möglichkeit, Unterstützung hinzuzufügen qbec und git-crypt, die bereits ausführlich im vorherigen Artikel behandelt wurden.

Bevor wir mit der Konfiguration beginnen, müssen wir zunächst verstehen, wie Argo CD genau funktioniert.

Für jede hinzugefügte Anwendung gibt es zwei Phasen:

  • init — eine anfängliche Vorbereitung vor dem Deployment, bei der vieles passieren kann: Abhängigkeiten herunterladen, Geheimnisse entpacken und mehr.
  • generieren — die Ausführung des Manifestgenerierungsbefehls, die Ausgabe muss ein gültiger YAML-Stream sein, das wird im Cluster angewendet.

Bemerkenswert ist, dass Argo diesen Ansatz für jede Art von Anwendungen anwendet, einschließlich Helm. Das bedeutet, dass in Argo CD Helm nicht für das Deployment von Releases im Cluster verantwortlich ist, sondern nur zur Generierung von Manifesten verwendet wird.

Argo kann Helm-Hooks nativ verarbeiten, was es ermöglicht, die Logik der Anwendung von Releases nicht zu stören.

QBEC

Qbec ermöglicht eine bequeme Beschreibung von Anwendungen mit jsonnet und hat auch die Möglichkeit, Helm-Charts zu rendern. Da Argo CD Helm-Hooks gut verarbeiten kann, erlaubt die Nutzung dieser Funktion in Argo CD, noch genauere Ergebnisse zu erzielen.

Um die Unterstützung für qbec in argocd hinzuzufügen, sind zwei Dinge erforderlich:

  • Ihr benutzerdefinierter Plugin muss in der Argo CD-Konfiguration definiert werden, sowie die Befehle zur Generierung von Manifesten.
  • Die benötigten Binaries müssen im Image verfügbar sein. argocd-repo-server.

Die erste Aufgabe wird recht einfach gelöst:

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

(der Befehl init wird nicht verwendet)

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

Um Binaries hinzuzufügen, wird vorgeschlagen, ein neues Image zu bauen,oder zu verwenden. Trick mit Init-Container:

# 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)"

Schauen wir uns an, wie das Manifest unserer Anwendung aussehen wird:

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

In der Variablen ENVIRONMENT wir geben den Namen der Umgebung an, für die die Manifestgenerierung durchgeführt werden soll.

wir wenden es an und sehen, was wir erreicht haben:

Lassen Sie uns mit Custom Tooling in Argo CD arbeiten

Die Anwendung wurde erfolgreich bereitgestellt, großartig!

git-crypt

Git-crypt ermöglicht die Einrichtung einer transparenten Verschlüsselung des Repositories. Dies ist eine einfache und sichere Methode, vertrauliche Daten direkt in Git zu speichern.

Die Implementierung von git-crypt gestaltete sich als komplizierter.

Theoretisch könnten wir git-crypt unlock in der Init-Phase unseres benutzerdefinierten Plugins ausführen, aber das ist nicht sehr praktisch, da es die Verwendung nativer Bereitstellungsmethoden nicht ermöglichen würde. Zum Beispiel bei Helm und Jsonnet verlieren wir die flexible GUI-Oberfläche, die die Konfiguration der Anwendung (Werte-Dateien usw.) erleichtert.

Deshalb wollte ich das Drucken des Repositories schon in einem früheren Stadium beim Klonen durchführen.

Da Argo CD derzeit keine Möglichkeit bietet, Hooks zur Synchronisierung des Repositories zu definieren, musste ich dieses Limit mit einem cleveren Shell-Skript umgehen, das den Git-Befehl ersetzt:

#!/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 führt git fetch immer vor dem Deployment-Vorgang aus. Genau an diesen Befehl hängen wir die Ausführung git-crypt unlock zum Entsperren des Repositories.

Für Tests kannst du mein Docker-Image verwenden, das bereits alles Nötige enthält:

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

Jetzt müssen wir uns überlegen, wie Argo unsere Repositories entschlüsseln wird. Nämlich indem wir einen GPG-Schlüssel für ihn generieren:

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

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

$ gpg --batch --gen-key genkey-batch
gpg: WARNUNG: unsichere Eigentümerschaft im homedir '/home/argocd/.gnupg'
gpg: keybox '/home/argocd/.gnupg/pubring.kbx' erstellt
gpg: '/home/argocd/.gnupg/trustdb.gpg': trustdb erstellt
gpg: Schlüssel 8CB8B24F50B4797D als letztlich vertrauenswürdig markiert
gpg: Verzeichnis '/home/argocd/.gnupg/openpgp-revocs.d' erstellt
gpg: Widerrufszertifikat gespeichert als '/home/argocd/.gnupg/openpgp-revocs.d/9A1FF8CAA917CE876E2562FC8CB8B24F50B4797D.rev'

Lassen Sie uns den Schlüsselnamen speichern 8CB8B24F50B4797D für die nächsten Schritte. Exportieren wir den Schlüssel selbst:

$ gpg --list-keys
gpg: WARNUNG: unsichere Eigentümerschaft im homedir '/home/argocd/.gnupg'
/home/argocd/.gnupg/pubring.kbx
-------------------------------
pub   rsa3072 2020-09-04 [SC]
      9A1FF8CAA917CE876E2562FC8CB8B24F50B4797D
uid           [ultimate] IHR NAME 
sub   rsa3072 2020-09-04 [E]

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

Und fügen wir ihn als separates Geheimnis hinzu:

# 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

Das Einzige, was uns bleibt, ist, es in den Container weiterzuleiten argocd-repo-server, dafür bearbeiten wir das Deployment:

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

Und ersetzen das vorhandene gpg-keys Volume durch projected, wo wir unser Geheimnis angeben:

   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 lädt beim Start des Containers automatisch die gpg-Schlüssel aus diesem Verzeichnis, sodass es auch unseren privaten Schlüssel importiert.

Lass uns überprüfen:

$ kubectl -n argocd exec -ti deploy/argocd-repo-server -- bash
$ GNUPGHOME=/app/config/gpg/keys gpg --list-secret-keys
gpg: WARNUNG: unsichere Besitzverhältnisse im Homedirectory '/app/config/gpg/keys'
/app/config/gpg/keys/pubring.kbx
--------------------------------
sec   rsa2048 2020-09-05 [SC] [läuft ab: 2021-03-04]
      ED6285A3B1A50B6F1D9C955E5E8B1B16D47FFC28
uid           [ultimate] Anon Ymous (ArgoCD Signierschlüssel) 

sec   rsa3072 2020-09-03 [SC]
      9A1FF8CAA917CE876E2562FC8CB8B24F50B4797D
uid           [ultimate] DEIN NAME 
ssb   rsa3072 2020-09-03 [E]

Prima, der Schlüssel wurde geladen! Jetzt müssen wir nur noch Argo CD zu unserem Repository als Mitwirkenden hinzufügen, damit es den Schlüssel automatisch zur Laufzeit entschlüsseln kann.

Importiere den Schlüssel auf den lokalen Computer:

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

Lass uns das Vertrauenslevel einstellen:

$ gpg --edit-key 8CB8B24F50B4797D
trust
5

Fügen wir argo als Mitwirkenden zu unserem Projekt hinzu:

$ git-crypt add-gpg-user 8CB8B24F50B4797D

Verweise zum Thema:

Quelle: habr.com

Купить надежный хостинг для сайтов с защитой от DDoS, VPS VDS серверы 🔥 Купить надежный хостинг для сайтов с защитой от DDoS, VPS VDS серверы | ProHoster