← Übersicht  ·  Skripte & Dateien  ·  cloud-host · OpenShift · CI/CD

GitOps mit Argo CD in OpenShift

Die Zeichnungen dazu stehen hier bei den jeweiligen Schritten. Git ist das Soll, der Cluster ist das Ist – Argo CD vergleicht beide dauernd und gleicht ab. Diese Anleitung installiert den OpenShift-GitOps-Operator, legt eine echte Application an, erzeugt live Drift und lässt selfHeal sie zurückdrehen – genau die Lücke, die ein blosses helm upgrade offen lässt. Dazu ein Secret über Sealed Secrets statt im Klartext, und der Rebuild-Ablauf als Checkliste. EX280-relevant.

Stand: 4. September 2026 OKD 4.x / OCP 4.x ns library

Voraussetzung: oc login als cluster-admin für Schritt 2, ein öffentlich lesbares Git-Repo (oder eines mit hinterlegten Zugangsdaten) für Schritt 3. Schritt 6 wird nur durchgegangen, nicht ausgeführt – ein echter sno.ps1 destroy gehört nicht in eine Lernanleitung gegen einen laufenden Cluster.

1 Git ist das Soll, der Cluster das Ist

Argo CD vergleicht dauernd, was in Git steht, mit dem, was im Cluster läuft – und gleicht ab.

Argo CD vergleicht dauernd, was in Git steht (das Soll) mit dem, was im Cluster läuft (das Ist), zeigt die Abweichung und gleicht ab – von Hand oder automatisch. Mit selfHeal schließt es die Lücke, die Helm lässt (B12): eine manuelle Änderung am Cluster wird zurückgedreht. Eine Application zeigt auf {Repo, Pfad} und {Cluster, Namespace}.

