Approfondiamo il Custom Tooling in Argo CD

Approfondiamo il Custom Tooling in Argo CD

Dopo un certo periodo di tempo dalla scrittura del primo articolo, in cui gestivo con abilità jsonnet e gitlab, ho capito che i pipeline sono certamente utili, ma eccessivamente complessi e scomodi.

Nella maggior parte dei casi è necessaria una richiesta standard: "generare YAML e caricarlo in Kubernetes". In effetti, è ciò con cui Argo CD si occupa egregiamente.

Argo CD consente di collegare un repository Git e sincronizzarne lo stato in Kubernetes. Per impostazione predefinita, supporta diversi tipi di applicazioni: Kustomize, Helm charts, Ksonnet, Jsonnet puro o semplicemente directory con manifesti YAML/JSON.

La maggior parte degli utenti di questo set sarà soddisfatta, ma non tutti. Per soddisfare le esigenze di tutti, in Argo CD è disponibile la possibilità di utilizzare strumenti personalizzati.

Innanzitutto, interessa la possibilità di aggiungere supporto per qbec e git-crypt, che sono stati trattati completamente nell'articolo precedente.

Prima di iniziare con la configurazione, è necessario capire come funziona realmente Argo CD.

Per ogni applicazione aggiunta, ha due fasi:

  • join — preparazione iniziale prima del deployment, qui può esserci di tutto: scaricamento di dipendenze, estrazione di segreti e altro.
  • generate — esecuzione della comando di generazione dei manifesti, l'output deve essere un flusso YAML valido, questo è precisamente ciò che sarà applicato nel cluster.

È interessante notare che Argo applica questo approccio a qualsiasi tipo di applicazione, inclusi i Helm. Quindi, in Argo CD, Helm non si occupa del deployment delle release nel cluster, ma viene utilizzato solo per generare i manifesti.

Dalla sua parte, Argo è in grado di gestire nativamente i ganci di Helm, il che consente di non compromettere la logica di applicazione delle release.

QBEC

Qbec consente di descrivere comodamente le applicazioni utilizzando jsonnet e, inoltre, ha la possibilità di renderizzare i chart di Helm. Poiché Argo CD può gestire correttamente i ganci di Helm, l'uso di questa possibilità con Argo CD porta a risultati ancora più accurati.

Per aggiungere il supporto per qbec in argocd servono due cose:

  • nel file di configurazione di Argo CD deve essere definito il tuo plugin personalizzato e i comandi per generare i manifesti.
  • i binari necessari devono essere disponibili nell'immagine argocd-repo-server.

Il primo compito si risolve piuttosto facilmente:

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

(il comando join non è utilizzato)

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

Per aggiungere i binari si propone di costruire una nuova immagine, o utilizzare il trucco con il 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 sarà il manifesto 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

Nella variabile ENVIRONMENT stiamo passando il nome dell'ambiente per il quale è necessario generare i manifesti.

applichiamo e vediamo cosa abbiamo ottenuto:

Approfondiamo il Custom Tooling in Argo CD

l'applicazione è stata distribuita, ottimo!

git-crypt

Git-crypt consente di impostare la crittografia trasparente del repository. È un modo semplice e sicuro per archiviare dati riservati direttamente in git.

Con l'implementazione di git-crypt è stato più complicato.

Teoricamente potremmo eseguire git-crypt unlock nella fase di init del nostro plugin personalizzato, ma non è molto comodo, poiché non consentirebbe di utilizzare i metodi nativi di distribuzione. Ad esempio, nel caso di Helm e Jsonnet, perdiamo l'interfaccia GUI flessibile che semplifica la configurazione dell'applicazione (file values e altro).

Proprio per questo sarebbe stato utile eseguire la stampa del repository già in una fase precedente, durante il cloning.

Poiché al momento Argo CD non offre la possibilità di descrivere alcun hook per la sincronizzazione del repository, abbiamo dovuto aggirare questa limitazione con un astuto script shell di avvolgimento, 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

Argo CD esegue git fetch ogni volta prima dell'operazione di distribuzione. È su questo comando che faremo eseguire git-crypt unlock per sbloccare il repository.

Per i test puoi utilizzare la mia immagine docker in cui c'è già tutto il necessario:

$ 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 decifrerà i nostri repository. In particolare, generare una chiave gpg per esso:

$ 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'

Salveremo il nome della chiave 8CB8B24F50B4797D per i passaggi successivi. Esportiamo la chiave stessa:

$ gpg --list-keys
gpg: ATTENZIONE: proprietà non sicura nella home directory '\/home\/argocd\/.gnupg'\n\/home\/argocd\/.gnupg\/pubring.kbx\n-------------------------------\npub   rsa3072 2020-09-04 [SC]\n      9A1FF8CAA917CE876E2562FC8CB8B24F50B4797D\nuid           [ultimate] IL TUO NOME <YOUR EMAIL@example.com>\nsub   rsa3072 2020-09-04 [E]\n\n$ gpg --armor --export-secret-keys 8CB8B24F50B4797D

E lo aggiungeremo 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 da fare è passarla nel contenitore argocd-repo-server, per fare ciò modificheremo il deployment:

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

E sostituiremo l'attuale gpg-keys volume con projected, dove indicheremo il nostro segreto:

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

Argo CD carica automaticamente le chiavi gpg da questa directory all'avvio del contenitore, in questo modo caricherà anche la nostra chiave privata.

verifichiamo:

$ kubectl -n argocd exec -ti deploy\/argocd-repo-server -- bash\n$ GNUPGHOME=\/app\/config\/gpg\/keys gpg --list-secret-keys\ngpg: ATTENZIONE: proprietà non sicura nella home directory '\/app\/config\/gpg\/keys'\n\/app\/config\/gpg\/keys\/pubring.kbx\n--------------------------------\nsec   rsa2048 2020-09-05 [SC] [expires: 2021-03-04]\n      ED6285A3B1A50B6F1D9C955E5E8B1B16D47FFC28\nuid           [ultimate] Anon Ymous (chiave di firma ArgoCD) <noreply@argoproj.io>\n\nsec   rsa3072 2020-09-03 [SC]\n      9A1FF8CAA917CE876E2562FC8CB8B24F50B4797D\nuid           [ultimate] IL TUO NOME <YOUR EMAIL@example.com>\nssb   rsa3072 2020-09-03 [E]

Ottimo, la chiave è stata caricata! Ora ci basta aggiungere Argo CD al nostro repository come collaboratore e potrà decrittografarlo automaticamente al volo.

Importiamo la chiave sul computer locale:

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

Impostiamo il livello di fiducia:

$ gpg --edit-key 8CB8B24F50B4797D\ntrust\n5

Aggiungiamo argo come collaboratore al nostro progetto:

$ git-crypt add-gpg-user 8CB8B24F50B4797D

Link correlati:

Fonte: habr.com

Acquista hosting affidabile per siti web con protezione DDoS, VPS VDS server 🔥 Acquista hosting affidabile per siti web con protezione DDoS, VPS VDS server | ProHoster