DEV Community

Uhltak Therestismysecret
Uhltak Therestismysecret

Posted on

GitOps mit FluxCD: Kubernetes ohne kubectl apply automatisieren

Hook – Der tägliche Kampf mit kubectl apply

Sie kennen das: In der Sprint‑Retrospektive fragt Ihr Lead‑Dev, warum das Production‑Cluster immer noch einen "manuellen" kubectl apply‑Befehl erfordert. Die Antwort ist oft ein kurzer Satz wie "es ist schneller, ich patche das gleich“ – und das war's. Das klingt nach Pragmatismus, wirkt aber bei genauerem Hinsehen wie ein Sicherheitsloch im Deploy‑Prozess. Hier kommen GitOps und FluxCD ins Spiel: Sie ermöglichen, dass jede Änderung am Cluster nur über Git erfolgt. Das bedeutet weniger menschliche Fehler, klare Audits und, ja, keine kubectl apply‑Explosion mehr.

Persönliche Einschätzung: In meinem zehn‑jährigen Leben als Linux‑ und Cloud‑Profi habe ich mehr Produktionsausfälle durch vergessene kubectl apply‑Befehle erlebt als durch jede andere Ursache. FluxCD hat das Spiel für uns komplett verändert.


Was ist GitOps und warum kubectl apply nicht reicht

GitOps ist kein Buzzword, sondern ein klar definierter Ansatz:

  1. Source of Truth ist ein Git‑Repository.
  2. Reconciliation wird vom Operator (hier Flux) kontinuierlich durchgeführt.
  3. Rollback erfolgt durch ein einfacher Git‑Commit.

kubectl apply bricht diesen Kreislauf sofort. Der Befehl mutiert das Cluster direkt, ohne dass ein Commit entsteht. Das bedeutet:

  • Kein nachvollziehbarer Audit‑Log.
  • Manuelle Zustandsabweichungen, die bei einer Skalierung schnell unbemerkt bleiben.
  • Kein automatischer Rollback, weil das vorherige Manifest nicht versioniert ist.

Einschätzung: Wer kubectl apply als Herzstück eines Produktions‑Deploy‑Workflows nutzt, führt im Grunde ein „Git‑Minus‑Ops“ – das ist ein Rezept für „Feature‑Freeze mit Überraschungen“.


FluxCD im Überblick – Der leise GitOps‑Operator

FluxCD ist ein CNCF‑Projekt, das declarative Kubernetes‑Manifeste synchronisiert. Die wichtigsten Komponenten sind:

  • source-controller: Beobachtet Git‑Repos, Helm‑Charts oder OCI‑Registries.
  • kustomize-controller: Transformiert Kustomize‑Bases.
  • helm-controller: Installiert und aktualisiert Helm‑Releases.
  • notification-controller: Schickt Webhooks an Slack, Teams o. Ä.

Warum Flux statt ArgoCD?

  • Native Kubernetes‑CRDs – alles läuft als Pods, keine eigenständige UI nötig.
  • Kompatibilität mit Helm 3, Kustomize und OCI‑Images.
  • Leichtgewichtiger Footprint (≈ 30 MiB RAM, 2 CPU‑Kerne).

Meine Meinung: In kleinen bis mittleren Teams ist Flux fast immer die bessere Wahl, weil es sich nahtlos in bestehende CI‑Pipelines einfügt und kaum Overhead erzeugt.


Einrichtung von FluxCD – Schritt‑für‑Schritt‑Tutorial

Hinweis: Alle Befehle setzen voraus, dass kubectl bereits auf Ihr Cluster konfiguriert ist und Sie ein lokales Git‑Repo mit den Deploy‑Manifests besitzen.

1. Flux‑Installation (CLI‑basiert)

# Installiere die neueste Flux‑Version
curl -s https://fluxcd.io/install.sh | sudo bash
# Prüfe die Installation
flux version
Enter fullscreen mode Exit fullscreen mode