Git = Soll, Cluster = Ist – Argo vergleicht dauernd und gleicht ab. Git-Repo Manifeste / Helm-Charts / Kustomize der einzige Ort der Wahrheit jede Änderung ist ein Commit – reviewbar, nachvollziehbar, umkehrbar (git revert) Secrets: nicht im Klartext – E5 Argo CD vergleicht Git (Soll) mit dem Cluster (Ist), dauernd Status je App: Synced / OutOfSync + ein Diff Sync: manual (du drückst) oder automated automated.prune: aus Git gelöscht → auch im Cluster weg automated.selfHeal: manuelle Cluster-Änderung → zurückgedreht → genau die Drift-Lücke, die Helm lässt (B12), ist zu Health je Resource (Healthy/Progressing/Degraded) Pull-Modell: Argo läuft im Ziel-Cluster und zieht – kein Push von außen (E1) Rendering: Helm/Kustomize rendert Argo selbst, dann apply Cluster (Ist) Namespaces, Deployments, Services, Routes, Operatoren was Argo hier findet, gleicht es gegen Git ab Argo darf nur, was seine SA erlaubt (A5) – sonst bleibt die App OutOfSync mit einem RBAC-Fehler mehrere Ziel-Cluster möglich (ein Argo, viele Cluster) liest applyt / heilt Application – das eine Objekt, das alles verbindet source: repoURL + path + targetRevision (Branch/Tag/SHA) destination: server (Cluster) + namespace syncPolicy: automated / prune / selfHeal / CreateNamespace liegt selbst in einem Namespace (meist openshift-gitops) ignoreDifferences: Felder, die ein Operator setzt, nicht als Drift werten argocd app get, argocd app sync, argocd app diff · die UI zeigt den Baum Reihenfolge & Skalierung sync-wave-Annotation ordnet: Namespace (-2) < CRD (-1) < Config (0) < Workload (1) App-of-Apps: eine Wurzel-Application, deren Pfad weitere Applications enthält → ein Einstiegspunkt verwaltet den ganzen Cluster ApplicationSet: erzeugt Applications aus einer Vorlage – pro Cluster, pro Umgebung, pro Verzeichnis Resource-Hooks (PreSync/PostSync): DB-Migration wie Helm-Hooks (B12) der GitOps-Operator liefert Argo + Dex + eine openshift-gitops-Instanz + die Route Merksatz: eine Application = {Repo, Pfad} → {Cluster, Namespace}. Argo vergleicht dauernd und synct – selfHeal hält das Soll durch. Bibliothek: eine Wurzel-App, je Dienst eine Application auf das Helm-Chart – Jenkins baut nur noch das Image, den Rest zieht Argo OCP-Unterschied: OpenShift GitOps ist Argo CD als Operator mit Konsolen-Integration und OpenShift-Login – die Argo-Objekte sind Standard.
Git ist das Soll, der Cluster das Ist. Eine Application verbindet {Repo, Pfad, Revision} mit {Cluster, Namespace}. Argo CD vergleicht beide dauernd, zeigt OutOfSync plus einen Diff und synct – von Hand oder automated. prune löscht, was aus Git verschwindet, selfHeal dreht manuelle Cluster-Änderungen zurück – genau die Drift-Lücke, die Helm lässt (B12). sync-wave ordnet die Reihenfolge, App-of-Apps macht eine Wurzel-App zum Einstiegspunkt für den ganzen Cluster.
  • eine Application (ein CR) zeigt auf {Repo + Pfad + Revision} und {Ziel-Cluster + Namespace}
  • Argo CD vergleicht dauernd Git (Soll) mit dem Cluster (Ist) – Status Synced/OutOfSync plus ein Diff je Resource
  • Sync: manual (du drückst den Knopf) oder automated
  • automated.prune: aus Git gelöscht → auch im Cluster weg
  • automated.selfHeal: eine manuelle Cluster-Änderung wird zurückgedreht – die Drift-Lücke von Helm (B12) ist damit zu
  • Pull-Modell: Argo läuft im Ziel-Cluster und zieht aus Git – kein Push von außen (E1), kein Deploy-Token nach draußen
  • Argo rendert Helm/Kustomize selbst und macht dann apply – kein helm im Spiel
  • Argo darf nur, was seine SA erlaubt (A5) – sonst bleibt die App OutOfSync mit einem RBAC-Fehler
  • sync-wave-Annotation ordnet: Namespace (-2) < CRD (-1) < Config (0) < Workload (1)
  • App-of-Apps: eine Wurzel-Application, deren Pfad weitere Application-Manifeste enthält – ein Einstiegspunkt für den ganzen Cluster
  • ApplicationSet: erzeugt Applications aus einer Vorlage – pro Cluster, pro Umgebung, pro Verzeichnis
  • Resource-Hooks (PreSync/PostSync): DB-Migration, wie die Helm-Hooks (B12)
  • Werkzeuge: argocd app sync, argocd app diff, die Argo-UI als Route, der OpenShift-GitOps-Operator (Argo + Dex + OpenShift-Login)
  • Bibliothek: eine Wurzel-App, je Dienst eine Application auf das Helm-Chart – Jenkins baut nur noch das Image, den Rest zieht Argo
Git-RepoManifeste/Charts, der einzige Ort der Wahrheit, jede Änderung ein reviewbarer, umkehrbarer Commit
Argo CDvergleicht Git (Soll) mit dem Cluster (Ist), Status Synced/OutOfSync plus Diff, synct manual oder automated
Clusterwas Argo hier findet, gleicht es gegen Git ab – nur was die Argo-SA darf (A5)

Anders als beim Push-Modell aus der Build-Kette läuft Argo CD im Ziel-Cluster und zieht – kein Deploy-Token, das nach außen gegeben werden muss. automated.selfHeal schließt genau die Drift-Lücke, die helm upgrade offen lässt: eine manuelle Cluster-Änderung wird zurückgedreht.

2 Den GitOps-Operator installieren

OpenShift GitOps ist Argo CD als Operator – Argo, Dex und eine fertige openshift-gitops-Instanz.

Laptop · Bash
oc get csv -A | grep -i gitops   # schon installiert?

cat <<'EOF' | oc apply -f -
apiVersion: operators.coreos.com/v1alpha1
kind: Subscription
metadata:
  name: openshift-gitops-operator
  namespace: openshift-operators
spec:
  channel: latest
  name: openshift-gitops-operator
  source: redhat-operators
  sourceNamespace: openshift-marketplace
