Cheatsheet im Volltext
Derselbe Inhalt wie im PDF, zum Mitlesen, Durchsuchen und direkten Kopieren der YAML-Snippets. Stand: Flux v2.10.0 (Edition 2026.11).
Architektur & GitOps-Toolkit
Pull statt Push
Flux zieht den deklarierten Zustand aus Git, OCI-Registries
oder Buckets und wendet ihn kontinuierlich an. Quelle =
Wahrheit: was nicht im Repo steht, gehört nicht in den
Cluster. Jede Ressource trägt ihr eigenes
interval; Änderungen laufen über Git-Push,
nicht über kubectl.
Controller & CRDs
source-controller: GitRepository, OCIRepository, HelmRepository, HelmChart, Bucket. kustomize-controller: Kustomization (inkl. SOPS-Decryption). helm-controller: HelmRelease.
notification-controller: Provider, Alert, Receiver (Webhooks). image-reflector-/image-automation-controller (optional): ImageRepository, ImagePolicy, ImageUpdateAutomation.
source-watcher (optional): ArtifactGenerator
(v1beta1), erzeugt ExternalArtifact
(source.toolkit.fluxcd.io/v1). Optionale Controller
per --components-extra zuschalten.
flux check # Prereqs + Controller-Status flux get all -A # Status aller Flux-Ressourcen kubectl get fluxcd -A # alle Flux-CRs (Resource-Kategorie)
Neu in v2.10
Highlights
SPIFFE-mTLS zwischen den Controllern: Artefakt-Abruf, Events und Webhooks einzeln per Flag, X.509-SVIDs etwa aus SPIRE.
Object Identity GA (vorher object-level
workload identity): Flux-Objekte authentisieren sich über
ihren serviceAccountName, Provider per SA-Annotation
credential.auth.fluxcd.io/provider
(kubernetes oder spiffe);
provider: generic für OCI und Images nimmt
SA-Tokens.
Alert/Provider v1, neue Typen
zoom, incident.io,
mastodon; ArtifactGenerator über Namespaces
hinweg.
Upgrade auf 2.10
Kubernetes ab 1.35.2, 1.36.1 bzw. 1.37.0; 1.34 (seit 27.10.2026 EOL) vorher heben.
Default-RBAC ohne create auf
serviceaccounts/token: für Object Identity mit
Provider kubernetes an source-, notification- oder
image-*-controller vorher eine ClusterRole binden
(fluxcd/flux2#6139).
image-reflector-controller speichert Tags im
Flux-Artefaktspeicher statt in BadgerDB; der erste Lauf scannt
jede ImageRepository neu, Opt-out
--feature-gates=FluxStorage=false.
Alert/Provider v1beta3 ist deprecated; nach
v1 entfallen spec.summary,
spec.interval, spec.proxy, das
statische JWT für Azure Event Hub und TLS/Proxy im
secretRef (Ersatz
eventMetadata.summary, certSecretRef,
proxySecretRef). flux migrate (Storage),
flux migrate -f <dir> (Repo), gemischte Flotte
mit -v 2.9.
kubeConfig.configMapRef: statt Key
audiences die SA-Annotation
credential.auth.fluxcd.io/audiences.
Ablauf: Upgrade Procedure for Flux v2.7+ (fluxcd/flux2 Discussion #5572).
Stand v2.10.0 (26.10.2026): source-/kustomize-controller
v1.10.1, notification v1.10.0, helm
v1.7.1 (Helm 4.3.1), image-* v1.3.0,
source-watcher v2.3.1.
Bootstrap
flux bootstrap
Installiert source-, kustomize-, helm- und
notification-controller nach flux-system (Image
Automation per --components-extra), pusht die
eigenen Manifeste unter --path ins Repo
und synct sich ab dann selbst. Idempotent: erneuter Lauf mit
gleichen Argumenten ist der Upgrade-Pfad.
Ohne --token-auth legt bootstrap einen read-only
Deploy-Key an (Image Automation braucht
--read-write-key=true); mit
--token-auth landet der PAT als Secret
flux-system im Cluster.
Alternative zu flux bootstrap: Flux Operator
(Open Source, Flux-Ökosystem) mit FluxInstance
(fluxcd.controlplane.io/v1);
.spec.cluster.multitenant: true schaltet den
Lockdown.
export GITHUB_TOKEN=<pat> flux bootstrap github \ --owner=example-org --repository=fleet \ --branch=main --path=clusters/prod
Repo-Layout pro Cluster
--path=clusters/<name> gibt jedem Cluster
einen eigenen Einstiegspunkt im selben Repo. Infrastruktur (CRDs,
Operatoren, Ingress) und Apps als getrennte Kustomizations
verketten, dependsOn erzwingt die
Reihenfolge.
Sources
GitRepository & OCIRepository
url + interval + ref:
Git per branch, tag,
semver oder commit; OCI per
tag, semver oder digest.
Auth via secretRef oder provider: Git
azure/aws, OCI
aws/azure/gcp per Workload
Identity, Git github per GitHub App (App-Key und
githubAppID oder seit 2.10
githubAppClientID im secretRef).
OCIRepository liefert Manifeste als OCI-Artefakt inkl.
Signatur-Prüfung (verify: cosign/notation),
GitRepository prüft Commits per OpenPGP oder seit 2.9 per
SSH-Key.
HelmRepository & Bucket
HelmRepository: HTTP/S-Index; type: oci ist im
Wartungsmodus, OCI-Charts per OCIRepository
(chartRef oder seit 2.10 chart.kind). Bucket: S3-kompatibel, per
provider auch GCS und Azure Blob. Jede Source
produziert ein versioniertes Artefakt, auf das
Kustomization/HelmRelease per sourceRef zeigen.
apiVersion: source.toolkit.fluxcd.io/v1
kind: GitRepository
metadata: {name: platform, namespace: flux-system}
spec:
interval: 1m
url: https://github.com/example-org/platform
ref: {branch: main} # oder tag/semver/commit
secretRef: {name: git-auth}
---
apiVersion: source.toolkit.fluxcd.io/v1
kind: OCIRepository
metadata: {name: manifests, namespace: flux-system}
spec:
interval: 5m
url: oci://ghcr.io/example-org/manifests
ref: {semver: ">=1.0.0 <2.0.0"}
Kustomization
Spec-Kern
path: Verzeichnis im Source-Artefakt.
prune: true: Garbage-Collection gelöschter
Manifeste. sourceRef: GitRepository, OCIRepository,
Bucket oder ExternalArtifact (Feature-Gate
ExternalArtifact, setzt bootstrap mit
source-watcher).
retryInterval steuert Fehler-Retries getrennt vom
regulären interval;
serviceAccountName erzwingt Impersonation
(RBAC-Grenze), targetNamespace zwingt alle Objekte
in einen Namespace. ignore (seit 2.9) nimmt Felder
fremder Controller aus Drift-Check und Apply aus.
apiVersion: kustomize.toolkit.fluxcd.io/v1
kind: Kustomization
metadata: {name: apps, namespace: flux-system}
spec:
interval: 10m
retryInterval: 2m
path: ./apps/production
prune: true # Garbage Collection
sourceRef: {kind: GitRepository, name: platform}
dependsOn:
- name: infrastructure
wait: true # Health aller Objekte
timeout: 5m
postBuild:
substituteFrom:
- kind: ConfigMap
name: cluster-vars
ignore: # seit 2.9
- target: {kind: Deployment}
paths: ["/spec/replicas"] # HPA
Health & Reihenfolge
wait: true prüft die Health aller
applizierten Objekte, healthChecks gezielt einzelne
(Deployment, HelmRelease, …). dependsOn gated
nachgelagerte Kustomizations, bis die Abhängigkeit Ready ist.
Standard-Muster: infrastructure vor apps.
postBuild-Substitution
postBuild.substituteFrom ersetzt
${var}-Platzhalter aus ConfigMaps/Secrets,
cluster-spezifische Werte (Domain, Zone, Replicas) ohne
Overlay-Wildwuchs. optional: true toleriert fehlende
Quellen.
HelmRelease
Chart-Referenz
chart.spec + sourceRef
(HelmRepository, GitRepository, Bucket) erzeugt eine HelmChart.
Seit 2.10 legt chart.kind: OCIRepository mit
spec.url eine OCIRepository im Namespace der
HelmRelease an, Version und Values stehen dann in einem Objekt.
chartRef nutzt eine vorhandene OCIRepository,
HelmChart oder ExternalArtifact. SemVer-Ranges
(6.x, >=0.2.0 <1.0.0) wählen
die höchste passende Version.
apiVersion: helm.toolkit.fluxcd.io/v2
kind: HelmRelease
metadata: {name: podinfo, namespace: apps}
spec:
interval: 30m
chart:
kind: OCIRepository # seit 2.10
spec:
url: oci://ghcr.io/stefanprodan/charts/podinfo
ref: {semver: ">=6.0.0 <7.0.0"}
install: {remediation: {retries: 3}}
upgrade: {remediation: {retries: 3, strategy: rollback}}
driftDetection: {mode: enabled}
valuesFrom: [{kind: Secret, name: podinfo-values}]
values:
replicaCount: 2
Remediation & Drift
remediation.retries (Install, Upgrade):
automatische Wiederholung fehlgeschlagener Releases; strategy:
rollback oder uninstall.
driftDetection.mode: enabled erkennt und korrigiert
manuelle Änderungen am Release-Inventar (warn
meldet nur). test.enable führt Helm-Tests nach
Install/Upgrade aus.
Helm 4 (seit 2.8)
helm-controller arbeitet mit dem Helm-4-SDK (v2.10: 4.3.1). Neue
Releases laufen per Server-Side Apply
(install.serverSideApply, Default
true), bestehende bleiben auf Client-Side Apply, bis
upgrade.serverSideApply: enabled (Default
auto) sie umstellt. Health-Checks laufen für
alle Releases über kstatus
(waitStrategy.name: poller). Seit 2.9 laufen Hooks
durch die Post-Renderer (postRenderStrategy:
combined). Je Release zurück per
waitStrategy: {name: legacy} bzw.
postRenderStrategy: nohooks, global per
Feature-Gate UseHelm3Defaults.
Reconciliation & Betrieb
Intervalle & Trigger
Jede Ressource reconciled periodisch (interval);
flux reconcile … --with-source stößt
sofort an, samt Source-Fetch. Push statt Polling:
Receiver (notification-controller) nimmt
Webhooks von GitHub/GitLab an, Typ generic-oidc
(seit 2.9) prüft ein OIDC-Token statt eines Shared Secrets.
Provider/Alert melden Events an
Chat-, Incident- oder Webhook-Endpunkte.
suspend / resume
flux suspend hält die Reconciliation an
(Incident-Freeze, Wartungsfenster), flux resume
nimmt sie wieder auf. Suspendierte Objekte driften still,
Freeze immer zeitlich begrenzen.
flux reconcile ks/apps --with-source # ab 2.10 flux reconcile source git platform flux suspend kustomization apps flux resume kustomization apps flux get kustomizations --watch
Image Automation
Drei CRDs
ImageRepository scannt Registry-Tags,
ImagePolicy wählt den Ziel-Tag
(semver.range, alphabetisch, numerisch, Vorfilter
filterTags), ImageUpdateAutomation
committet den neuen Tag per Setters-Marker ins Repo. Seit 2.10
bündelt policyChangeDelay Updates in einen
Commit, GitPushRetryOnFailure (Gate, opt-in)
wiederholt abgelehnte Pushes.
apiVersion: image.toolkit.fluxcd.io/v1
kind: ImagePolicy
metadata: {name: podinfo, namespace: flux-system}
spec:
imageRepositoryRef: {name: podinfo}
policy:
semver: {range: 6.x}
# Setters-Marker (gleiche Zeile!) im Ziel-Manifest:
# tag: 6.9.0 # {"$imagepolicy": "flux-system:podinfo:tag"}
Multi-Tenancy
Lockdown: Flags am Controller
--no-cross-namespace-refs=true (kustomize, helm,
notification, image-*, source-watcher) verbietet Sources aus
fremden Namespaces, --no-remote-bases=true
(kustomize) Kustomize-Remote-Bases. Mit
--default-service-account=default (kustomize, helm,
ab 2.10 source-watcher, dort nur für Artefakte in fremden
Namespaces) laufen Objekte ohne
serviceAccountName mit dem rechtelosen
Default-Account des Tenant-Namespaces. Die
flux-system-Kustomization braucht dann
serviceAccountName: kustomize-controller.
Object Identity: dasselbe Flag auf source-, notification- und
image-*-controller, dazu
--default-kubeconfig-service-account (kustomize, helm)
und --default-decryption-service-account
(kustomize).
# clusters/prod/flux-system/kustomization.yaml
patches:
- patch: |
- op: add
path: /spec/template/spec/containers/0/args/-
value: --no-cross-namespace-refs=true
target:
kind: Deployment
name: "(kustomize|helm|notification|image-.*)-controller"
- patch: |
- op: add
path: /spec/template/spec/containers/0/args/-
value: --no-cross-namespace-refs=true
target: {kind: Deployment, name: source-watcher}
- patch: |
- op: add
path: /spec/template/spec/containers/0/args/-
value: --no-remote-bases=true
target: {kind: Deployment, name: kustomize-controller}
- patch: |
- op: add
path: /spec/template/spec/containers/0/args/-
value: --default-service-account=default
target: # source-watcher erst ab 2.10
kind: Deployment
name: "(kustomize|helm)-controller|source-watcher"
- patch: |
- op: add
path: /spec/serviceAccountName
value: kustomize-controller
target: {kind: Kustomization, name: flux-system}
Secrets: SOPS & age
Verschlüsselt ins Repo
Secrets liegen SOPS-verschlüsselt im Git; der
kustomize-controller entschlüsselt beim Apply
(decryption.provider: sops). Private Key als Secret
sops-age in flux-system (Key-Datei muss
auf .agekey enden). Nur
data/stringData verschlüsseln,
die Manifest-Struktur bleibt diff-bar.
age-keygen -o age.agekey cat age.agekey | kubectl create secret generic \ sops-age --namespace=flux-system \ --from-file=age.agekey=/dev/stdin sops --age=<public-key> --encrypt \ --encrypted-regex '^(data|stringData)$' \ --in-place basic-auth.yaml
# Kustomization-Ausschnitt:
spec:
decryption:
provider: sops
secretRef: {name: sops-age}
Diagnose (flux CLI)
Vom Symptom zur Quelle
flux trace zeigt für ein beliebiges
Cluster-Objekt, welche Kustomization/HelmRelease und welche
Source es verwaltet, der schnellste Einstieg, wenn unklar
ist, woher ein Objekt kommt.
Status & Events
flux get pro Kind oder all,
--watch für Live-Status. flux events
filtert Kubernetes-Events auf Flux-Ressourcen
(--for Kind/name). flux logs aggregiert
die Controller-Logs (--level=error).
flux trace -n apps deployment my-app flux events --for Kustomization/apps flux logs --level=error --all-namespaces
Anti-Patterns
Was du nicht tun solltest
kubectl apply am Repo vorbei: die
nächste Reconciliation überschreibt den Hotfix still.
Änderungen gehören ins Repo; Notfall-Stopp ist
flux suspend.
prune: false als Dauerzustand: gelöschte Manifeste bleiben als Waisen im Cluster stehen: Drift, den niemand mehr sieht.
Eine Mega-Kustomization: CRDs, Operatoren und
deren Custom Resources in einem Apply racen gegeneinander.
Aufteilen + dependsOn/healthChecks.
Mutable Tags ohne Digest: ImagePolicy
wählt per Tag-Sortierung, ein neu gepushtes
latest bliebe unbemerkt. Besser unveränderliche
SemVer-Tags. Muss es latest sein:
filterTags.pattern: '^latest$' +
policy.alphabetical,
digestReflectionPolicy: Always +
interval, Setter-Marker :digest.
Klartext-Secrets im Repo: SOPS/age gehört vor das erste Secret-Commit ins Setup, nicht danach.
Multi-Tenant ohne Lockdown: ohne
--no-cross-namespace-refs und
Default-ServiceAccount greift jeder Tenant auf fremde Sources
zu.