Comprendere gli strumenti personalizzati nel CD Argo

Comprendere gli strumenti personalizzati nel CD Argo

Qualche tempo dopo aver scritto primo articolo, dove ho gestito abilmente jsonnet e gitlab, mi sono reso conto che le pipeline sono certamente buone, ma inutilmente complicate e scomode.

Nella maggior parte dei casi, è richiesta un’attività tipica: “generare YAML e inserirlo in Kubernetes”. In realtà, questo è ciò che il CD Argo fa straordinariamente bene.

Argo CD ti consente di connettere un repository Git e inviare il suo stato a Kubernetes. Per impostazione predefinita, è disponibile il supporto per diversi tipi di applicazioni: Kustomize, grafici Helm, Ksonnet, Jsonnet semplice o solo directory con manifest YAML/JSON.

Questo set sarà sufficiente per la maggior parte degli utenti, ma non per tutti. Per soddisfare le esigenze di tutti, Argo CD ha la possibilità di utilizzare strumenti personalizzati.

Innanzitutto mi interessa la possibilità di aggiungere supporto qbec и git-crypt, di cui abbiamo ampiamente parlato nel precedente articolo.

Prima di iniziare la configurazione, devi prima capire esattamente come funziona Argo CD.

Per ogni applicazione aggiunta, ha due fasi:

  • init — preparazione iniziale prima della distribuzione, qui può succedere di tutto: scaricare le dipendenze, decomprimere i segreti e altro ancora.
  • generare — eseguendo direttamente il comando di generazione del manifest, l'output deve essere un flusso YAML valido, questo è esattamente ciò che verrà applicato al cluster.

La cosa notevole è che Argo applica questo approccio a qualsiasi tipo di applicazione, incluso Helm. Cioè, in Argo CD Helm non distribuisce versioni al cluster, ma viene utilizzato solo per generare manifest.

Da parte sua, Argo può elaborare gli hook Helm in modo nativo, il che gli consente di non violare la logica di applicazione dei rilasci.

QBEC

Qbec ti consente di descrivere comodamente le applicazioni utilizzando jsonnet e inoltre ha la capacità di eseguire il rendering dei grafici Helm e poiché Argo CD può normalmente elaborare gli hook Helm, l'utilizzo di questa funzionalità con Argo CD ti consente di ottenere risultati ancora più corretti.

Per aggiungere il supporto qbec ad argocd hai bisogno di due cose:

  • Nella configurazione del CD Argo, è necessario definire il plug-in personalizzato e i comandi per generare manifest.
  • i file binari necessari devono essere disponibili nell'immagine server-repo-argocd.

Primo compito è deciso abbastanza semplice:

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

(squadra init non usato)

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

Si consiglia di aggiungere file binari raccogliere una nuova immagineo utilizzare trucco del contenitore 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)"

Ora vediamo come apparirà il manifest della nostra applicazione:

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 una variabile AMBIENTE passiamo il nome dell'ambiente per il quale dobbiamo generare manifest.

applichiamolo e vediamo cosa otteniamo:

Comprendere gli strumenti personalizzati nel CD Argo

L'applicazione è stata distribuita, fantastico!

git-crypt

Git-crypt ti consente di impostare una crittografia trasparente per il tuo repository. È un modo semplice e sicuro per archiviare dati sensibili direttamente in Git.

L'implementazione di git-crypt si è rivelata più difficile.

Teoricamente potremmo farlo git-crypt unlock nella fase iniziale del nostro plugin personalizzato, ma questo non è molto conveniente, poiché non consentirebbe l'utilizzo di metodi di distribuzione nativi. Ad esempio, nel caso di Helm e Jsonnet, perdiamo un'interfaccia GUI flessibile che ci consente di semplificare la configurazione dell'applicazione (file di valori, ecc.).

Questo è il motivo per cui ho voluto stampare il repository in una fase precedente, durante la clonazione.

Dato che al momento Argo CD non fornisce la possibilità di descrivere alcun hook per la sincronizzazione del repository, abbiamo dovuto aggirare questa limitazione con un complicato script di shell che sostituisce il comando 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

Si esibisce il CD Argo git fetch ogni volta prima dell'operazione di distribuzione. È a questo comando che assegneremo l'esecuzione git-crypt unlock per sbloccare il repository.

per i test che puoi utilizzare la mia immagine mobile che ha già tutto quello che ti serve:

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

Ora dobbiamo pensare a come Argo decodificherà i nostri repository. Vale a dire, genera una chiave gpg per questo:

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

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

$ gpg --batch --gen-key genkey-batch
gpg: WARNING: unsafe ownership on homedir '/home/argocd/.gnupg'
gpg: keybox '/home/argocd/.gnupg/pubring.kbx' created
gpg: /home/argocd/.gnupg/trustdb.gpg: trustdb created
gpg: key 8CB8B24F50B4797D marked as ultimately trusted
gpg: directory '/home/argocd/.gnupg/openpgp-revocs.d' created
gpg: revocation certificate stored as '/home/argocd/.gnupg/openpgp-revocs.d/9A1FF8CAA917CE876E2562FC8CB8B24F50B4797D.rev'

Salviamo il nome della chiave 8CB8B24F50B4797D per ulteriori passaggi. Esporta la chiave stessa:

$ gpg --list-keys
gpg: WARNING: unsafe ownership on homedir '/home/argocd/.gnupg'
/home/argocd/.gnupg/pubring.kbx
-------------------------------
pub   rsa3072 2020-09-04 [SC]
      9A1FF8CAA917CE876E2562FC8CB8B24F50B4797D
uid           [ultimate] YOUR NAME <YOUR EMAIL@example.com>
sub   rsa3072 2020-09-04 [E]

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

E aggiungilo come segreto separato:

# 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

L'unica cosa che ci resta è gettarlo nel contenitore server-repo-argocd, per fare ciò, modifica la distribuzione:

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

E sostituiremo quello esistente chiavi gpg volume acceso projected, dove indichiamo il nostro segreto:

   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 carica automaticamente le chiavi gpg da questa directory all'avvio del contenitore, quindi caricherà anche la nostra chiave privata.

controlliamo:

$ kubectl -n argocd exec -ti deploy/argocd-repo-server -- bash
$ GNUPGHOME=/app/config/gpg/keys gpg --list-secret-keys
gpg: WARNING: unsafe ownership on homedir '/app/config/gpg/keys'
/app/config/gpg/keys/pubring.kbx
--------------------------------
sec   rsa2048 2020-09-05 [SC] [expires: 2021-03-04]
      ED6285A3B1A50B6F1D9C955E5E8B1B16D47FFC28
uid           [ultimate] Anon Ymous (ArgoCD key signing key) <noreply@argoproj.io>

sec   rsa3072 2020-09-03 [SC]
      9A1FF8CAA917CE876E2562FC8CB8B24F50B4797D
uid           [ultimate] YOUR NAME <YOUR EMAIL@example.com>
ssb   rsa3072 2020-09-03 [E]

Ottimo, la chiave è caricata! Ora non ci resta che aggiungere Argo CD al nostro repository come collaboratore e sarà in grado di decrittografarlo automaticamente al volo.

Importa la chiave sul computer locale:

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

Impostiamo il livello di fiducia:

$ gpg --edit-key 8CB8B24F50B4797D
trust
5

Aggiungiamo argo come collaboratore al nostro progetto:

$ git-crypt add-gpg-user 8CB8B24F50B4797D

Link correlati:

Fonte: habr.com