EOF

oc get csv -n openshift-operators -w
oc get route -n openshift-gitops   # die Argo-UI, sobald bereit
oc get pods -n openshift-gitops

Der Operator legt sofort den Namespace openshift-gitops mit einer lauffähigen Argo-CD-Instanz an – kein separates Bootstrapping nötig, wie es Community-Argo-CD bräuchte.

3 Eine Application anlegen

Eine Application zeigt auf {Repo, Pfad} und {Cluster, Namespace} – das eine Objekt, das alles verbindet.

Laptop · Bash
cat <<'EOF' | oc apply -f -
apiVersion: argoproj.io/v1alpha1
kind: Application
metadata:
  name: demo-gitops
  namespace: openshift-gitops
spec:
  project: default
  source:
    repoURL: https://github.com/openshift/origin.git
    targetRevision: HEAD
    path: examples/hello-openshift
  destination:
    server: https://kubernetes.default.svc
    namespace: library
  syncPolicy:
    automated:
      prune: true
      selfHeal: true
    syncOptions:
      - CreateNamespace=false
EOF

oc get application demo-gitops -n openshift-gitops
oc get application demo-gitops -n openshift-gitops -o jsonpath='{.status.sync.status} {.status.health.status}{"\n"}'

Das Beispiel-Repo dient nur der Demonstration – für ein echtes Projekt zeigt source.path auf den eigenen Helm-Chart-Ordner (helm-am-bibliothek-chart.html). syncPolicy.automated ohne weitere Angabe reicht für prune und selfHeal – ohne sie bleibt der Sync manuell, per argocd app sync demo-gitops oder Klick in der UI.

4 Drift erzeugen und selfHeal zusehen

Eine manuelle Cluster-Änderung, die Argo zurückdreht – live beobachtet.

Laptop · Bash
# den von Argo verwalteten Deployment manuell veraendern:
oc scale deployment/hello-openshift -n library --replicas=0

# sofort danach: Argo sieht die Abweichung
oc get application demo-gitops -n openshift-gitops -w
# Status kurz OutOfSync, dann durch selfHeal wieder Synced

# der Beweis: die Replica-Zahl ist zurueckgedreht, nicht bei 0 geblieben
oc get deployment/hello-openshift -n library

Das ist der PunktOhne selfHeal hätte oc scale bis zum nächsten manuellen Sync überlebt – genau die Lücke, die helm upgrade (B12) offen lässt, weil Helm nach dem Deploy nicht mehr hinschaut.

Wer die andere Richtung sehen will: eine Zeile im Git-Repo ändern und pushen – Argo zieht sie innerhalb des Poll-Intervalls (Standard 3 Minuten, oder sofort per Webhook) automatisch in den Cluster.

5 Ein Secret nicht im Klartext versionieren

Ein Klartext-Secret-YAML in Git ist base64, also lesbar. Sealed Secrets verschlüsselt mit dem Public Key eines in-cluster Controllers.

Ein Klartext-Secret in Git ist base64 – also lesbar. In GitOps (E3) braucht es einen Umweg. Drei Wege: Sealed Secrets (Key im Cluster), External Secrets Operator (Store außerhalb), SOPS (Key beim Deployer). Die Secret-Maschinerie muss vor den Workloads syncen – Sync-Wave -1.

