Zabýváme se Custom Tooling v Argo CD

Zabýváme se Custom Tooling v Argo CD

Po nějaké době po napsání prvního článku, kde jsem šikovně manipuloval s jsonnet a gitlabem, jsem pochopil, že pipeline jsou sice skvělé, ale přece jen příliš složité a nepohodlné.

Většinou je potřeba vyřešit běžný úkol: "vygenerovat YAML a uložit ho do Kubernetes". To, co Argo CD skvěle zvládá.

Argo CD umožňuje připojit Git repozitář a synchronizovat jeho stav v Kubernetes. Podporuje různé typy aplikací: Kustomize, Helm chart, Ksonnet, čistý Jsonnet nebo prostě adresáře s YAML/JSON manifesty.

Většině uživatelů tohoto balíčku to stačí, ale ne všem. Aby vyhovělo potřebám každého, Argo CD má možnost používat custom tooling.

Především mě zajímá možnost přidání podpory qbec a git-crypt, které byly podrobněji probrány v předchozím článku.

Než začnete s konfigurací, je potřeba nejprve pochopit, jak Argo CD funguje.

Pro každou přidanou aplikaci má dvě fáze:

  • init — počáteční příprava před nasazením, zde může být cokoliv: stahování závislostí, rozbalování tajemství a další.
  • vygenerovat — provedení samotného příkazu pro generaci manifestů, výstup by měl být platným YAML streamem, to je přesně to, co bude aplikováno v clusteru.

Zajímavé je, že Argo používá tento přístup pro jakýkoliv typ aplikací, včetně Helm. To znamená, že v Argo CD Helm nezodpovídá za nasazení vydání do clusteru, ale slouží pouze k generaci manifestů.

Argo umí nativně zpracovávat Helm hooky, což umožňuje nenarušovat logiku aplikace vydání.

QBEC

Qbec umožňuje pohodlně popisovat aplikace pomocí jsonnet, a navíc má možnost renderovat Helm chart, a protože Argo CD umí řádně zpracovávat Helm hooky, využití této možnosti s Argo CD přináší ještě přesnější výsledky.

Abychom přidali podporu qbec do argocd, potřebujeme dvě věci:

  • ve konfiguraci Argo CD musí být definován váš custom plugin a příkazy pro generaci manifestů.
  • potřebné binárky musí být dostupné v obraze argocd-repo-server.

První úkol se řeší poměrně snadno:

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

(příkaz init se nepoužívá)

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

Pro přidání binárek se doporučuje sestavit nový obraz, nebo použít trik s init kontejnerem:

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

Nyní se podívejme, jak bude vypadat manifest naší aplikace:

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

V proměnné ENVIRONMENT předáváme jméno prostředí, pro které je třeba generovat manifesty.

Aplikujeme a podíváme se, co jsme dostali:

Zabýváme se Custom Tooling v Argo CD

Aplikace byla úspěšně nasazena, skvělé!

git-crypt

Git-crypt umožňuje nastavit transparentní šifrování repozitáře. To je jednoduchý a bezpečný způsob, jak uchovávat důvěrné údaje přímo v gitu.

S implementací git-crypt to bylo složitější.

Teoreticky bychom mohli spustit git-crypt unlock ve fázi init našeho vlastního pluginu, ale to není příliš pohodlné, protože by nám to neumožnilo používat nativní metody nasazení. Například v případě Helm a Jsonnet ztrácíme flexibilní GUI, které usnadňuje konfiguraci aplikace (soubor values a další).

Právě proto bychom chtěli provést dešifrování repozitáře ještě dříve, při klonování.

Protože Argo CD v současnosti nenabízí možnost popsat žádné hooky pro synchronizaci repozitáře, museli jsme obejít toto omezení chytrým shell skriptem, který nahrazuje příkaz 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 provádí git fetch každýkrát před operací nasazení. Na tento příkaz zavěsíme provedení git-crypt unlock pro odemčení repozitáře.

Pro testy můžete použít můj docker obraz ve kterém je již vše potřebné:

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

Nyní musíme přemýšlet o tom, jak Argo dešifruje naše repozitáře. A to konkrétně o generování gpg klíče pro něj:

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

$ printf "%sn" 
    "%no-protection" 
    "Key-Type: default" 
    "Subkey-Type: default" 
    "Name-Real: VAŠE JMÉNO" 
    "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'

Uložíme jméno klíče 8CB8B24F50B4797D pro další kroky. Exportujeme samotný klíč:

$ 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

A přidáme ho jako samostatné tajemství:

# 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

Jediné, co nám zbývá, je překlopit ho do kontejneru argocd-repo-server, k tomu upravíme deployment:

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

A nahradíme stávající gpg-keys objemem na projected, kde uvedeme naše tajemství:

   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 automaticky načítá gpg klíče z tohoto adresáře při spuštění kontejneru, takže načte i náš privátní klíč.

zkontrolujeme:

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

Skvěle, klíč byl nahrán! Teď stačí přidat Argo CD do našeho repozitáře jako spolupracovníka, a on ho bude moci automaticky dešifrovat za běhu.

Importujeme klíč na místní počítač:

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

Nastavíme úroveň důvěry:

$ gpg --edit-key 8CB8B24F50B4797D
trust
5

Přidáme argo jako spolupracovníka do našeho projektu:

$ git-crypt add-gpg-user 8CB8B24F50B4797D

Odkazy k tématu:

Zdroj: habr.com

Koupit spolehlivý hosting pro webové stránky s ochranou proti DDoS, VPS VDS servery 🔥 Koupit spolehlivý hosting pro webové stránky s ochranou proti DDoS, VPS VDS servery | ProHoster