Einschätzung: Das Skript lädt das Binary in /usr/local/bin. Auf produktiven Nodes nutze lieber ein Package‑Manager‑Repo, um Sicherheits‑Scans zu ermöglichen.

2. Bootstrap in ein Git‑Repo (Git‑Ops‑First)

# Erstelle ein neues Repository auf GitHub (oder GitLab)
# Beispiel: git@github.com:myorg/infra.git

# Bootstrapen – Flux legt automatisch die system‑Namespace, Source und Kustomization an
flux bootstrap github \
  --owner=myorg \
  --repository=infra \
  --branch=main \
  --path=./clusters/production
Enter fullscreen mode Exit fullscreen mode

Einschätzung: Der bootstrap‑Befehl schreibt ein flux-system‑Namespace und die zugehörigen CRDs. Jetzt hat das Team einen single source of truth.

3. Hinzufügen einer neuen Anwendung

flux create source git my-app \
  --url=https://github.com/myorg/my-app.git \
  --branch=main \
  --interval=1m

flux create kustomization my-app \
  --source=GitRepository/my-app \
  --path=./k8s/production \
  --prune=true \
  --validation=client \
  --interval=5m
Enter fullscreen mode Exit fullscreen mode

Einschätzung: Mit --prune=true stellt Flux sicher, dass gelöschte Ressourcen auch im Cluster entfernt werden – ein echter Vorteil gegenüber manuellem apply.


Praktische Beispiele – Drei reale Deploy‑Szenarien

Beispiel 1: Standard‑Deployment einer NGINX‑App

Manifest (k8s/production/nginx.yaml):

apiVersion: apps/v1
kind: Deployment
metadata:
  name: nginx
  labels:
    app: nginx
spec:
  replicas: 3
  selector:
    matchLabels:
      app: nginx
  template:
    metadata:
      labels:
        app: nginx
    spec:
      containers:
      - name: nginx
        image: nginx:1.25-alpine
        ports:
        - containerPort: 80
---
apiVersion: v1
kind: Service
metadata:
  name: nginx-svc
spec:
  selector:
    app: nginx
  ports:
  - port: 80
    targetPort: 80
  type: ClusterIP
Enter fullscreen mode Exit fullscreen mode

Deploy‑Befehl (nur commit & push):

git add k8s/production/nginx.yaml
git commit -m "Add nginx deployment"
git push origin main
Enter fullscreen mode Exit fullscreen mode

Flux erkennt die Änderung innerhalb von 30 Sekunden (Standard‑Interval) und rollt das Deployment automatisch aus.

Meine Sicht: Das ist das Kernstück von GitOps – kein kubectl apply mehr, nur ein Commit.

Beispiel 2: Automatisches Image‑Update mit image‑automation-controller

flux create image policy nginx-policy \
  --image=nginx \
  --interval=1h

flux create image update nginx-update \
  --image=nginx \
  --policy=nginx-policy \
  --target=Deployment/nginx \
  --container=nginx
Enter fullscreen mode Exit fullscreen mode

Jetzt prüft Flux stündlich das Docker‑Hub‑Repository. Sobald ein neuer Tag (z. B. 1.26-alpine) erscheint, wird das Manifest automatisch aktualisiert und ein Pull‑Request im Git‑Repo erstellt.

Einschätzung: Durch die Trennung von Policy und Update haben Sie volle Kontrolle – keine Überraschungen durch ungetestete Tags.

Beispiel 3: Helm‑Release mit Flux + SOPS‑verschlüsseltem Secret

HelmRelease (helm/myapp.yaml):

apiVersion: helm.toolkit.fluxcd.io/v2beta1
kind: HelmRelease
metadata:
  name: myapp
spec:
  chart:
    spec:
      chart: mychart
      sourceRef:
        kind: HelmRepository
        name: myrepo
  values:
    replicaCount: 2
    image:
      repository: myorg/myapp
      tag: "{{ .Values.imageTag }}"
    secret:
      name: myapp-secret
      data: "{{ .Values.secret }}"