Klartext-Secret in Git = lesbar. Drei Wege, es trotzdem zu versionieren. Sealed Secrets (Bitnami) 1 Controller hat ein Schlüsselpaar im Cluster 2 du: kubeseal verschlüsselt mit dem Public Key 3 ein SealedSecret-CR ist sicher zu committen 4 der Controller entschlüsselt im Cluster → echtes Secret Key: im Cluster · Secret-Wert: nur verschlüsselt in Git Namespace-gebunden (strict) – nicht in einen anderen NS kopierbar der Key ist clusterspezifisch: neuer Cluster → neu sealen oder den Key sichern – die DR-Sorge aus E4 Rotation: der Controller erneuert den Key, alte bleiben gültig am einfachsten – ein Controller, keine externe Abhängigkeit gut für kleine Setups, ein Cluster, wenige Secrets External Secrets Operator (ESO) 1 ein SecretStore / ClusterSecretStore zeigt auf Vault / AWS SM / Azure KV / GCP SM 2 ein ExternalSecret-CR referenziert einen Key-Pfad 3 der Operator holt den Wert → schreibt ein echtes Secret 4 aktualisiert in einem Intervall (refreshInterval) Secret-Wert: nie in Git · lebt im externen Store eine Quelle der Wahrheit für alle Cluster und Umgebungen Rotation im Store → ESO zieht nach, der Reloader rollt (B10) mehr bewegliche Teile: Operator + Store + Zugang zum Store der Store-Zugang ist selbst ein Bootstrap-Secret gut, wenn es schon einen Vault gibt oder viele Cluster Cluster wegwerfbar ohne Key-Verlust (E4) SOPS (+ age / PGP) 1 eine Werte-Datei wird mit sops verschlüsselt (nur die Werte, die Schlüssel bleiben lesbar) 2 die Datei liegt verschlüsselt in Git 3 ein GitOps-Plugin entschlüsselt beim Rendern (Argo CD SOPS-Plugin, argocd-vault-plugin, Flux) Key: beim Deployer (age-Key als Cluster-Secret oder KMS) passt zu jedem GitOps-Tool, kein eigener Controller Diff im Git zeigt key: ENC[...] – welcher Key sich änderte, sieht man Key-Verwaltung liegt bei dir (KMS, age, PGP-Ring) gut, wenn Werte-Dateien schon der Weg sind (Helm/Kustomize) der Renderer braucht den Key im Cluster oder eine KMS-Rolle Sync-Wave-Reihenfolge – das entscheidet, ob es beim Rebuild klappt Wave -2: der Secret-Controller / -Operator (oder er ist ein clusterweiter Operator, immer da) Wave -1: die SealedSecret- / ExternalSecret-CRs → echte Secrets entstehen Wave 0+: die Workloads, die das Secret mounten (E3) – sonst starten sie vor dem Secret Entscheidungsmatrix Sealed: einfachste, Key im Cluster, DR-Risiko am Key ESO: eine Quelle außerhalb, mehr Teile, cluster-wegwerfbar SOPS: tool-unabhängig, Key-Verwaltung bei dir Merksatz: Sealed = Key im Cluster, ESO = Secret in einem externen Store, SOPS = Key beim Deployer – und die Maschinerie synct vor den Workloads Bibliothek / cloud-host: bis der GitOps-Teil steht, Secrets von Hand mit oc create secret (B10) – danach Sealed Secrets im selben Repo wie die Charts OCP-Unterschied: keiner – alle drei sind Community-Werkzeuge. OpenShift GitOps liefert nur Argo CD, nicht die Secret-Schicht.
Drei Wege, ein Secret zu versionieren. Sealed Secrets: kubeseal verschlüsselt mit dem Public Key des in-cluster Controllers → das SealedSecret ist sicher in Git → der Controller entschlüsselt es im Cluster. External Secrets Operator: ein ExternalSecret referenziert einen Key in Vault / AWS SM / Azure KV → der Operator synct ihn in ein Secret, der Wert berührt Git nie. SOPS: eine verschlüsselte Werte-Datei in Git, ein GitOps-Plugin entschlüsselt beim Rendern. Die Secret-Maschinerie muss in einer frühen Sync-Wave laufen, sonst starten die Workloads ohne ihr Secret.
  • ein Klartext-Secret-YAML in Git ist base64, also lesbar – jeder mit Repo-Zugriff hat die Zugangsdaten (B10)
  • Sealed Secrets: kubeseal verschlüsselt mit dem Public Key des in-cluster Controllers → ein SealedSecret-CR ist sicher zu committen
  • der Sealed-Secrets-Controller entschlüsselt im Cluster in ein echtes Secret – der Key liegt im Cluster, der Wert nur verschlüsselt in Git
  • ein SealedSecret ist Namespace-gebunden (strict) – nicht in einen anderen NS kopierbar
  • der Sealing-Key ist clusterspezifisch: neuer Cluster → neu sealen, oder den Key sichern (die DR-Sorge aus E4)
  • External Secrets Operator: ein ExternalSecret-CR referenziert einen Key-Pfad in Vault / AWS SM / Azure KV / GCP SM
  • der Operator holt den Wert und schreibt ein echtes Secret, aktualisiert in einem refreshInterval – der Wert berührt Git nie
  • ESO braucht einen SecretStore/ClusterSecretStore mit Zugang zum Backend – der Store-Zugang ist selbst ein Bootstrap-Secret
  • SOPS (+ age / PGP): eine Werte-Datei wird verschlüsselt (nur die Werte), liegt so in Git, ein GitOps-Plugin entschlüsselt beim Rendern
  • bei SOPS liegt der Key beim Deployer (age-Key als Cluster-Secret oder eine KMS-Rolle) – passt zu jedem GitOps-Tool, kein eigener Controller
  • Sync-Wave-Reihenfolge: der Secret-Controller in Wave -2, die SealedSecret/ExternalSecret-CRs in -1, die Workloads in 0+ (E3)
  • Entscheidung: Sealed Secrets ist am einfachsten (Key im Cluster, DR-Risiko am Key), ESO ist eine Quelle außerhalb (mehr Teile, Cluster wegwerfbar), SOPS ist tool-unabhängig (Key-Verwaltung bei dir)
  • Bibliothek: bis der GitOps-Teil steht, Secrets von Hand mit oc create secretdanach Sealed Secrets im selben Repo wie die Charts
  • OCP-Unterschied: keiner – alle drei sind Community-Werkzeuge, OpenShift GitOps liefert nur Argo CD, nicht die Secret-Schicht
