Flux CD Flux CD

Image-Updates mit Flux Image Automation automatisieren

Lass Flux neue Container-Image-Tags erkennen und in Git zurückcommitten.

15 min Fortgeschritten

In den meisten GitOps-Setups baut deine CI-Pipeline ein Image und committet dann den neuen Tag in das Konfigurations-Repository. Flux bietet eine Alternative: Zwei optionale Controller beobachten deine Container-Registry, wählen den neuesten Tag, der zu einer Regel passt, und committen die Änderung selbst nach Git. Der Cluster ändert sich weiterhin nur wegen eines Git-Commits, du behältst also den Audit-Trail. Diese Anleitung nutzt das öffentliche Image podinfo.

Wie die Teile zusammenpassen

Drei Ressourcen arbeiten zusammen:

  • ImageRepository scannt eine Registry nach den Tags eines Images.
  • ImagePolicy wählt aus dieser Liste einen Tag aus, zum Beispiel die höchste semantische Version in einem Bereich.
  • ImageUpdateAutomation bearbeitet das YAML in deinem Git-Repository dort, wo ein Marker es verlangt, und committet und pusht dann.

Alle drei nutzen die API image.toolkit.fluxcd.io/v1. Die ältere Version v1beta2 wurde in Flux 2.9 aus den CRDs entfernt, migriere also alte Manifeste, bevor du upgradest.

Die zusätzlichen Controller installieren

Die Image-Controller sind nicht Teil einer Standardinstallation. Führe Bootstrap erneut aus und füge sie hinzu, und erlaube Flux, in das Repository zu pushen:

flux bootstrap github \
  --owner=<your-github-user> \
  --repository=fleet-infra \
  --branch=main \
  --path=clusters/dev \
  --personal \
  --components-extra=image-reflector-controller,image-automation-controller \
  --read-write-key

Bootstrap kann gefahrlos wiederholt werden. Es committet die neuen Controller-Manifeste und installiert sie. --read-write-key macht den Deploy Key beschreibbar, damit die Automatisierung pushen kann. Prüfe mit kubectl get pods -n flux-system.

Die Registry scannen

apps/podinfo/image-repository.yaml, im selben Ordner wie dein Deployment:

apiVersion: image.toolkit.fluxcd.io/v1
kind: ImageRepository
metadata:
  name: podinfo
  namespace: flux-system
spec:
  image: ghcr.io/stefanprodan/podinfo
  interval: 5m

Für eine private Registry füge secretRef hinzu, das auf ein Docker-Registry-Secret zeigt, erstellt mit kubectl create secret docker-registry oder flux create secret oci.

Einen Tag mit einer Policy wählen

apiVersion: image.toolkit.fluxcd.io/v1
kind: ImagePolicy
metadata:
  name: podinfo
  namespace: flux-system
spec:
  imageRepositoryRef:
    name: podinfo
  policy:
    semver:
      range: 6.x

semver mit range: 6.x wählt die höchste 6.x-Version. Andere Policy-Typen sind numerical (höchste Zahl) und alphabetical, die für Tags wie Build-Nummern oder Datumsangaben passen. Für Regeln auf Basis von Tag-Namen füge der Policy filterTags mit einem regulären Ausdruck hinzu.

Die zu aktualisierende Zeile markieren

Flux aktualisiert genau die Zeilen, die du mit einem Kommentar markierst. In apps/podinfo/deployment.yaml:

    spec:
      containers:
        - name: podinfo
          image: ghcr.io/stefanprodan/podinfo:6.5.0 # {"$imagepolicy": "flux-system:podinfo"}

Der Marker ist namespace:policy-name. Standardmäßig ersetzt er die gesamte Image-Referenz. Um nur den Tag zu aktualisieren, nutze {"$imagepolicy": "flux-system:podinfo:tag"}; für Helm-Values oder Kustomize-images-Einträge funktioniert derselbe Marker in der Zeile, die den Tag enthält. Alles ohne Marker bleibt unangetastet.

Flux sagen, wie es committen soll

apiVersion: image.toolkit.fluxcd.io/v1
kind: ImageUpdateAutomation
metadata:
  name: flux-system
  namespace: flux-system
spec:
  interval: 30m
  sourceRef:
    kind: GitRepository
    name: flux-system
  git:
    checkout:
      ref:
        branch: main
    commit:
      author:
        name: fluxcdbot
        email: fluxcdbot@users.noreply.github.com
      messageTemplate: |
        Automated image update

        {{range .Changed.Changes}}
        - {{.OldValue}} -> {{.NewValue}}
        {{end}}
    push:
      branch: main
  update:
    path: ./apps
    strategy: Setters

Die wichtigen Teile:

  • sourceRef ist das Git-Repository, in das committet wird. Es muss beschreibbar sein, daher --read-write-key.
  • checkout.ref.branch ist der Branch, von dem aus gestartet wird, und push.branch der, auf den der Commit geht.
  • update.path begrenzt, welche Ordner nach Markern gescannt werden.
  • messageTemplate steuert die Commit-Nachricht, damit die Historie lesbar ist.

Direkt auf main zu pushen macht alles vollautomatisch. Während du Vertrauen aufbaust, pushe stattdessen auf einen separaten Branch (zum Beispiel push.branch: flux-image-updates) und merge einen Pull Request, wenn du zufrieden bist. Die Änderung erreicht den Cluster erst nach dem Merge.

Beim Arbeiten zusehen

Committe und pushe diese Dateien und prüfe dann jede Stufe:

flux get image repository
flux get image policy
flux get image update

Das Repository zeigt, wie viele Tags gescannt wurden, die Policy zeigt den ausgewählten Tag, und die Update-Automatisierung zeigt den letzten gepushten Commit. Ist der ausgewählte Tag neuer als der in deinem YAML, erscheint ein Commit in Git, und Flux wendet ihn dann wie jede andere Änderung an. Zum Debuggen nutze kubectl describe auf jedem Objekt: ein falscher Marker, ein Policy-Bereich, der nichts trifft, oder ein schreibgeschützter Deploy Key sind die üblichen Verdächtigen.

Welchen Ansatz du wählst

Nutze CI-gesteuerte Commits, wenn eine Pipeline bereits die Promotion besitzt und du einen einzelnen Ort willst, der entscheidet, was ausgeliefert wird. Nutze Flux Image Automation, wenn das Konfigurations-Repository des Clusters von selbst einer Registry folgen soll, zum Beispiel um eine Dev-Umgebung auf dem neuesten Patch-Release zu halten. Beide können nebeneinander existieren.

Beliebte Anleitungen