Flux CD Flux CD

Secrets in Git mit SOPS und age verwalten

Verschlüssele Kubernetes-Secrets vor dem Committen und lass Flux sie im Cluster entschlüsseln.

12 min Fortgeschritten

GitOps legt die Konfiguration deines Clusters in Git, und das schließt Secrets ein. Ein einfaches Kubernetes-Secret zu committen legt seine Werte jedem offen, der das Repository lesen kann, denn Secret-Daten sind nur Base64-kodiert. Fluxs kustomize-controller kann Dateien entschlüsseln, die mit Mozilla SOPS verschlüsselt wurden, sodass du verschlüsselte Secrets committen und das gesamte System in Git halten kannst. Diese Anleitung nutzt age-Schlüssel, die einfachste Option.

Die Werkzeuge installieren und einen Schlüssel erstellen

Installiere age und sops (zum Beispiel brew install age sops) und erzeuge dann ein Schlüsselpaar:

age-keygen -o age.agekey

Die Ausgabedatei enthält den privaten Schlüssel, und der Befehl gibt den öffentlichen Schlüssel aus (er beginnt mit age1). Halte den privaten Schlüssel aus Git heraus. Sichere ihn an einem sicheren Ort, denn wenn du ihn verlierst, kannst du deine Secrets nicht mehr entschlüsseln. Flux 2.9 fügt außerdem Unterstützung für agens post-quantum-Chiffre hinzu, falls deine Richtlinien das verlangen.

Dem Cluster den privaten Schlüssel geben

Speichere den privaten Schlüssel als Secret im selben Namespace wie die Flux-Kustomization, die ihn nutzen wird:

kubectl create secret generic sops-age \
  --namespace=flux-system \
  --from-file=age.agekey=/dev/stdin < age.agekey

Der Schlüssel im Secret muss auf .agekey enden. Lösche die lokale Datei age.agekey oder verschiebe sie in einen Passwortmanager, sobald sie anderswo sicher gespeichert ist.

SOPS im Repository konfigurieren

Erstelle .sops.yaml im Stammverzeichnis deines Repositorys, damit alle auf dieselbe Weise verschlüsseln. Ersetze den Schlüssel durch deinen öffentlichen Schlüssel:

creation_rules:
  - path_regex: .*\.yaml
    encrypted_regex: ^(data|stringData)$
    age: age1xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx

encrypted_regex verschlüsselt nur die Felder data und stringData, sodass alles andere im Manifest zur Prüfung und zur Verarbeitung durch Flux lesbar bleibt. Du kannst mehrere age-Empfänger auflisten (kommagetrennt), sodass Teammitglieder und der Cluster-Schlüssel alle entschlüsseln können.

Ein Secret verschlüsseln

Schreibe das Secret-Manifest lokal, zum Beispiel apps/webapp/db-credentials.yaml:

apiVersion: v1
kind: Secret
metadata:
  name: db-credentials
  namespace: webapp
stringData:
  username: webapp
  password: s3cr3t-value

Verschlüssele es an Ort und Stelle:

sops --encrypt --in-place apps/webapp/db-credentials.yaml

Öffne die Datei: Die Werte von username und password sind nun Chiffretext, und ein sops:-Block mit Metadaten wurde hinzugefügt. Sie ist sicher zu committen. Zum späteren Bearbeiten führe sops apps/webapp/db-credentials.yaml aus, was in deinem Editor entschlüsselt und beim Speichern neu verschlüsselt. Um zu prüfen, was du committen willst, stelle sicher, dass die Werte nicht mehr lesbar sind.

Flux das Entschlüsseln mitteilen

Füge der Flux-Kustomization, die den Ordner anwendet, einen decryption-Block hinzu:

apiVersion: kustomize.toolkit.fluxcd.io/v1
kind: Kustomization
metadata:
  name: webapp
  namespace: flux-system
spec:
  interval: 10m
  sourceRef:
    kind: GitRepository
    name: flux-system
  path: ./apps/webapp
  prune: true
  decryption:
    provider: sops
    secretRef:
      name: sops-age

Committe und pushe. Beim Abgleich entschlüsselt der kustomize-controller die Datei im Speicher und wendet ein normales Secret auf den Cluster an. Prüfe es:

flux reconcile kustomization webapp --with-source
kubectl get secret db-credentials -n webapp

Fehlersuche und gute Praxis

Meldet die Kustomization einen Entschlüsselungsfehler, prüfe, ob das Secret sops-age im selben Namespace wie die Kustomization existiert, ob sein Schlüsselname auf .agekey endet und ob die Datei mit dem passenden öffentlichen Schlüssel verschlüsselt wurde. kubectl describe kustomization webapp -n flux-system zeigt den Fehler.

  • Nutze pro Umgebung einen anderen Schlüssel, damit ein Dev-Schlüssel keine Produktions-Secrets lesen kann.
  • Rotiere Schlüssel, indem du den neuen Empfänger hinzufügst, neu verschlüsselst (sops updatekeys) und dann den alten entfernst.
  • Cloud-KMS-Schlüssel (AWS KMS, Azure Key Vault, Google Cloud KMS) sowie HashiCorp Vault oder OpenBao funktionieren ebenfalls und vermeiden die Verteilung von Schlüsseldateien. Konfiguriere sie mit Workload Identity und lass secretRef weg, wo die Plattform Zugangsdaten bereitstellt.
  • Wenn du Secrets lieber ganz aus Git heraushalten willst, nutze den External Secrets Operator, um sie aus einem Tresor zu synchronisieren, und lass Flux nur die ExternalSecret-Objekte verwalten.

Beliebte Anleitungen