GitOps mit Kubernetes, Kustomize und Flux

Git informiert die Flux Controller, die Flux Controller holen den Soll-Zustand.

Mit GitOps ist es möglich, die Konfigurationen des Clusters in einem Git Repository zu verwalten. Dadurch wird eine versionierte Single Source of Truth geschaffen und eine Qualitätskontrolle durch protected branches, pull/merge requests und approvals ermöglicht.

Mein persönliches Highlight sind die Pipelines. Ich kann auf der Infrastruktur Tests laufen lassen, validieren, automatisieren und so z.B. sehr einfach Vorschauanwendungen deployen, in denen Entwickler und QA bereits einen bestimmten Stand testen können.

Das hier vorgestellte Tool Flux ist nur ein Weg und benötigt zwingend Kubernetes. Eine etwas unabhängigere Alternative wäre z.B. Terraform von HashiCorp.

Teil der Serie
  1. GitOps mit Kubernetes, Kustomize und Flux
  2. Preview Apps mit GitOps durch Flux und Kubernetes

Installieren link

Für die Installation und Updates wird die Flux CLI benötigt. Im Betrieb wird sie, außer für Statusanzeigen, nicht mehr benötigt. Eine Anleitung zur Installation des Up to Date CLI ist hier zu finden.

Einrichten link

Flux kann auf verschiedene Arten eingerichtet werden. Für diesen Beitrag habe ich mich für Github entschieden und verwende dort ein Personal Token.

Im ersten Schritt muss der Flux CLI ein GitHub Token und der dazugehörige User als ENV Variable übergeben werden.

export GITHUB_TOKEN=<token>
export GITHUB_USER=<username>

Mit dem Befehl bootstrap wird alles konfiguriert. Flux überprüft dazu den aktuellen Status und versucht diesen gegebenenfalls anzupassen. Wenn z.B. das angegebene Repository noch nicht existiert, wird Flux versuchen, es zu erstellen.

Das Flux CLI muss in einer Terminal-Session mit Kubernetes-Zugriff ausgeführt werden. Die Flux CLI wird gestartet, um die notwendigen Controller im Cluster zu installieren und um zu prüfen, ob sie noch funktionieren.

flux bootstrap github \
  --owner=$GITHUB_USER \
  --repository=repository \
  --branch=main \
  --path=./clusters/my-cluster \
  --personal

Parameter

  • owner Repository Owner (Orga oder User)
  • repository Repository Name
  • branch Git Branch
  • path Hauptverzeichnis für diesen Cluster
  • personal Definiert die Auth Methode für Github.

Antwort

► connecting to github.com
✔ repository created
✔ repository cloned
✚ generating manifests
✔ components manifests pushed
► installing components in flux-system namespace
deployment "source-controller" successfully rolled out
deployment "kustomize-controller" successfully rolled out
deployment "helm-controller" successfully rolled out
deployment "notification-controller" successfully rolled out
✔ install completed
► configuring deploy key
✔ deploy key configured
► generating sync manifests
✔ sync manifests pushed
► applying sync manifests
◎ waiting for cluster sync
✔ bootstrap finished

Was ist passiert? link

  • Repository wurde angelegt
  • Flux Konfigurationen wurden erstellt und zum Repository hinzugefügt
  • Die Flux Controller im Kubernetes Cluster wurden installiert
  • Flux überwacht ./clusters/my-cluster.

Flux erstellt seine Konfiguration im überwachten Verzeichnis. So kann die CLI diese Dateien einfach aktualisieren und die Flux-Controller im Kubernetes-Cluster aktualisieren sich selbst.

Mit dem Parameter path ist es möglich, mehrere Cluster aus dem gleichen Repository zu verwalten.

Repositories link

Der Kubernetes Cluster my-cluster hat jetzt einen Einstiegspunkt im Repository unter ./clusters/my-cluster. Flux bietet die Möglichkeit von diesem Einstiegspunkt weitere Repositories einzubinden.

Der Cluster schaut in einem Repository, in dem weitere definiert sind.

Eine mögliche Struktur könnte wie folgt aussehen:

  • gitops-infrastructure Cluster Definitionen
    • ./clusters/my-cluster
  • gitops-monitoring Monitoring
  • gitops-team-a Team Repositories

Flux definiert Repositories als Source. So können andere Repositories in das zuvor definierte Haupt-Repository eingebunden werden.

Diese Trennung hat mehrere Vorteile. Wenn Flux einen Fehler in der geänderten Konfiguration erkennt, wird das entsprechende Repository nicht auf den Cluster angewendet, bis der Fehler behoben ist. Einzelne Teile wie z.B. der Monitoring Stack können auf mehrere Cluster angewendet werden.

Zusätzlich hat jedes Team ein leeres Repository, in dem sie alles anfassen und ändern können, ohne sich mit dem darunter liegenden System beschäftigen zu müssen. Durch die Trennung kommen sich die Teams nicht in die Quere.

Source link

Für die Verwendung eines anderen Repositories muß dieses als Quelle hinzugefügt werden. Es ist auch möglich, die YAML-Datei direkt zu Schreiben. Der Befehl geht davon aus, dass er im Repository von oben ausgeführt wird.

flux create source git gitops-team-a \
  --url=https://github.com/<orga>/gitops-team-a \
  --branch=main \
  --interval=30s \
  --export > ./clusters/my-cluster/gitops-team-a-source.yaml

Der Befehl erstellt die folgende YAML-Datei in der Flux Cluster Definition. Das Repository wird von Flux alle 30 Sekunden überprüft (interval).

apiVersion: source.toolkit.fluxcd.io/v1beta2
kind: GitRepository
metadata:
  name: gitops-team-a
  namespace: flux-system
spec:
  interval: 30s
  ref:
    branch: main
  url: https://github.com/<orga>/gitops-team-a

Achtung: Der Befehl erzeugt nur die Datei. Damit Flux sie anwenden kann, muss die Datei im Main Branch Repository abgelegt werden. (git push).

Deployment link

Durch den Endpunkt ist Flux nun auch mit anderen Repositories vertraut. Damit Kubernetes Konfigurationen angewendet werden können, müssen Ordner als Flux Kustomization definiert werden. Wenn es keine Kustomize Datei im Ordner gibt, wird jede Datei im Ordner angewendet.

Team A hat in seinem Repository einen Ordner für Produktivumgebungen und einen Ordner für Stagingumgebungen. Um einen dieser Ordner auf den Cluster anwenden zu können, wird ein weiteres YAML im Infrastruktur-Repository benötigt.

flux create kustomization gitops-team-a-prod \
  --target-namespace=gitops-team-a-prod \
  --source=gitops-team-a \
  --path="./prod" \
  --prune=true \
  --interval=5m \
  --export > ./clusters/my-cluster/gitops-team-a-prod-kustomization.yaml

Parameter

  • target-namespace Namespace im Cluster
  • source Name der zuvor angelegten Source
  • path Pfad im Repository das als Source definiert wurde
  • prune Lösche vom Cluster wenn es nicht mehr im Git definiert ist
  • interval Überprüft den Stand alle 5 Minuten.
apiVersion: kustomize.toolkit.fluxcd.io/v1beta2
kind: Kustomization
metadata:
  name: gitops-team-a-prod
  namespace: flux-system
spec:
  interval: 5m0s
  path: ./prod
  prune: true
  sourceRef:
    kind: GitRepository
    name: gitops-team-a
  targetNamespace: gitops-team-a-prod