Enter fullscreen mode Exit fullscreen mode

Secret (verschlüsselt mit SOPS):

apiVersion: v1
kind: Secret
metadata:
  name: myapp-secret
stringData:
  password: ENC[AES256_GCM,data:...,tag:...]
Enter fullscreen mode Exit fullscreen mode

Einrichtung:

flux create source helm myrepo \
  --url=https://charts.myorg.com \
  --interval=10m

flux create helmrelease myapp \
  --source=HelmRepository/myrepo \
  --chart=mychart \
  --interval=5m \
  --values=./helm/values.yaml
Enter fullscreen mode Exit fullscreen mode

Durch das Zusammenspiel von Flux, Helm und SOPS erhalten Sie ein komplett deklaratives Deployment, das sichere Secrets handhabt.

Bewertung: In meiner Praxis konnten wir mit dieser Kombination die Zeit von Secret‑Erstellung bis Produktiv‑Rollout von Stunden auf wenige Minuten reduzieren.


Häufige Fehler – Und wie Sie sie vermeiden

  1. Vergessenes prune bei Kustomizations – Ressourcen bleiben „Orphaned“. Lösung: Immer --prune=true setzen.
  2. Unsichere Secrets ohne Verschlüsselung – Git wird zum Daten‑Leak‑Kanal. Lösung: SOPS + age oder GPG nutzen.
  3. Zu kurzer Sync‑Intervall – Flux versucht zu häufig zu reconciliieren, was API‑Rate‑Limits auslösen kann. Lösung: Realistische Werte (5m für Deployments, 1h für Image‑Policies).
  4. Manuelle kubectl‑Interventionen – Dieser Shortcut bricht die Git‑Truth‑Chain. Lösung: Nutzen Sie flux suspend für geplante Wartungen, nicht direkte kubectl‑Befehle.
  5. Fehlende RBAC‑Berechtigungen für Flux‑ServiceAccount – Crash‑Loops beim Start. Lösung: Minimal‑Policy wie cluster-admin nur im Test, im Prod ein dediziertes Role‑Binding.

Mein Tipp: Setzen Sie einen Git‑Hook ein, der prüft, ob das Repository vor jedem Push einen kubectl‑Befehl enthält. So verhindern Sie versehentliche Live‑Changes.


Fazit – Der nächste konkrete Schritt

FluxCD macht GitOps greifbar: Kein manuelles kubectl apply, vollständige Audits, automatisierte Rollbacks. Wenn Sie noch nicht auf GitOps umgestiegen sind, starten Sie mit einem kleinen Pilot‑Cluster (z. B. k3s), bootstrapen Sie Flux und migrieren Sie ein simples NGINX‑Deployment. Sobald das funktioniert, erweitern Sie schrittweise um Helm‑Releases, Image‑Policies und SOPS‑Secrets.

Sofortiger Action‑Plan

  1. Installieren Sie die Flux‑CLI auf Ihrem Admin‑Workstation.
  2. Bootstrapen Sie ein Git‑Repo (idealerweise in einem dedizierten „infra“-Projekt).
  3. Deployen Sie eine Test‑App (NGINX) über das neue Git‑Repository.
  4. Setzen Sie ein Image‑Policy‑Beispiel auf, um automatische Updates zu testen.
  5. Fügen Sie ein verschlüsseltes Secret hinzu und schauen Sie, wie Flux die Helm‑Release aktualisiert.

Wenn Sie diese fünf Schritte durchlaufen, haben Sie nicht nur einen funktionierenden GitOps‑Workflow, sondern auch die Basis für skalierbare, sichere und wiederholbare Deployments in jedem Kubernetes‑Cluster.

Auf geht’s – geben Sie Ihrem Team das Werkzeug, das Sie wirklich verdient haben: GitOps mit FluxCD.

Top comments (0)