Laptop · Bash
# Sealed-Secrets-Controller installieren (Community-Operator oder manuell):
oc apply -f https://github.com/bitnami-labs/sealed-secrets/releases/latest/download/controller.yaml

# ein normales Secret NUR lokal erzeugen, nie committen:
oc create secret generic demo-api-key -n library \
  --dry-run=client --from-literal=key=ein-echtes-geheimnis -o yaml > secret-lokal.yaml

# mit kubeseal in ein committierbares SealedSecret umwandeln:
kubeseal --format=yaml < secret-lokal.yaml > sealed-secret.yaml
rm secret-lokal.yaml   # die Klartextdatei nie behalten

cat sealed-secret.yaml   # das hier ist sicher zu committen - verschluesselt
oc apply -f sealed-secret.yaml

# der Controller im Cluster entschluesselt automatisch:
oc get secret demo-api-key -n library

sealed-secret.yaml ist nur für diesen einen Cluster entschlüsselbar – der Public Key des Controllers ist clusterspezifisch. Deshalb gehört der private Sealing-Key auf die Backup-Liste, sonst sind alle SealedSecrets nach einem Rebuild (Schritt 6) unlesbar.

6 Der Rebuild-Ablauf als Checkliste

Wenn alles in Git steht, ist ein Cluster wegwerfbar – hier nur durchgegangen, nicht ausgeführt.

Wenn alles in Git steht, ist ein Cluster wegwerfbar. Die Übung: zerstören, neu installieren, Argo CD bootstrappen – und Argo zieht den ganzen Rest aus Git zurück. Was nicht in Git liegt (Klartext-Secrets, PVC-Daten, Installer-Config) muss separat gelöst sein. „Wiederhergestellt“ heißt: Workloads ja, Daten nur bei separatem Backup.

