Argo CD ist ein Werkzeug für GitOps auf Kubernetes: Der gewünschte Zustand des Clusters steht in einem Git-Repository, und Argo CD sorgt dafür, dass das Cluster diesem Zustand entspricht. Änderungen erfolgen ausschließlich über Commits – nicht über kubectl apply aus einer Shell.
Warum GitOps statt kubectl
Ohne GitOps:
Wer hat die Konfiguration geaendert? -> unbekannt
Was war der Zustand vor 3 Tagen? -> niemand weiss es
Wie kommt ein Rollback zustande? -> von Hand
Wer darf aendern? -> alle mit Clusterzugriff
Mit GitOps:
Jede Aenderung ist ein Commit -> Verlauf, Urheber, Grund
Der Zustand vor 3 Tagen ist ein Commit -> git checkout
Rollback = Commit zuruecksetzen -> ein Befehl
Rechte = Schreibrecht im Repository -> pruefbar, nachvollziehbar
Zusaetzlich: Das Cluster wird selbstheilend. Wer etwas von Hand
aendert, verliert die Aenderung beim naechsten Abgleich - mit
Meldung. Genau das ist gewollt.
Installation
kubectl create namespace argocd
kubectl apply -n argocd -f \
https://raw.githubusercontent.com/argoproj/argo-cd/stable/manifests/install.yaml
# Warten
kubectl -n argocd rollout status deploy/argocd-server
# Erster Zugang: Benutzer admin, Passwort aus einem Geheimnis
kubectl -n argocd get secret argocd-initial-admin-secret \
-o jsonpath="{.data.password}" | base64 -d; echo
# SOFORT aendern und das Geheimnis loeschen!
# CLI installieren
curl -sSL -o /usr/local/bin/argocd \
https://github.com/argoproj/argo-cd/releases/latest/download/argocd-linux-amd64
chmod +x /usr/local/bin/argocd
argocd login argocd.example.org --username admin
argocd account update-password
argocd version
Die Anwendungsbeschreibung
# app.yaml - die zentrale Ressource
apiVersion: argoproj.io/v1alpha1
kind: Application
metadata:
name: webshop-prod
namespace: argocd
finalizers:
- resources-finalizer.argocd.argoproj.io # beim Loeschen aufraeumen
spec:
project: default
source:
repoURL: https://git.example.org/platform/k8s-manifests.git
targetRevision: main
path: apps/webshop/overlays/prod # Kustomize-Overlay
# Alternativ Helm:
# helm:
# valueFiles: [values-prod.yaml]
# parameters:
# - name: image.tag
# value: "1.4.2"
destination:
server: https://kubernetes.default.svc
namespace: webshop
syncPolicy:
automated:
prune: true # nicht mehr vorhandene Ressourcen entfernen
selfHeal: true # manuelle Aenderungen zuruecksetzen
allowEmpty: false # Schutz: nie alles loeschen
syncOptions:
- CreateNamespace=true
- PrunePropagationPolicy=foreground
- ApplyOutOfSyncOnly=true
retry:
limit: 5
backoff:
duration: 10s
factor: 2
maxDuration: 5m
Der Ablauf im Alltag
# Zustand ansehen
argocd app list
argocd app get webshop-prod
argocd app diff webshop-prod # was weicht ab?
# Synchronisieren
argocd app sync webshop-prod
argocd app sync webshop-prod --dry-run # Vorschau, ohne zu aendern
argocd app history webshop-prod
argocd app rollback webshop-prod 12 # auf Stand 12 zurueck
# Warten, bis fertig (gut in Skripten)
argocd app wait webshop-prod --timeout 300
# Manuelles Abweichen sichtbar machen
# Status "OutOfSync" -> jemand hat von Hand geaendert
# Mit selfHeal: true wird es zurueckgesetzt und protokolliert
# Eine Anwendung loeschen (inklusive der Ressourcen)
argocd app delete webshop-prod --cascade
# Alle Anwendungen einer Gruppe
argocd app list -l team=webshop
App-of-Apps: viele Anwendungen verwalten
Statt jede Anwendung einzeln anzulegen, verwaltet man eine Wurzelanwendung, die weitere Anwendungsbeschreibungen aus dem Repository zieht.
# apps/root.yaml - die Wurzelanwendung
apiVersion: argoproj.io/v1alpha1
kind: Application
metadata:
name: root
namespace: argocd
spec:
project: default
source:
repoURL: https://git.example.org/platform/k8s-manifests.git
targetRevision: main
path: apps/ # hier liegen weitere Application-Dateien
destination:
server: https://kubernetes.default.svc
namespace: argocd
syncPolicy:
automated: {prune: true, selfHeal: true}
# Ergebnis: Eine neue Anwendung aufnehmen heisst:
# 1. Datei unter apps/ anlegen
# 2. Commit und Push
# 3. Argo CD zieht sie automatisch
# Kein manuelles "argocd app create" mehr - alles im Verlauf.
# Mit ApplicationSet noch einen Schritt weiter:
# Eine Vorlage erzeugt Anwendungen je Umgebung oder je Cluster
# aus Verzeichnisstruktur oder Clusterliste.
Prüfliste
- Sind die Manifeste im Repository die einzige Quelle der Wahrheit – oder wird weiterhin von Hand geändert?
- Ist
selfHeal: trueaktiv, damit manuelle Änderungen zurückgesetzt werden? - Ist
prune: truemit Vorsicht aktiviert (Löschungen sind echt!)? - Sind die Rechte im Git-Repository aussagekräftig – wer darf in den Produktionspfad committen?
- Sind Geheimnisse nicht im Klartext im Repository (Sealed Secrets, SOPS, External Secrets)?
- Ist die Zustandsprüfung aktiv, damit Argo CD weiß, wann ein Rollout fertig ist?
- Sind Rollback und das Verhalten bei fehlerhaften Änderungen einmal geübt worden?
- Wird die Argo-CD-Instanz selbst aktualisiert und überwacht?
Häufige Fehler
- Geheimnisse im Repository. Ein Klartextpasswort im Git-Verlauf bleibt dort, auch wenn es später entfernt wird. Verschlüsselung (SOPS, Sealed Secrets) ist Pflicht.
prune: trueohne Verständnis. Eine Ressource aus dem Repository zu entfernen bedeutet echtes Löschen im Cluster – inklusive Datenbanken und Speichermedien, wenn keine Schutzmechanismen greifen.- Keine Zustandsprüfungen. Ohne sie meldet Argo CD „synchronisiert“, während der Rollout noch läuft – und ein nachfolgender Schritt greift auf eine halbfertige Anwendung zu.
- Cluster-Ressourcen ohne Namensraum. Was
namespacenicht braucht (ClusterRole, Namespace, CustomResourceDefinition), muss korrekt angegeben werden – sonst fehlt es oder wird an der falschen Stelle angelegt. - Selbstverwaltung außer Acht gelassen. Wird Argo CD aus demselben Repository verwaltet, das es überwacht, kann eine fehlerhafte Änderung die eigene Steuerung außer Betrieb setzen. Getrennt halten.
- Abgleichintervall zu lang. Standard sind drei Minuten. Bei wichtigen Anwendungen kann eine Abfrage (Webhook aus dem Repository) den Abgleich beschleunigen.
- Keine Trennung nach Umgebung. Produktion und Testumgebung im gleichen Pfad und mit gleichen Rechten führt unweigerlich zu Fehlern. Verzeichnisse je Umgebung, Rechte je Umgebung.
- Argo CD ohne Überwachung. Der Ausfall der Steuerung ist der stille Ausfall: Es funktioniert weiter – bis zur nächsten Änderung, die nicht mehr ankommt.
Wann GitOps passt – und wann nicht
Gut geeignet: Kubernetes-Umgebungen mit mehreren Umgebungen, Teams mit Änderungsnachverfolgung, wiederkehrende Konfiguration über Cluster hinweg.
Weniger geeignet: Ein einzelner Server ohne Cluster (dort passen Ansible oder ein Werkzeug wie Argo CD nicht), Umgebungen mit regulierten Änderungsfenstern und ohne Repository-Zugriff (dort braucht es einen zusätzlichen Freigabeprozess), und Situationen, in denen niemand Git versteht.
Verwandte Grundlagen: GitOps, Argo CD, Kubernetes, Kubernetes-Architektur.