La oss se på egendefinert verktøyutvikling i Argo CD

La oss se på egendefinert verktøyutvikling i Argo CD

Etter en tid etter å ha skrevet den første artikkelen, der jeg dyktig håndterte jsonnet og GitLab, innså jeg at pipelines er bra, men ofte for kompliserte og upraktiske.

I de fleste tilfeller er det et standardbehov: "generere YAML og plassere det i Kubernetes". Dette er noe Argo CD takler utmerket.

Argo CD gjør det mulig å koble til et Git-repositorium og synkronisere dets tilstand med Kubernetes. Som standard støtter det flere typer applikasjoner: Kustomize, Helm-diagrammer, Ksonnet, ren Jsonnet eller bare kataloger med YAML/JSON-maniester.

For de fleste brukere av dette settet er dette tilstrekkelig, men ikke for alle. For å imøtekomme alles behov i Argo CD er det mulig å bruke tilpassede verktøy.

Først og fremst er det interessant å legge til støtte qbec og git-crypt, som ble grundig gjennomgått i den forrige artikkelen.

Før man begynner å konfigurere, må man først forstå hvordan Argo CD fungerer.

For hver applikasjon som legges til, har den to faser:

  • init — innledende forberedelse før distribusjon, her kan det være hva som helst: nedlasting av avhengigheter, oppakking av hemmeligheter og mer.
  • generate — utføring av selve kommandoen for generering av manifester, utdataene må være en gyldig YAML-strøm, dette er nettopp det som vil bli brukt i klyngen.

Det interessante er at Argo bruker denne tilnærmingen for alle typer applikasjoner, også for Helm. Med andre ord, i Argo CD håndterer ikke Helm distribusjonen av utgivelser i klyngen, men brukes kun til å generere manifester.

Argo kan native håndtere Helm-hooks, noe som gjør at logikken i utgivelser ikke blir brutt.

QBEC

Qbec gjør det enkelt å beskrive applikasjoner med jsonnet, og det har også evnen til å rendere Helm-diagrammer, og siden Argo CD kan håndtere Helm-hooks korrekt, gir bruken av denne funksjonaliteten sammen med Argo CD enda mer nøyaktige resultater.

For å legge til støtte for qbec i argocd trenger man to ting:

  • den tilpassede plugin-en din må være definert i Argo CD-konfigurasjonen, samt kommandoene for generering av manifester.
  • de nødvendige binære filene må være tilgjengelige i bildet argocd-repo-server.

Det første problemet løses ganske enkelt:

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

(kommandoen init brukes ikke)

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

For å legge til binære filer foreslås det å bygge et nytt bilde, eller bruke triks med init-containeren:

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

La oss se hvordan manifestet for applikasjonen vår vil se ut:

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

I variabelen ENVIRONMENT sender vi navnet på miljøet som må brukes for å generere manifestene.

Vi anvender det og ser hva vi fikk:

La oss se på egendefinert verktøyutvikling i Argo CD

applikasjonen ble deployert, flott!

git-crypt

Git-crypt lar deg konfigurere transparent kryptering av repositoriet. Dette er en enkel og sikker måte å lagre konfidensielle data direkte i git.

Implementeringen av git-crypt viste seg å være mer utfordrende.

Teoretisk kunne vi ha kjørt git-crypt unlock på init-stadium av vår custom-plugin, men det er ikke veldig praktisk, siden det ikke ville tillatt bruk av native distribusjonsmetoder. For eksempel, i tilfelle Helm og Jsonnet, mister vi det fleksible GUI-grensesnittet som forenkler applikasjonsoppsett (verdifiler og lignende).

Av denne grunn ønsket jeg å utføre nedlastingen av repositoriet enda tidligere, ved kloning.

Siden Argo CD for øyeblikket ikke gir mulighet for å beskrive noen synkroniseringshooks for repositoriet, måtte jeg omgå denne begrensningen med en smart shell-wrapper-script som erstatter git-kommandoen:

#!/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 kjører git fetch hver gang før deploy-operasjonen. Det er på denne kommandoen vi vil henge opp utførelsen git-crypt unlock for å låse opp repositoriet.

For tester kan du bruke mitt docker-bilde som allerede har alt nødvendig:

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

Nå må vi tenke på hvordan Argo vil dekryptere repositoriene våre. Spesielt å generere en gpg-nøkkel for det:

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

Vi lagrer navnet på nøkkelen 8CB8B24F50B4797D for further steps. We export the key itself:

$ 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 
sub   rsa3072 2020-09-04 [E]

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

And we will add it as a separate secret:

# 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

The only thing left for us is to pass it into the container argocd-repo-server, for this, we will edit the deployment:

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

And replace the existing gpg-keys volume with projected, where we will specify our 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 automatically loads gpg keys from this directory when starting the container, thus it will load our private key as well.

let's check:

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

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

Great, the key is loaded! Now we just need to add Argo CD as a collaborator to our repository, and it will be able to decrypt it on the fly.

We will import the key to the local computer:

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

Let's set the trust level:

$ gpg --edit-key 8CB8B24F50B4797D
trust
5

We will add argo as a collaborator to our project:

$ git-crypt add-gpg-user 8CB8B24F50B4797D

Related links:

Kilde: habr.com

Kjøp pålitelig hosting for nettsteder med DDoS-beskyttelse, VPS VDS-servere 🔥 Kjøp pålitelig hosting for nettsteder med DDoS-beskyttelse, VPS VDS-servere | ProHoster