Argo CD Argo CD

Helm-Charts und Kustomize-Overlays pro Umgebung deployen

Ein Repository für Dev und Prod strukturieren und die ConfigMap-Rollout-Falle vermeiden.

15 min Fortgeschritten

Echte Anwendungen laufen in mehreren Umgebungen, die sich in Kleinigkeiten unterscheiden: Replikazahlen, Hostnamen, Konfigurationswerte. Argo CD kann aus reinem YAML, Helm-Charts oder Kustomize deployen und erkennt, welches davon ein Ordner verwendet. Diese Anleitung zeigt, wie du ein Repository für mehrere Umgebungen mit Kustomize-Overlays und mit Helm-Values-Dateien strukturierst, und behandelt eine Falle, in die man bei Konfigurationsänderungen gerne tappt. Sie baut auf dem webapp-Beispiel aus den früheren Anleitungen auf.

Ein Layout wählen: Ordner statt Branches

Du kannst Umgebungen als langlebige Branches abbilden (dev, staging, main), aber dann wird die Promotion zur Merge-Übung, und die Umgebungen driften auseinander. Ein einzelner Branch mit einem Ordner pro Umgebung ist leichter zu durchschauen: Jede Umgebung ist nebeneinander sichtbar, und eine Änderung an einer ist ein normaler Diff.

Kustomize ist genau dafür gebaut: eine gemeinsame Base plus ein kleines Overlay pro Umgebung, das nur ändert, was sich unterscheidet.

Eine Kustomize-Base und Overlays bauen

webapp-config/
├── base/
│   ├── deployment.yaml
│   ├── service.yaml
│   └── kustomization.yaml
└── overlays/
    ├── dev/
    │   └── kustomization.yaml
    └── prod/
        └── kustomization.yaml

base/kustomization.yaml listet die gemeinsamen Ressourcen auf:

resources:
  - deployment.yaml
  - service.yaml

Lass den Container in base/deployment.yaml seine Einstellungen aus einer ConfigMap lesen, die jedes Overlay erzeugt:

          envFrom:
            - configMapRef:
                name: webapp-config

overlays/dev/kustomization.yaml:

resources:
  - ../../base
namespace: webapp-dev
replicas:
  - name: webapp
    count: 2
configMapGenerator:
  - name: webapp-config
    literals:
      - HEADER=Hello from dev

overlays/prod/kustomization.yaml sieht genauso aus, mit namespace: webapp-prod, count: 4 und einem eigenen HEADER-Wert.

Pro Overlay eine Application anlegen

Argo CD erkennt eine kustomization.yaml im Pfad und baut sie für dich. Erstelle pro Umgebung eine Application:

apiVersion: argoproj.io/v1alpha1
kind: Application
metadata:
  name: webapp-dev
  namespace: argocd
spec:
  project: default
  source:
    repoURL: https://github.com/your-org/webapp-config.git
    targetRevision: HEAD
    path: overlays/dev
  destination:
    server: https://kubernetes.default.svc
    namespace: webapp-dev
  syncPolicy:
    syncOptions:
      - CreateNamespace=true
    automated:
      prune: true

Für webapp-prod änderst du Name, Pfad (overlays/prod) und Namespace. Überlege außerdem, automated wegzulassen, damit Produktions-Syncs von einer Person freigegeben werden.

Bei Helm ist die Form dieselbe, nur dass die Quelle ein Chart ist und du die Values-Datei einer Umgebung auswählst:

  source:
    repoURL: https://github.com/your-org/webapp-config.git
    targetRevision: HEAD
    path: charts/webapp
    helm:
      valueFiles:
        - values-dev.yaml

valueFiles-Pfade sind relativ zum Chart-Ordner, und spätere Dateien überschreiben frühere.

Konfigurationsänderungen bewusst behandeln

Ändere den HEADER-Wert in einer Umgebung und vergleiche, was die beiden Werkzeuge tun:

  • Kustomize hängt einen Hash des Inhalts an die Namen generierter ConfigMaps an. Ein neuer Wert erzeugt eine neue ConfigMap (webapp-config-<hash>) und aktualisiert die Referenz des Deployments, was einen Pod-Rollout auslöst. Die alte ConfigMap ist nun verwaist, daher zeigt die Anwendung OutOfSync, bis sie bereinigt (gepruned) wird. Mit aktiviertem prune: true passiert das automatisch.
  • Helm aktualisiert die vorhandene ConfigMap an Ort und Stelle. Die Deployment-Spec ändert sich nicht, die laufenden Pods behalten also die alten Werte, und nichts veranlasst Argo CD oder Kubernetes, sie neu zu starten.

Die Standardlösung für Helm ist, eine Prüfsumme der ConfigMap in das Pod-Template zu schreiben. So ändert eine Konfigurationsänderung das Template und rollt die Pods aus. In templates/deployment.yaml:

  template:
    metadata:
      annotations:
        checksum/config: {{ include (print $.Template.BasePath "/configmap.yaml") . | sha256sum }}

Das Deployment von Hand neu zu starten funktioniert einmalig ebenfalls, ist aber nicht in Git festgehalten und verfehlt damit den Sinn.

Änderungen durch die Umgebungen befördern

Mit diesem Layout ist Promotion eine Folge gewöhnlicher Commits. Ändere zuerst das Dev-Overlay (zum Beispiel ein Image-Bump mit kustomize edit set image webapp=nginx:1.26, ausgeführt in overlays/dev), lass den automatischen Sync es anwenden und prüfe das Ergebnis. Mache dann dieselbe Änderung in overlays/prod und synchronisiere sie, manuell, wenn du die Produktion abgesichert hast. Eine CI-Pipeline kann den Dev-Commit automatisieren, und ein Pull Request oder eine Freigabe kann den Produktions-Commit absichern. Wenn du viele Cluster oder Umgebungen von einer Stelle aus betreiben willst, wirf einen Blick auf Argo CD ApplicationSets, die Application-Ressourcen aus einer Vorlage erzeugen.

Beliebte Anleitungen