Cluster weg – und in einer Stunde wieder da, bis auf die Daten. 1 · zerstören sno.ps1 destroy Server, Snapshot, IP, Firewall 2 · neu installieren sno.ps1 install frischer OKD-Single-Node (~35 min) 3 · Argo bootstrappen GitOps-Operator + Wurzel-Application ein oc apply -f bootstrap/ 4 · Argo zieht alles App-of-Apps → je Dienst eine App (E3) reconcile bis alles Synced & Healthy 5 · grün Workloads laufen, Routes antworten Daten: nur wenn separat gesichert was in Git liegt – kommt automatisch zurück Namespaces, RBAC (Roles, RoleBindings), NetworkPolicy (F2) Deployments, Services, Routes, ConfigMaps, HPAs Helm-Werte-Overrides je Umgebung Operator-Subscriptions + OperatorGroups (D2) die Custom Resources der Operatoren (Kafka, PostgresCluster, D5) die Argo-Application-Objekte selbst (App-of-Apps) Reihenfolge per sync-wave: Secrets-Maschinerie (-1) → Config (0) → Workloads (1) Cluster-Config (Ingress, OAuth-IdP, image-registry): auch als Manifeste in Git der zurückgestellte --rebuild-Flag = genau diese fünf Schritte in einem Kommando was nicht in Git liegt – muss separat gelöst sein Klartext-Secrets → Sealed Secrets in Git (Controller entschlüsselt) oder ESO zieht aus einem externen Store – muss in Wave -1 kommen (E5) bei Sealed Secrets: der Sealing-Key ist clusterspezifisch → sichern PVC-Daten (DB-Inhalt, Uploads) → ein echtes Backup: Velero oder Volume-Snapshots (G3) – ein Rebuild stellt sie nicht her Installer-Config: install-config.yaml, das echte Pull-Secret, die reservierte IP – liegen bei sno.ps1, nicht im App-Repo etcd-Backup (G7) ist die andere DR-Strategie: den Cluster-Zustand wiederherstellen statt neu bauen – für Multi-Node, nicht für SNO-Wegwerf Merke: GitOps rettet die Struktur, nicht den Inhalt Merksatz: destroy → install → Argo bootstrap → Argo zieht alles. Workloads sind in Minuten zurück, Daten nur mit eigenem Backup. der --rebuild-Flag im cloud-host-Skript war bis Block E zurückgestellt, weil er GitOps voraussetzt – ab hier baubar Time-to-green: SNO-Install ~35 min, Argo-Sync ~10 min, Operatoren-Reconcile ~10 min – grob eine Stunde bis alles läuft OCP-Unterschied: identisch – das Muster ist Argo CD + IaC, unabhängig von OKD oder OCP. Nur der Installer-Teil unterscheidet sich (Assisted vs kexec).
Der Cluster ist wegwerfbar – die Daten nicht. Die Übung: sno.ps1 destroysno.ps1 install → den GitOps-Operator und die Wurzel-Application anwenden → Argo zieht Namespaces, RBAC, Workloads, Operator-Subscriptions und die Argo-Apps selbst aus Git zurück. Was nicht in Git liegt, muss separat gelöst sein: Klartext-Secrets (Sealed Secrets / ESO, frühe Sync-Wave), PVC-Daten (ein echtes Backup, Velero / Snapshots), die Installer-Config. GitOps rettet die Struktur, nicht den Inhalt.
  • der Ablauf: sno.ps1 destroysno.ps1 installArgo CD bootstrappen (Operator + Wurzel-Application) → Argo zieht alles aus Git
  • was in Git liegt und automatisch zurückkommt: Namespaces, RBAC, NetworkPolicy, Deployments/Services/Routes, ConfigMaps, HPAs
  • auch in Git: Helm-Werte-Overrides je Umgebung, Operator-Subscriptions und OperatorGroups (D2), die Custom Resources der Operatoren (D5)
  • und in Git: die Argo-Application-Objekte selbst (App-of-Apps), sowie die Cluster-Config als Manifeste (Ingress, OAuth-IdP, image-registry)
  • Reihenfolge per sync-wave: die Secrets-Maschinerie in Wave -1, Config in 0, Workloads in 1
  • was nicht in Git liegt – Klartext-Secrets: über Sealed Secrets in Git (Controller entschlüsselt) oder ESO aus einem externen Store, muss in Wave -1 (E5)
  • bei Sealed Secrets ist der Sealing-Key clusterspezifisch – er muss separat gesichert werden, sonst sind die Secrets nach dem Rebuild unlesbar
  • PVC-Daten (DB-Inhalt, Uploads) brauchen ein echtes Backup: Velero oder Volume-Snapshots (G3) – ein Rebuild stellt sie nicht her
  • Installer-Config (install-config.yaml, das echte Pull-Secret, die reservierte IP) liegt bei sno.ps1, nicht im App-Repo
  • etcd-Backup (G7) ist die andere DR-Strategie: den Cluster-Zustand wiederherstellen statt neu bauen – für Multi-Node, nicht für den SNO-Wegwerf
  • der zurückgestellte --rebuild-Flag im cloud-host-Skript ist genau diese fünf Schritte in einem Kommando – ab Block E baubar
  • Time-to-green: SNO-Install ~35 min, Argo-Sync ~10 min, Operatoren-Reconcile ~10 min – grob eine Stunde
  • „Wiederhergestellt“ heißt ehrlich: Workloads ja, Daten nur bei separatem Backup – GitOps rettet die Struktur, nicht den Inhalt
  • OCP-Unterschied: identisch – das Muster ist Argo CD plus Infrastructure-as-Code, nur der Installer-Teil unterscheidet sich
  1. sno.ps1 destroy – Server, Snapshot, IP, Firewall weg
  2. sno.ps1 install – frischer OKD-Single-Node, ~35 Minuten
  3. GitOps-Operator installieren (Schritt 2) und die Wurzel-Application anwenden (oc apply -f bootstrap/)
  4. Argo zieht Namespaces, RBAC, Workloads, Operator-Subscriptions und die Argo-Application-Objekte selbst aus Git zurück
  5. warten bis alles Synced und Healthy ist – Argo-Sync grob 10 Minuten, Operatoren-Reconcile grob 10 Minuten

