- Authors

- Name
- Phillip Pham
- @ddppham
TL;DR
- ArgoCD synchronisiert Ihren Kubernetes-Cluster automatisch mit Git-Repositories und ermoeglicht deklarative GitOps-Deployments
- Installation in wenigen Minuten via kubectl, mit UI, CLI und automatischer Synchronisation
- Unterstuetzt Kustomize, Helm Charts, Multi-Cluster-Deployments und das App-of-Apps-Pattern
- Sync-Waves und Hooks ermoeglichen kontrollierte Deployment-Reihenfolgen mit Pre-/PostSync-Jobs
- Best Practices: Separate Repos fuer Code und Config, Image Updater, RBAC fuer Teams und Notifications
ArgoCD: GitOps für Kubernetes
ArgoCD ist der beliebteste GitOps-Controller für Kubernetes. Er synchronisiert Ihren Cluster automatisch mit Git - Änderungen am Repository werden automatisch deployed. In diesem Tutorial richten wir ArgoCD ein und deployen eine erste Anwendung.
Was ist GitOps?
┌──────────────┐ ┌──────────────┐ ┌──────────────┐
│ Git │────▶│ ArgoCD │────▶│ Kubernetes │
│ (Source of │ │ (Controller)│ │ (Cluster) │
│ Truth) │ │ │ │ │
└──────────────┘ └──────────────┘ └──────────────┘
Änderung im Git → ArgoCD erkennt Diff → Automatisches Deployment
Vorteile:
- Git als Single Source of Truth
- Automatische Deployments
- Einfaches Rollback (git revert)
- Audit-Trail durch Git-Historie
- Keine kubectl-Zugriffe für Entwickler nötig
Teil 1: ArgoCD installieren
Quick Install
# Namespace erstellen
kubectl create namespace argocd
# ArgoCD installieren
kubectl apply -n argocd -f https://raw.githubusercontent.com/argoproj/argo-cd/stable/manifests/install.yaml
# Warten bis alle Pods laufen
kubectl wait --for=condition=Ready pods --all -n argocd --timeout=300s
Initial Password abrufen
# Admin-Password
kubectl -n argocd get secret argocd-initial-admin-secret \
-o jsonpath="{.data.password}" | base64 -d
Zugriff auf UI
Option A: Port-Forward (schnell, temporär)
kubectl port-forward svc/argocd-server -n argocd 8080:443
# Browser: https://localhost:8080
# User: admin
# Password: siehe oben
Option B: LoadBalancer (Production)
kubectl patch svc argocd-server -n argocd -p '{"spec": {"type": "LoadBalancer"}}'
Option C: Ingress (empfohlen)
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: argocd-server
namespace: argocd
annotations:
nginx.ingress.kubernetes.io/ssl-passthrough: "true"
nginx.ingress.kubernetes.io/backend-protocol: "HTTPS"
spec:
ingressClassName: nginx
rules:
- host: argocd.example.de
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: argocd-server
port:
name: https
tls:
- hosts:
- argocd.example.de
secretName: argocd-tls
ArgoCD CLI installieren
# macOS
brew install argocd
# Linux
curl -sSL -o argocd https://github.com/argoproj/argo-cd/releases/latest/download/argocd-linux-amd64
chmod +x argocd
sudo mv argocd /usr/local/bin/
# Login
argocd login localhost:8080
Teil 2: Repository verbinden
Öffentliches Repository
Kein Setup nötig - ArgoCD kann direkt darauf zugreifen.
Privates Repository (SSH)
# SSH Key als Secret hinzufügen
argocd repo add git@github.com:myorg/myapp.git \
--ssh-private-key-path ~/.ssh/id_rsa
Oder deklarativ:
apiVersion: v1
kind: Secret
metadata:
name: private-repo
namespace: argocd
labels:
argocd.argoproj.io/secret-type: repository
stringData:
type: git
url: git@github.com:myorg/myapp.git
sshPrivateKey: |
-----BEGIN OPENSSH PRIVATE KEY-----
...
-----END OPENSSH PRIVATE KEY-----
GitHub App (empfohlen für Organisationen)
apiVersion: v1
kind: Secret
metadata:
name: github-app-repo
namespace: argocd
labels:
argocd.argoproj.io/secret-type: repository
stringData:
type: git
url: https://github.com/myorg/myapp.git
githubAppID: "12345"
githubAppInstallationID: "67890"
githubAppPrivateKey: |
-----BEGIN RSA PRIVATE KEY-----
...
-----END RSA PRIVATE KEY-----
Teil 3: Erste Application erstellen
Repository-Struktur
myapp-gitops/
├── apps/ # ArgoCD Applications
│ ├── production.yaml
│ └── staging.yaml
├── base/ # Basis-Manifeste
│ ├── deployment.yaml
│ ├── service.yaml
│ └── kustomization.yaml
└── overlays/ # Umgebungs-Overrides
├── production/
│ ├── kustomization.yaml
│ └── replicas-patch.yaml
└── staging/
└── kustomization.yaml
Basis-Manifeste
base/deployment.yaml:
apiVersion: apps/v1
kind: Deployment
metadata:
name: myapp
spec:
selector:
matchLabels:
app: myapp
template:
metadata:
labels:
app: myapp
spec:
containers:
- name: myapp
image: myregistry/myapp:latest
ports:
- containerPort: 8080
resources:
requests:
cpu: 100m
memory: 128Mi
limits:
cpu: 200m
memory: 256Mi
base/service.yaml:
apiVersion: v1
kind: Service
metadata:
name: myapp
spec:
selector:
app: myapp
ports:
- port: 80
targetPort: 8080
base/kustomization.yaml:
apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization
resources:
- deployment.yaml
- service.yaml
Production Overlay
overlays/production/kustomization.yaml:
apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization
namespace: production
resources:
- ../../base
patches:
- path: replicas-patch.yaml
images:
- name: myregistry/myapp
newTag: v1.2.3
overlays/production/replicas-patch.yaml:
apiVersion: apps/v1
kind: Deployment
metadata:
name: myapp
spec:
replicas: 3
ArgoCD Application
apps/production.yaml:
apiVersion: argoproj.io/v1alpha1
kind: Application
metadata:
name: myapp-production
namespace: argocd
finalizers:
- resources-finalizer.argocd.argoproj.io
spec:
project: default
source:
repoURL: https://github.com/myorg/myapp-gitops.git
targetRevision: main
path: overlays/production
destination:
server: https://kubernetes.default.svc
namespace: production
syncPolicy:
automated:
prune: true
selfHeal: true
syncOptions:
- CreateNamespace=true
- PruneLast=true
retry:
limit: 5
backoff:
duration: 5s
factor: 2
maxDuration: 3m
Application deployen
# Via kubectl
kubectl apply -f apps/production.yaml
# Oder via CLI
argocd app create myapp-production \
--repo https://github.com/myorg/myapp-gitops.git \
--path overlays/production \
--dest-server https://kubernetes.default.svc \
--dest-namespace production \
--sync-policy automated
Teil 4: Sync-Strategien
Manual Sync
spec:
syncPolicy: {} # Keine automatische Synchronisation
# Manuell synchronisieren
argocd app sync myapp-production
Automated Sync
spec:
syncPolicy:
automated:
prune: true # Löscht Ressourcen die nicht mehr in Git sind
selfHeal: true # Stellt Zustand wieder her bei manuellen Änderungen
Sync Waves
Kontrollierte Reihenfolge beim Deployment:
# ConfigMap zuerst
apiVersion: v1
kind: ConfigMap
metadata:
name: app-config
annotations:
argocd.argoproj.io/sync-wave: "-1"
---
# Dann Deployment
apiVersion: apps/v1
kind: Deployment
metadata:
name: myapp
annotations:
argocd.argoproj.io/sync-wave: "0"
---
# Zuletzt Ingress
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: myapp
annotations:
argocd.argoproj.io/sync-wave: "1"
Hooks
apiVersion: batch/v1
kind: Job
metadata:
name: db-migration
annotations:
argocd.argoproj.io/hook: PreSync
argocd.argoproj.io/hook-delete-policy: HookSucceeded
spec:
template:
spec:
containers:
- name: migrate
image: myapp:v1.2.3
command: ["./migrate.sh"]
restartPolicy: Never
Hook Types:
PreSync: Vor dem SyncSync: Während des SyncPostSync: Nach erfolgreichem SyncSyncFail: Nach fehlgeschlagenem Sync
Teil 5: App of Apps Pattern
Verwalten Sie alle Applications mit einer Meta-Application:
Struktur
argocd-apps/
├── apps.yaml # Meta-Application
└── apps/
├── myapp-prod.yaml
├── myapp-staging.yaml
├── monitoring.yaml
└── ingress.yaml
Meta-Application
apps.yaml:
apiVersion: argoproj.io/v1alpha1
kind: Application
metadata:
name: applications
namespace: argocd
spec:
project: default
source:
repoURL: https://github.com/myorg/argocd-apps.git
targetRevision: main
path: apps
destination:
server: https://kubernetes.default.svc
namespace: argocd
syncPolicy:
automated:
prune: true
selfHeal: true
Einzelne Applications
apps/monitoring.yaml:
apiVersion: argoproj.io/v1alpha1
kind: Application
metadata:
name: monitoring
namespace: argocd
spec:
project: default
source:
repoURL: https://prometheus-community.github.io/helm-charts
chart: kube-prometheus-stack
targetRevision: 55.5.0
helm:
values: |
grafana:
adminPassword: admin123
prometheus:
retention: 7d
destination:
server: https://kubernetes.default.svc
namespace: monitoring
syncPolicy:
automated:
prune: true
syncOptions:
- CreateNamespace=true
Teil 6: Helm Charts mit ArgoCD
Helm Repository
apiVersion: argoproj.io/v1alpha1
kind: Application
metadata:
name: nginx-ingress
namespace: argocd
spec:
project: default
source:
repoURL: https://kubernetes.github.io/ingress-nginx
chart: ingress-nginx
targetRevision: 4.9.0
helm:
releaseName: nginx-ingress
values: |
controller:
replicaCount: 2
service:
type: LoadBalancer
destination:
server: https://kubernetes.default.svc
namespace: ingress-nginx
syncPolicy:
automated:
prune: true
syncOptions:
- CreateNamespace=true
Helm Chart aus Git
apiVersion: argoproj.io/v1alpha1
kind: Application
metadata:
name: myapp
spec:
source:
repoURL: https://github.com/myorg/myapp.git
path: helm/myapp
targetRevision: main
helm:
valueFiles:
- values-production.yaml
parameters:
- name: image.tag
value: v1.2.3
Teil 7: Multi-Cluster Deployment
Cluster hinzufügen
# Cluster registrieren
argocd cluster add my-cluster-context
# Liste aller Cluster
argocd cluster list
Application auf Remote-Cluster
apiVersion: argoproj.io/v1alpha1
kind: Application
metadata:
name: myapp-eu
namespace: argocd
spec:
project: default
source:
repoURL: https://github.com/myorg/myapp-gitops.git
path: overlays/production
targetRevision: main
destination:
server: https://my-eu-cluster.example.de:6443 # Remote Cluster
namespace: production
ApplicationSet für Multi-Cluster
apiVersion: argoproj.io/v1alpha1
kind: ApplicationSet
metadata:
name: myapp
namespace: argocd
spec:
generators:
- list:
elements:
- cluster: eu-west
url: https://eu-west.k8s.example.de
- cluster: us-east
url: https://us-east.k8s.example.de
template:
metadata:
name: 'myapp-{{cluster}}'
spec:
project: default
source:
repoURL: https://github.com/myorg/myapp-gitops.git
targetRevision: main
path: 'overlays/{{cluster}}'
destination:
server: '{{url}}'
namespace: production
Teil 8: Best Practices
1. Separate Repos für Code und Config
myapp/ # Application Code
├── src/
├── Dockerfile
└── .github/workflows/ # Build Image → Update GitOps Repo
myapp-gitops/ # Kubernetes Manifeste (ArgoCD watched hier)
├── base/
└── overlays/
2. Image Updater für automatische Updates
# ArgoCD Image Updater installieren
kubectl apply -n argocd -f https://raw.githubusercontent.com/argoproj-labs/argocd-image-updater/stable/manifests/install.yaml
apiVersion: argoproj.io/v1alpha1
kind: Application
metadata:
name: myapp
annotations:
argocd-image-updater.argoproj.io/image-list: myapp=myregistry/myapp
argocd-image-updater.argoproj.io/myapp.update-strategy: semver
argocd-image-updater.argoproj.io/write-back-method: git
3. Notifications einrichten
# Slack Notification
apiVersion: v1
kind: ConfigMap
metadata:
name: argocd-notifications-cm
namespace: argocd
data:
service.slack: |
token: $slack-token
template.app-sync-status: |
message: |
Application {{.app.metadata.name}} sync status: {{.app.status.sync.status}}
trigger.on-sync-succeeded: |
- when: app.status.sync.status == 'Synced'
send: [app-sync-status]
4. RBAC für Teams
apiVersion: v1
kind: ConfigMap
metadata:
name: argocd-rbac-cm
namespace: argocd
data:
policy.csv: |
p, role:frontend-team, applications, get, frontend/*, allow
p, role:frontend-team, applications, sync, frontend/*, allow
g, frontend-developers, role:frontend-team
policy.default: role:readonly
Troubleshooting
Application stuck in "Progressing"
# Events prüfen
argocd app get myapp --show-operation
# Ressourcen-Status
argocd app resources myapp
# Sync erzwingen
argocd app sync myapp --force
Sync failed
# Diff anzeigen
argocd app diff myapp
# Detaillierte Logs
argocd app logs myapp
# Hard Refresh
argocd app get myapp --hard-refresh
"OutOfSync" trotz korrektem Git-State
# Cache leeren
argocd app get myapp --refresh
# Ignorierte Felder prüfen
# Oft: metadata.resourceVersion, status, etc.
Zusammenfassung
| Aufgabe | Befehl |
|---|---|
| App erstellen | argocd app create |
| Sync starten | argocd app sync myapp |
| Status prüfen | argocd app get myapp |
| Diff anzeigen | argocd app diff myapp |
| Rollback | argocd app rollback myapp |
| Logs | argocd app logs myapp |
Nächste Schritte
- Heute: ArgoCD installieren und erste Application erstellen
- Diese Woche: Bestehende Anwendungen auf GitOps migrieren
- Dieser Monat: App of Apps Pattern implementieren
Weiterführende Artikel:
- Helm Charts für Anfänger: Der Einstieg in Kubernetes-Paketmanagement
- Kubernetes Rolling Updates: Zero-Downtime Deployments
- Kubernetes Monitoring & Observability: Der komplette Guide
- Kubernetes Security Hardening: Best Practices für Production
- Kubernetes Cluster Setup für Production
GitOps klingt gut, aber Sie haben keine Zeit für den Aufbau? Als Managed Service Partner implementieren wir ArgoCD für Sie - inklusive Best Practices, Monitoring und Support.
Kubernetes-Beratung gesucht?
Wir helfen deutschen Unternehmen bei der Kubernetes-Implementierung, Migration und Optimierung. DSGVO-konform und praxiserprobt.
📖 Verwandte Artikel
Weitere interessante Beiträge zu ähnlichen Themen
ArgoCD Enterprise: App-of-Apps, RBAC und SSO
ArgoCD im Unternehmen einführen mit App-of-Apps-Pattern, RBAC, SSO-Integration und Multi-Repo-Strategien anhand realer YAML-Beispiele.
ArgoCD ApplicationSets: Multi-App Deployment Patterns
ArgoCD ApplicationSets automatisieren Multi-App und Multi-Cluster Deployments mit Generatoren. Praxis-Patterns für Git, Cluster und Matrix.
ArgoCD installieren und erstes Projekt deployen
ArgoCD auf Kubernetes installieren und das erste Projekt Schritt für Schritt deployen, von der CLI-Einrichtung bis zur automatischen Synchronisation.
Kubernetes CI/CD mit GitOps: Argo CD und Tekton einrichten
GitOps-basierte CI/CD-Pipelines für Kubernetes mit Argo CD, Tekton und Helm einrichten: Architektur, YAML-Beispiele und Deployment-Strategien.
GitOps Repository-Struktur: Best Practices
Die richtige Repository-Struktur entscheidet über den Erfolg von GitOps. Mono-Repo vs. Multi-Repo, Verzeichnisaufbau und Environment-Promotion praxisnah erklärt.