· Kubernetes  · 4 Min. Lesezeit

Ein gewachsenes Cluster nach ArgoCD holen, ohne etwas kaputtzumachen

Bestehende Workloads deklarativ unter ArgoCD-Verwaltung bringen, ohne sie neu auszurollen. Das Adopt-Muster Schritt für Schritt, und die vier Fallen, die dabei aus einem harmlosen Diff plötzlich Duplikate machen.

Bestehende Workloads deklarativ unter ArgoCD-Verwaltung bringen, ohne sie neu auszurollen. Das Adopt-Muster Schritt für Schritt, und die vier Fallen, die dabei aus einem harmlosen Diff plötzlich Duplikate machen.

GitOps klingt einfach, solange man auf der grünen Wiese startet. In der Praxis steht aber meist schon ein Cluster mit laufenden, von Hand oder per Katalog installierten Workloads, und die will niemand für die Umstellung abreißen. Das Ziel ist darum: den Ist-Zustand deklarativ in Git abbilden und ArgoCD die Verwaltung übernehmen lassen, ohne dass sich am laufenden Betrieb irgendetwas ändert. Das nenne ich adoptieren.

ArgoCD-Übersicht mit der frisch angelegten Application, die einen bereits laufenden Workload verwaltet.

Das Muster: Live-Werte statt Wunsch-Werte

Der Kern ist eine ArgoCD-Application mit zwei Quellen: das ursprüngliche Helm-Chart und ein Werte-Repo. ArgoCD kann mehrere sources kombinieren und die Werte für ein Chart aus einem separaten Git-Repo ziehen, referenziert über die Variable $values. Die Werte sind dabei nicht neu erdacht, sondern die real laufenden. Ich exportiere sie mit helm get values direkt aus dem Cluster:

helm get values <release>

Damit rendert das Chart exakt das, was schon läuft, und der Sync wird zum No-Op.

sources:
  - repoURL: https://charts.example.com
    chart: app-a
    helm:
      releaseName: app-a
      valueFiles:
        - $values/apps/app-a/prod.yaml
  - repoURL: https://git.example.internal/gitops.git
    ref: values

Angelegt wird die Application zunächst zahnlos: DryRun an, selfHeal und prune aus. So passiert erst einmal nichts, ich sehe nur den Diff.

Der Ressourcenbaum: alles Healthy, aber OutOfSync. Die Workloads laufen bereits, ArgoCD kennt sie nur noch nicht als seine. Genau das ist der Adopt-Moment.

Der Ablauf

  1. Application anlegen (DryRun, kein SelfHeal, kein Prune).
  2. Den Diff prüfen. Nur harmlose Label- und Annotation-Unterschiede sind ein No-Op. Taucht ein Recreate oder Delete einer bestehenden Ressource auf, ist das ein Stoppsignal.
  3. Bei sauberem Diff einmal manuell syncen.
  4. Erst danach den Eigentumsübergang: das Helm-Release-Secret sh.helm.release.v1.<release>.* löschen. Nicht helm uninstall, das würde die Ressourcen entfernen. Die Workloads laufen dabei unberührt weiter.

Nach dem Sync: dieselben, unveränderten Ressourcen, jetzt Synced und Healthy. ArgoCD hat sie adoptiert, ohne einen einzigen Pod neu zu starten.

Die vier Fallen

  • Duplikate statt Adoption. ArgoCD nutzt als Release-Namen per Default <namespace>-<app>. Das Chart rendert dann namespace-app-... statt der live laufenden app-..., alles erscheint komplett neu und ein Sync würde Duplikate anlegen. Der Fix ist eine Zeile: helm.releaseName auf den echten Release-Namen setzen.
  • Die Application zieht sich selbst ein. Trägt die Werte-Quelle einen path, rendert ArgoCD den Ordner mit, inklusive der dort liegenden Application-Datei, und verwaltet sich plötzlich selbst. Lösung: bei der Werte-Quelle keinen path, nur ref: values.
  • Der AppProject-Glob-Bug. Ein sourceRepos-Eintrag mit https://git.example.internal/* wird akzeptiert, die konkrete Repo-URL aber trotzdem abgelehnt, weil * nicht über /-Grenzen matcht. Ich trage die Repo-URLs exakt ein, das ist auch sauberer als eine Wildcard.
  • Die Zombie-Application. Eine mit prune:false und Finalizer angelegte App hing dauerhaft im Zustand „Deleting“. Der Finalizer lässt sich gefahrlos per Patch auf null setzen, weil ArgoCD nicht über ownerReferences löscht, der Workload bleibt.

Ehrlich: Was man vorher klären muss

Wo eine CI-Pipeline die Images am Helm vorbei patcht, entsteht nach der Adoption ein Dauerkonflikt zwischen CI und ArgoCD. Die Frage „wer besitzt den Soll-Zustand, die CI oder Git“ muss vor der Umstellung beantwortet sein. Und in seltenen Fällen löst ein Umbau auf existingSecret einen einmaligen Pod-Neustart aus, das lässt sich mit ignoreDifferences auf die betroffene Annotation vermeiden. Der Eigentumsübergang selbst ist der einzige heikle Moment, davor lohnt ein kurzer Diff-Blick mehr als jede Eile.

Sie wollen eine gewachsene Umgebung nachvollziehbar und reproduzierbar machen? Ich überführe Bestandssysteme schrittweise in einen dokumentierten, deklarativen Zustand, ohne Bruch im Betrieb. Wie ich Automatisierung angehe, lesen Sie unter IT-Automatisierung, das Erstgespräch ist unverbindlich.

Alex Jabi, Jabi IT

Alex Jabi

Ich betreue IT, Informationssicherheit und Datenschutz für KMU und Praxen an der Bergstraße und im Odenwald, persönlich, dokumentiert und ohne Cloud-Zwang.

Mehr über mich
Zurück zum Blog

Passende Artikel

Alle Artikel »
ArgoCD an Keycloak hängen: SSO für das GitOps-Werkzeug

ArgoCD an Keycloak hängen: SSO für das GitOps-Werkzeug

ArgoCD kommt mit einem lokalen admin-Account. Für ein Werkzeug, das ausrollt, was in Produktion läuft, ist das zu wenig. Wie man den admin deaktiviert, ArgoCD per OIDC an Keycloak hängt und dabei nicht in die Issuer-Falle tappt.