Was dabei NICHT zurückkommt Klartext-Secrets (deshalb Schritt 5), PVC-Daten (DB-Inhalt, Uploads – braucht ein echtes Backup wie Velero oder Volume-Snapshots), die Installer-Config (install-config.yaml, das echte Pull-Secret, die reservierte IP liegen bei sno.ps1, nicht im App-Repo).

„Wiederhergestellt“ heißt ehrlich: Workloads ja, Daten nur bei separatem Backup – GitOps rettet die Struktur, nicht den Inhalt. Der zurückgestellte --rebuild-Flag im cloud-host-Skript wäre genau diese fünf Schritte in einem Kommando.

7 Typische Fallen

Symptommeist
Application bleibt OutOfSync mit RBAC-Fehlerdie Argo-SA darf das Ziel-Objekt nicht anfassen (A5) – Rolle fehlt oder falscher Namespace
selfHeal greift nichtsyncPolicy.automated.selfHeal fehlt in der Application – ohne sie bleibt Drift stehen bis zum manuellen Sync
SealedSecret entschlüsselt nichtauf einem anderen Cluster erzeugt (anderer Public Key) – neu sealen mit dem Key dieses Clusters
nach Rebuild sind alle SealedSecrets unlesbarder private Sealing-Key war nicht gesichert – auf einem neuen Cluster entsteht ein neuer, alte SealedSecrets passen nicht mehr
Workload startet ohne sein SecretSync-Wave falsch – die Secret-Maschinerie muss vor den Workloads syncen (Wave -1 vs 0+)

8 Wie das Projekt es macht

Aktuell kein Argo CD im Einsatz – die Bibliothek deployt per helm upgrade --install aus Jenkins (build-kette-openshift.html), Secrets werden von Hand mit oc create secret angelegt (secrets-in-openshift.html). Diese Anleitung zeigt das Alternativmuster, das der Atlas als nächsten Ausbau nennt: eine Wurzel-App, je Dienst eine Application auf das Helm-Chart – Jenkins baut dann nur noch das Image, den Rest zieht Argo. Die SNO-API ist nur übers Tailnet erreichbar, das gilt für Argo CD (im Cluster) nicht – nur für den Zugriff auf den Cluster von außen.

+ Die Kurzfassung

Application{Repo, Pfad, Revision} → {Cluster, Namespace} – das eine verbindende Objekt
selfHealdreht manuelle Cluster-Änderungen zurück – schließt die Drift-Lücke, die Helm laesst
Secretsnie Klartext in Git – Sealed Secrets, ESO oder SOPS, immer vor den Workloads syncen
Rebuilddestroy → install → Argo bootstrap → Argo zieht alles – außer Daten und Installer-Config