Argo CD
auf einem Blatt.
Dichte Referenz für Senior Platform Engineers und SREs zum GitOps-Continuous-Delivery-Standard für Kubernetes. Architektur, Application und AppProject, ApplicationSet, Sync-Waves und Hooks, Sync-Options, Health-Checks (Lua), Drift, RBAC, Multi-Cluster, Notifications und Anti-Patterns. Keine Einsteiger-Folien.
Vorschau (2 Seiten A4 quer + Brand-Rückseite)


PDF herunterladen
Direkter Download, keine Mail-Adresse nötig. CC BY-SA 4.0: kopieren, drucken, weiterverteilen ist ausdrücklich erlaubt, solange die Quellenangabe sichtbar bleibt.
Was drin steht
Architektur
argocd-server (API/UI), repo-server (Git-Cache + Manifest-Rendering), application-controller (Soll/Ist-Vergleich), dex, Redis als Wegwerf-Cache. HA mit Controller-Sharding.
Application & AppProject
Source/Destination/syncPolicy, automated mit prune + selfHeal. AppProject als Blast-Radius: sourceRepos, destinations, Resource-Whitelists, Rollen + JWT-Tokens.
App-of-Apps & ApplicationSet
Bootstrapping per Parent-Application. Generators: List, Cluster, Git, SCM-Provider, Pull-Request, Plugin; Matrix und Merge kombinieren sie.
Sync-Steuerung
Phasen PreSync/Sync/PostSync/SyncFail, PreDelete/PostDelete-Hooks, Waves per sync-wave-Annotation, Hooks mit delete-policy. Sync-Options: Server-Side Apply, Prune, Replace, ApplyOutOfSyncOnly.
Health & Drift
Health-Stati und Built-in-Checks, Custom Health via Lua in argocd-cm, ignoreDifferences (jsonPointers, jq, managedFields), Server-Side Diff, selfHeal gegen Drift.
RBAC, Multi-Cluster & Notifications
policy.csv (Casbin), SSO via dex, v3-RBAC-Änderungen, Cluster-Secrets deklarativ, Notifications per Annotation oder zentral per Selector. Anti-Patterns aus der Praxis.
Cheatsheet im Volltext
Derselbe Inhalt wie im PDF, zum Mitlesen, Durchsuchen und direkten Kopieren der YAML-Snippets. Stand: Argo CD v3.5 (Edition 2026.10).
Architektur
Control-Plane in drei Diensten
argocd-server: gRPC/REST-API für Web-UI, CLI und CI/CD; Auth, RBAC-Enforcement, Git-Webhook-Empfang.
argocd-repo-server: hält lokale Kopien der Git-Repos und rendert die Manifeste (Helm, Kustomize, Plain-YAML).
argocd-application-controller: vergleicht den Live-State im Cluster laufend mit dem Soll aus Git, meldet OutOfSync und führt Syncs samt Lifecycle-Hooks aus.
Nebenkomponenten
applicationset-controller: erzeugt Applications in Serie (siehe Generators). notifications-controller: Trigger/Templates für Alerts. commit-server: pusht gerenderte Manifeste nach Git (nur mit Source Hydrator). dex: gebündelter Identity-Broker für SSO (OIDC, SAML, LDAP, GitHub).
Redis: reiner Wegwerf-Cache, kann jederzeit ohne Datenverlust neu aufgebaut werden.
HA-Betrieb
argocd-server ist stateless: 3+ Replicas,
dazu ARGOCD_API_SERVER_REPLICAS setzen.
repo-server horizontal skalieren;
--parallelismlimit drosselt paralleles Rendern
(OOM-Schutz).
application-controller läuft als
StatefulSet und verteilt die Cluster per Sharding auf seine Replicas
(Anzahl in ARGOCD_CONTROLLER_REPLICAS); Algorithmus per
controller.sharding.algorithm:
legacy (Default), round-robin,
consistent-hashing (beide Alpha). Richtwert 1000
Apps: 50 Status- / 25 Operation-Processors.
HA-Manifeste brauchen ≥ 3 Nodes (Pod-Anti-Affinity).
argocd login argocd.example.com --sso argocd app list argocd app get shop --refresh argocd app diff shop
Application & AppProject
Application
Die Kern-CR: Source (repoURL,
path, targetRevision) +
Destination (server,
namespace) + project.
syncPolicy.automated aktiviert Auto-Sync:
prune löscht aus Git Entferntes,
selfHeal revertiert manuelle Cluster-Änderungen
zurück auf den Git-Stand.
apiVersion: argoproj.io/v1alpha1
kind: Application
metadata:
name: shop
namespace: argocd
spec:
project: team-shop
source:
repoURL: https://git.example.com/shop/deploy.git
targetRevision: main
path: overlays/prod
destination:
server: https://kubernetes.default.svc
namespace: shop
syncPolicy:
automated: {prune: true, selfHeal: true}
AppProject
Blast-Radius pro Team: sourceRepos (erlaubte
Git-Quellen), destinations (Cluster + Namespaces),
clusterResourceWhitelist (Allow-List für
cluster-scoped Kinds), namespaceResourceBlacklist.
Commit-Signaturen seit v3.5 über sourceIntegrity
(ersetzt signatureKeys).
Projekt-Rollen bündeln Policies; JWT-Tokens dazu
(argocd proj role create-token) für CI-Zugriff.
Das default-Projekt erlaubt initial alles, für Prod einschränken oder eigene Projekte schneiden.
App-of-Apps & ApplicationSet
App-of-Apps (Bootstrapping)
Eine Parent-Application zeigt auf einen Ordner (oder ein Chart) voller Application-Manifeste, ein Sync bootstrappt den ganzen Cluster deklarativ.
Achtung: Wer ins Parent-Repo pushen darf, kann Applications in beliebige Projekte legen, Push-Zugriff dorthin ist Admin-Level.
ApplicationSet-Generators
Template + Generator = Applications in Serie: List (feste Wertepaare), Cluster (alle in Argo CD registrierten Cluster), Git (Directories/Files eines Repos), SCM-Provider und Pull-Request (Repo-/PR-Discovery via Provider-API), Plugin (eigener RPC-Dienst).
Matrix kombiniert zwei Generators (z.B. Cluster × Git), Merge überlagert Parameter mehrerer Generators.
apiVersion: argoproj.io/v1alpha1
kind: ApplicationSet
metadata: {name: workloads, namespace: argocd}
spec:
goTemplate: true
goTemplateOptions: ["missingkey=error"]
generators:
- matrix:
generators:
- clusters: {} # alle registrierten Cluster
- git:
repoURL: https://git.example.com/deploy.git
revision: HEAD
directories:
- path: apps/*
template:
metadata:
name: '{{.name}}-{{.path.basename}}'
spec:
project: workloads
source:
repoURL: https://git.example.com/deploy.git
targetRevision: HEAD
path: '{{.path.path}}'
destination:
server: '{{.server}}'
namespace: '{{.path.basename}}'
syncPolicy:
automated: {prune: true, selfHeal: true}
Sync: Phasen, Waves & Hooks
Phasen, dann Waves
Reihenfolge pro Sync: PreSync →
Sync → PostSync;
SyncFail läuft nur bei Fehlschlag.
Innerhalb einer Phase ordnen Waves
(argocd.argoproj.io/sync-wave, Default 0, negativ
erlaubt): niedrigste Wave zuerst, dann Kind, dann Name.
Die nächste Wave startet erst, wenn die vorige synced +
healthy ist; zwischen Waves liegen 2 s Delay
(ARGOCD_SYNC_WAVE_DELAY).
Hooks
argocd.argoproj.io/hook: PreSync
(z.B. DB-Migration), Sync, PostSync
(Smoke-Test), SyncFail (Cleanup), Skip
(nicht anwenden); PreDelete/PostDelete
nur beim Löschen der App.
Aufräumen via
argocd.argoproj.io/hook-delete-policy:
HookSucceeded, HookFailed,
BeforeHookCreation (Default).
apiVersion: batch/v1
kind: Job
metadata:
name: db-migrate
annotations:
argocd.argoproj.io/hook: PreSync
argocd.argoproj.io/hook-delete-policy: HookSucceeded
argocd.argoproj.io/sync-wave: "-1"
spec:
template:
spec:
containers:
- name: migrate
image: registry.example.com/shop/migrate:1.4.2
restartPolicy: Never
Sync-Options
Pro App oder pro Ressource
ServerSideApply=true: K8s Server-Side Apply statt
Client-Side, für große Manifeste (Annotation-Limit)
und geteilte Ownership.
Prune=false (Ressourcen-Annotation) schützt
vor Löschung; Prune=confirm verlangt manuelle
Bestätigung. PruneLast=true: prunen erst,
nachdem alles Neue healthy ist.
Replace=true: kubectl replace statt
apply, destruktiv, nur gezielt einsetzen.
ApplyOutOfSyncOnly=true: nur abweichende Ressourcen
anfassen, entlastet den API-Server bei großen Apps.
Dazu: CreateNamespace=true,
Validate=false,
SkipDryRunOnMissingResource=true (CRD kommt im
selben Sync), RespectIgnoreDifferences=true,
PrunePropagationPolicy=background|orphan (Default
foreground).
spec:
syncPolicy:
automated: {prune: true, selfHeal: true}
syncOptions:
- ServerSideApply=true
- ApplyOutOfSyncOnly=true
- PruneLast=true
- CreateNamespace=true
---
# pro Ressource (Annotation):
metadata:
annotations:
argocd.argoproj.io/sync-options: Prune=false
Health & Custom Health
Health-Modell
Stati: Healthy, Progressing, Degraded, Suspended, Missing, Unknown. App-Health = schlechtester Zustand der direkten Kind-Ressourcen; Missing seit v3.4 nur, wenn alle fehlen.
Built-in-Checks u.a. für Deployment/StatefulSet/DaemonSet
(Generation + Replicas), LoadBalancer-Service und Ingress
(status.loadBalancer.ingress gefüllt), PVC
(Bound), Job/CronJob.
Custom Health (Lua)
Für CRDs ohne mitgelieferten Check (oder um ihn zu
überschreiben): Lua-Skript in
argocd-cm, Key
resource.customizations.health.<group>_<kind>.
Die Ressource liegt als obj vor, Rückgabe
hs.status + hs.message.
Standard-Lua-Libs sind aus Sicherheitsgründen per Default
deaktiviert.
# argocd-cm (ConfigMap, data:)
resource.customizations.health.db.example.com_Database: |
hs = {}
hs.status = "Progressing"
hs.message = "Warte auf Ready"
if obj.status ~= nil and obj.status.conditions ~= nil then
for _, c in ipairs(obj.status.conditions) do
if c.type == "Ready" and c.status ~= "Unknown" then
local ok = c.status == "True"
hs.status = ok and "Healthy" or "Degraded"
hs.message = c.message
end
end
end
return hs
Drift & Diff
ignoreDifferences
Erwartete Abweichungen ausblenden statt Dauer-OutOfSync:
jsonPointers (Feldpfad),
jqPathExpressions (Listenelemente selektieren),
managedFieldsManagers (alles eines Field-Managers,
z.B. kube-controller-manager).
Gilt per Default nur für den Diff, mit Sync-Option
RespectIgnoreDifferences=true auch beim Apply.
System-weit: resource.customizations.ignoreDifferences
in argocd-cm.
Seit v3.0 ignoriert der Vergleich status bei
allen Ressourcen (ignoreResourceStatusField: all).
Server-Side Diff rechnet per SSA-Dry-Run gegen
den API-Server, bei bestehenden Ressourcen greifen Defaults und
Validating Webhooks also schon im Diff (neue Ressourcen ohne
SSA-Dry-Run), Mutating Webhooks nur mit
IncludeMutationWebhook=true. Je App per
argocd.argoproj.io/compare-options: ServerSideDiff=true,
global per controller.diff.server.side: "true" in
argocd-cmd-params-cm.
spec:
ignoreDifferences:
- group: apps
kind: Deployment
jsonPointers:
- /spec/replicas # HPA steuert Replicas
- group: "*"
kind: "*"
managedFieldsManagers:
- kube-controller-manager
RBAC & SSO
RBAC (argocd-rbac-cm)
Casbin-Policies in policy.csv:
p, <subj>, <resource>, <action>, <object>, <effect>;
Gruppen-Mapping via g, <gruppe>, <rolle>.
Built-ins: role:readonly, role:admin.
policy.default gilt für jeden
authentifizierten Nutzer und lässt sich nicht per
deny-Regel aushebeln, restriktiv setzen.
Seit v3.0: logs, get ist eigenständig
nötig (nicht mehr von applications geerbt);
update/delete wirken nur noch auf die
App selbst (Sub-Ressourcen fine-grained).
# argocd-rbac-cm, policy.csv p, role:team-shop, applications, get, team-shop/*, allow p, role:team-shop, applications, sync, team-shop/*, allow p, role:team-shop, logs, get, team-shop/*, allow g, oidc:shop-devs, role:team-shop
SSO
dex als mitgelieferter Identity-Broker (OIDC,
SAML, LDAP, GitHub, ...) oder direktes OIDC über
oidc.config in argocd-cm.
Seit v3.0 mappt dex-RBAC auf
federated_claims.user_id statt sub,
bestehende Policies beim Upgrade anpassen.
Multi-Cluster
Cluster registrieren
CLI: argocd cluster add <context> legt im
Ziel-Cluster den ServiceAccount argocd-manager
(kube-system) an, gebunden an die ClusterRole
argocd-manager-role mit * auf alle
Ressourcen. Deklarativ
(GitOps-konform): Secret mit Label
argocd.argoproj.io/secret-type: cluster und Feldern
name, server, config.
Der eigene Cluster ist
https://kubernetes.default.svc. Repos analog:
secret-type: repository. Viele Cluster:
Controller-Sharding (siehe HA-Betrieb).
apiVersion: v1
kind: Secret
metadata:
name: prod-cluster
namespace: argocd
labels:
argocd.argoproj.io/secret-type: cluster
stringData:
name: prod
server: https://prod.example.com:6443
config: |
{"bearerToken": "<token>",
"tlsClientConfig": {"caData": "<b64-ca>"}}
Notifications
Trigger + Template + Service
argocd-notifications-cm definiert
Services (Slack, E-Mail, Webhook, PagerDuty,
...), Trigger (wann) und
Templates (was); ein mitgelieferter Katalog
deckt die Standardfälle ab. Abo pro App oder AppProject per
Annotation
notifications.argoproj.io/subscribe.<trigger>.<service>,
zentral über den Key subscriptions, optional mit
Label-Selector.
# argocd-notifications-cm (data:), zentral
subscriptions: |
- recipients: [slack:deploy-alerts]
triggers: [on-sync-failed, on-health-degraded]
selector: team=shop
Neu in v3.5
Highlights (04.08.2026)
Source Hydrator: beta (hydrator.enabled
in argocd-cmd-params-cm + commit-server). Argo CD
rendert aus der dry source (Chart/Kustomize) in einen
hydrated Branch, den der Sync dann liest. Neu: eigenes
Ziel-Repo (syncSource.repoURL) und Prüfung der dry
source per sourceIntegrity (alpha). Die Commits des
Hydrators sind unsigniert, eine Signaturpflicht auf dem hydrated
Branch lässt den Sync scheitern.
Impersonation: beta
(application.sync.impersonation.enabled in
argocd-cm, SA je Ziel über
destinationServiceAccounts im AppProject). Sync und
seit v3.5 auch Logs, Events, Delete und Resource Actions laufen
unter diesem SA statt unter dem des Controllers, die SAs brauchen
die Rechte dafür. ...impersonation.enforced: 'false'
fällt ohne Treffer auf den Controller-SA zurück und hebelt
die Trennung aus.
Helm 4.2 im Render-Pfad (vorher Helm 3),
helm.version: v3 wird ignoriert.
Plain-HTTP-OCI-Registries brauchen
--insecure-oci-force-http, auch Dependency-Registries
aus Chart.yaml, die dafür jetzt als eigenes Repo
registriert sein müssen. Nicht mit
--insecure-skip-server-verification in derselben Kette
kombinierbar.
Webhook-Jitter konfigurierbar: Refreshes nach Push laufen gestreut statt als Thundering Herd. Queue-Concurrency von ApplicationSet und Hydrator ebenfalls einstellbar.
Neue Health-Checks u.a. für GatewayClass.
Support-Fenster
Nur die drei jüngsten Minor-Linien bekommen Patches (aktuell 3.5, 3.4, 3.3), alles darunter gilt als EOL, auch für Security-Fixes. 3.6 ist für den 03.11.2026 geplant (rc1 seit 16.09.2026), damit fällt 3.3 aus dem Support. Ein Minor erscheint rund alle drei Monate, ein Cluster sollte also nicht mehr als drei Quartale zurückfallen.
Anti-Patterns
Was du nicht tun solltest
kubectl neben Argo CD: manuelle Edits sind
Drift; mit selfHeal sofort revertiert,
Änderungen gehören nach Git.
Alles im default-Projekt: kein
Blast-Radius-Limit, pro Team ein AppProject mit
sourceRepos/destinations schneiden.
Auto-Sync mit prune ohne Schutz: kritische
Ressourcen mit Prune=false oder
Prune=confirm markieren, PruneLast
nutzen.
Secrets im Klartext in Git: Argo CD bringt kein Secrets-Management mit, Sealed Secrets, External Secrets Operator o.ä. vorschalten.
ignoreDifferences als Pflaster: wer echten Drift ausblendet, verliert die Kernzusage von GitOps.
Verwandte Cheatsheets
Ebenfalls von OMNI52:
kubernetes-cheatsheet.de, Kubernetes Core
rke2-cheatsheet.de, RKE2-Distribution
rancher-cheatsheet.de, Rancher-Management
istio-cheatsheet.de, Service-Mesh-Layer (Istio in der Tiefe)
Lizenz & Weiterverteilung
Nicht erlaubt: Logo, Marken oder den Eindruck zu vermitteln, dass der Inhalt von dir/euch stammt oder dass OMNI52 GmbH die Weiterverwendung sponsort.
Volltext der Lizenz: creativecommons.org/licenses/by-sa/4.0/deed.de.
Argo is a registered trademark of The Linux Foundation (in the United States and/or other countries). Argo CD is a graduated project of the Cloud Native Computing Foundation (CNCF), part of The Linux Foundation. Kubernetes is a registered trademark of The Linux Foundation. OMNI52™ is a trademark of OMNI52 GmbH (filed, not yet registered). This website is operated by OMNI52 GmbH and is not affiliated with, endorsed by, or sponsored by The Linux Foundation or the Cloud Native Computing Foundation. “Argo CD” is used in a nominative / descriptive sense to indicate the technology this cheatsheet documents.