# OpenShift-Atlas — Plan

**Stand:** 2026-09-04 · **Status:** 65/65 gezeichnet — Breite + Diagramm 02–04 (CRC / Topologie / Konfiguration). Nächste Phase: Tiefe · **Seite:** `openshift-atlas.html`

Langfassung des Plans. Die lebende Deckungsmatrix und der Fortschritt stehen in
`openshift-atlas.html` selbst — dort **am Seitenende** (Anhang), damit die Diagramme
oben stehen.

---

## Ziel

- **Primär:** OpenShift wirklich verstehen. Breite zuerst, Tiefe danach.
- **Sekundär:** Bewerbungsgespräch — fällt als Nebenprodukt ab, kein eigener Plan.

## Methode

Hybrid-Spirale:

- **Breiten-Durchgang** über *alle* Themen, jedes Thema bekommt ≥1 Diagramm — **Pflicht**.
- **Tiefe** auf 2–3 job-relevante Themen hands-on — **explizit optional**.

Diagramm-Methode aus `cloud-host` (Inline-SVG, Farbkanon). Ein falsches Diagramm
fällt beim Zeichnen auf — das ist der Verständnis-Test.

## Regeln gegen Zerfall

1. **Deckungsmatrix** in `openshift-atlas.html` = EX280-Lernziele ∪ Atlas-Blöcke A–J,
   dedupliziert. EX280-Zeilen sind mit ★ markiert (zertifikatsreife Teilmenge sichtbar).
   „Breite fertig" = jede Zeile hat ≥1 Diagramm.
2. **Eine Einheit = eine Sitzung = ein Commit = ein Diagramm + Unterschrift.** Nach jedem
   Commit ist das Vorhandene kohärent, nie eine Ruine.
3. **Breite = Pflicht, Tiefe = optional.** Aufhören nach der Breite ist ein Erfolg.
4. **Kein fester Takt.** Matrix trägt je Zeile „zuletzt bearbeitet". **30-Tage-Stolperdraht:**
   zeigt die Matrix 30 Tage nichts angefasst → bewusst weitermachen oder bewusst ins Regal
   stellen. Kein Deadline-Druck, nur ein Alarm gegen das heimliche Sterben.
5. **Erklärregel.** Jeder Fachbegriff bekommt beim ersten Auftreten einen Satz Definition —
   auch scheinbar selbstverständliche (Namespace, Service, Deployment, Route). Einfache
   Sprache vor Jargon. Im Gespräch zählt sicheres Beherrschen der einfachen Dinge mehr als
   komplexe Begriffe.
6. **Viele Punkte je Diagramm, jeder kurz.** Nicht das SVG breiter machen (Schrift/Linien
   überlappen sonst) — sondern die *Anzahl* der angesprochenen Punkte erhöhen: mehr
   Beschriftungen, mehr Legendeneinträge, mehr kurze Callouts. Ein Punkt = ein Stichwort
   oder Halbsatz, nicht ein ganzer erklärender Satz. Ein Nebenkasten „was im Gespräch dazu
   oft gefragt wird" ist erwünscht. Breite der Abdeckung schlägt Tiefe der einzelnen Erklärung.

## Ort & Form

- Seite: `anleitungen/openshift-atlas.html`, eigene Nummerierung 01…N, eigene Nav,
  Rücklinks zur Diagrammseite (`diagramme-hetzner-und-crc.html`).
- **Glossar:** `shared-glossary/v2/loader.js` verursachte ein Encoding-Problem auf der Atlas-Seite
  (Umlaute) und ist vorerst wieder raus. Wird eingebunden, sobald das geklärt ist — ein
  `<meta charset="utf-8">` steht jetzt als erste Zeile, das könnte reichen. Neue OpenShift-Begriffe
  weiterhin blockweise ergänzen (nicht pro Sitzung), Startstatus `source-linked-not-reviewed` +
  Red-Hat-Doku-Link. Die Einzeiler-Definition für `terminology-data.js` ist ein Verständnis-Test.
- **HyperFrames:** ein Capstone-Video pro *vollständigem* Themenblock, montiert aus schon
  existierenden Diagrammen. Ein Video wird erst gebaut, wenn sein Block in der Matrix voll ist.
  Optional-Eimer.

## Referenz-Apps (Rollenmodell)

- **Bibliothek-Enterprise** = Rückgrat, ~90 % aller Diagramme. „So sieht OpenShift im
  Normalbetrieb aus."
- **Novaris-Versicherung-Legacy** = abgegrenzter Block „Legacy-Migration" (Block H). Nur dort.
- **Concordia-Bank-Middleware (WAS)** = abgegrenzter Block „kommerzielle Middleware" (Block I).
  Nur dort.
- **Regel:** Ein Novaris-/Concordia-Diagramm wird nur gezeichnet, wenn es etwas
  OpenShift-Spezifisches zeigt, das Bibliothek nicht kann.
- **Frontend** = eigener Block J, explizit im Scope.

## Infrastruktur

Die Matrix-Spalte **hands-on** sagt je Diagramm, wo es ausprobierbar ist. Vier Werte:

- **SNO** (Single Node OpenShift — ein Rechner ist Control-Plane-Node und Worker-Node zugleich)
  = die Umgebung für fast alles. Billig, `sno.ps1 down`/`up` snapshottet und stellt wieder her.
- **SNO ohne HA** — läuft auf dem Single-Node vollständig, nur die Redundanz fehlt (kein
  Verständnisverlust): G1 Monitoring, G2 Logging, G4 MachineConfig, G5 Upgrades.
- **Multi-Node** — braucht einen zweiten Node, dafür reicht ein lokaler **`kind`-Cluster**
  in der podman-machine: B6 Scheduling und F1 OVN zwei Nodes, G7 etcd drei Control-Plane-Nodes
  (Quorum-Übung). **Kein Hetzner-Multi-Node-Cluster nötig.**
- **Recherche** — reines Konzept ohne Umgebung (A1, D1).

**Optionale Kür (nicht mehr auf dem kritischen Pfad):** ein echter 3-Node-OKD auf Hetzner
über `scripts/cluster.ps1` (nur Kill-Switch, kein `install`) + `anleitungen/okd-cluster-hetzner.html`
(1425 Zeilen, vor den `sno.ps1`-Fixes — würde Reparatur brauchen). Nur wenn du echtes
RHCOS-Multi-Node anfassen willst.

- **CRC** (OpenShift Local — OpenShift in einer VM auf dem Laptop): optional zum lokalen
  Vorführen, z. B. im Bewerbungsgespräch. **Diagramm 02** zeigt, was CRC kann und wo es
  aufhört. Baut auf `bibliothek-enterprise-auf-crc.html` und `openshift-local-auf-windows.html` auf.
- **Red Hat Developer Sandbox:** raus (funktioniert für diesen Zweck nicht zuverlässig).
- **OKD vs OCP:** Der Atlas läuft auf OKD (die quelloffene Variante). OCP-Unterschiede werden
  inline notiert, wo sie zählen — RHCOS, Subscriptions, entitled builds, `registry.redhat.io`.

## Aufgabe 0

1. **Atlas-Diagramm 01:** SNO-Aufbau — von Rescue-Boot zum laufenden Cluster. **Erledigt 2026-09-03.**
2. **`cluster.ps1` ROT-Bug:** **Bereits behoben.** Die Version vom 1. September (`scripts/cluster.ps1`,
   `scripts/sno.ps1`) macht das schon richtig: `cluster.ps1` schließt `okd-sno*` per `$ExcludeLike`
   explizit aus; `sno.ps1 down` erstellt erst den Snapshot und löscht den Server nur bei
   `$LASTEXITCODE -eq 0`. Der Befund aus der Analyse 2026-09-01 ist überholt.
3. **`--rebuild`-Flag** + Lifecycle-Anleitung: **zurückgestellt bis Block E.** Ein Rebuild =
   `destroy` → `install` → Argo-CD-Bootstrap aus Git. Der Bootstrap-Teil setzt voraus, dass GitOps
   eingerichtet ist (Block E). Bis dahin ist der Weg `sno.ps1 destroy` + `sno.ps1 install` von Hand.

## Block-Skelett (65 Diagramme, abhängigkeitssortiert)

| Block | Inhalt | ~Anz | Infra |
|---|---|---|---|
| 0 | Vorbereitung: 01 Aufbau, 02 CRC, 03 Topologie, 04 Konfiguration | 4 | SNO / CRC |
| A | Fundament: OKD/OCP/K8s, Projects, `oc`, Auth/IdP, RBAC, SCC, ServiceAccounts | 7 | Recherche/SNO |
| B | Workloads + Konfiguration + Auslieferung: Deployment/DC, Services, Routes, Probes, Scheduling, Quotas, **ConfigMap&Secret**, **Secret-Schwerpunkt** (B9/B10), **Helm-Schwerpunkt** (B11/B12) | 12 | SNO |
| C | Build-Kette: ImageStreams, BuildConfig, S2I, `oc new-app`, interne Registry, Trigger | 6 | SNO |
| D | Operatoren & OLM | 5 | SNO |
| E | CI/CD: Jenkins→OCP, Tekton, Argo CD, GitOps-Rebuild, Secrets-in-Git | 5 | SNO |
| F | Netzwerk & Sicherheit: OVN, NetworkPolicy, Router, Service Mesh, serving-certs | 5 | SNO |
| G | Betrieb: Monitoring, Logging, Storage/CSI, MachineConfig/MCO, Upgrades, ClusterOperators, etcd | 7 | SNO (G3/G6) · SNO ohne HA (G1/G2/G4/G5) · kind 3 Nodes (G7) |
| H | Legacy-Migration (Novaris) | 6 | SNO |
| I | Kommerzielle Middleware (Concordia/WAS) | 4 | SNO |
| J | Frontend | 4 | SNO/CRC |

Reihenfolge A→G ist echte Abhängigkeit: SCC braucht ServiceAccounts und Projects,
Operatoren vor GitOps, Netzwerk vor Betrieb. H/I/J sind angehängte Themenblöcke,
jederzeit einschiebbar.

### Schwerpunkte (Thema mit mehreren Diagrammen)

Ein *Schwerpunkt* ist die praktische Umsetzung der „Tiefe" aus der Methode: ein Thema, das
der User schwer greift oder das im Projekt zentral ist, bekommt 2+ Diagramme statt einem.
In der Matrix mit ▪ markiert.

- **Helm** (B11 mentales Modell, B12 Praxis am Bibliothek-Chart) — der User „tut schwer das zu verstehen".
- **Secrets** (B9 Typen/Konsum/at-rest, B10 Herkunft/Pull-Secrets/Rotation/Git) — plus B8 als gemeinsame Grundlage mit ConfigMap.

### Reihenfolge in Block A

1. OKD vs OCP vs Kubernetes — was OpenShift hinzufügt
2. Projects vs Namespaces — was bei `oc new-project` automatisch entsteht (Quota, LimitRange, SCC-Bindung)
3. `oc` vs `kubectl` + API-/CRD-Modell + Web-Konsole
4. Authentifizierung — IdP, OAuth-Stack, htpasswd, `oc login`
5. RBAC — Roles/RoleBindings, `oc adm policy`, Default-Rollen
6. ServiceAccounts — was ein Pod als Identität mitbekommt
7. SCC — `restricted-v2`, warum kein Root, `add-scc-to-user` (zuletzt, weil es auf 5 und 6 aufbaut)

## Ehrliche Restrisiken

- „Kein Takt" + weicher Stolperdraht: der Abschluss hängt genuin daran, dass freiwillig
  weitergemacht wird.
- ~62 Diagramme sind ein Mehr-Monats-Vorhaben, auch bei gutem Tempo. Breite ist seit
  2026-09-04 durch, es geht jetzt um Tiefe und Politur.
- Zwei bis drei Diagramme (B6, F1, G7) brauchen einen lokalen `kind`-Cluster. Das ist ein
  kleiner Nebenschauplatz, kein Cluster-Fenster mehr — das teure Hetzner-Multi-Node
  entfällt (Triage 2026-09-04, siehe „Infrastruktur").
- Aufgabe 0 ist echte Skript-Arbeit (2–4 Sitzungen) *vor* dem ersten Lern-Diagramm.

## Blind-Spot-Runde (2026-09-04)

Nach der Breite eine Durchsicht der Infrastruktur-Annahmen. Ergebnis:

1. **„Cluster"-Tag zu großzügig** → Triage, neue Spaltenwerte, Cluster-Fenster gestrichen (siehe „Infrastruktur"). *Erledigt.*
2. **CRC ohne Rolle** → Diagramm **02 „CRC-Grenzen"** (drei Wurzeln: ein Node, eingefrorene Images, Laptop ohne Cloud). *Erledigt.*
3. **Keine Ist-Topologie** → Diagramm **03 „die echte Topologie"** (Laptop + podman-machine-Jenkins, Tailscale-Tunnel, SNO, Deploy-Weg). *Erledigt.*
4. **Plan kannte „Jenkins lokal" nicht** → in Diagramm 03 mit drin. *Erledigt.*
5. **`okd-cluster-hetzner.html` angestaubt** → durch die Triage nur noch optionale Kür, im Infrastruktur-Abschnitt vermerkt. *Geschlossen.*
6. **SNO-`up`-Reibung** (image-registry-Lease hängt, `pipeline`-Token weg) → Post-`up`-Hook: neuer `sno-wsl.sh remediate`, von `Invoke-Up` nach dem API-Check aufgerufen (löscht die Lease, rollt den Operator neu aus, legt `pipeline-token` neu an). Idempotent, nicht fatal. *Erledigt.*
7. **SCOS ist ein bewegtes Ziel** → Versionshinweis in Diagramm 01 (`4.22.0-okd-scos.8`, bei Neubau prüfen). *Erledigt.*
8. **Backup-Lehrspannung G7** → die zwei Backup-Wege explizit (`cluster-backup.sh` vs Hetzner-Disk-Snapshot). *Erledigt.*
9. **Keine Config-Landkarte** (aufgekommen durch die Frage „wo schaue ich DB-Passwörter / Endpunkte nach") → Diagramm **04 „Umgebungen & Konfiguration"** (vier Stufen Ideal vs. drei im Projekt, Config-Landkarte als Tabelle mit `oc`-Befehl + Konsolen-Weg je Config-Art, drei Schichten Quelle/Übersetzung/Wirkung) plus eigene Anleitung `okd-konfiguration-nachschauen.html`. *Erledigt.*

## Tiefe-Phase (ab 2026-09-04)

- **D–G-Qualitäts-Pass:** die Punkte-Listen von D1–D5, E1–E5, F1–F5, G1–G7 projektspezifisch schärfen (an Bibliothek/SNO/den realen Jenkins-Deploy andocken statt Doku-Speak). Läuft via Fork-Agenten (je Block einer), Parent integriert die `scratchpad/pts_<sid>.py`-Skripte und lässt danach den Link-Pass (`d_links.py`) nochmal über die neuen `(X#)`-Refs laufen.
- Danach: Helm/Secrets-Schwerpunkte vertiefen oder Hands-on-Durchlauf eines Themas.

## Randnotiz — der Commit-Zwischenfall (2026-09-04)

Beim Einbau von Block H und I ist ein Git-Fehler passiert. Er taugt als Lernfall,
darum hier festgehalten.

**Was schiefging.** Der Commit wurde mit `git add -A` vorbereitet. `-A` heißt „alles" —
jede geänderte *und jede bisher unbeobachtete* Datei im Projekt. Damit rutschten 3636
fremde Dateien in den Commit: das ganze Verzeichnis `hyperframes/.venv-piper/` (eine
*virtuelle Umgebung*, also eine lokale Kopie eines Python-Interpreters samt Bibliotheken —
nichts, was versioniert gehört) plus große Ton- und Videodateien. Der Commit war schon
auf `origin` gepusht (`origin` = der Server, hier GitHub), bevor es auffiel.

**Die Behebung, Schritt für Schritt.**

1. `git reset --soft <letzter-guter-commit>` — schiebt den Zweig-Zeiger einen Commit
   zurück. `--soft` heißt: die Dateiänderungen bleiben erhalten und vorgemerkt, nur der
   Commit selbst verschwindet.
2. `git restore --staged .` — alles aus der Vormerkung nehmen, um gezielt neu auszuwählen.
3. `git stash push -- index.html suchindex.js` — die fremden Änderungen an `index.html`
   (eine unfertige Video-Einbindung, gehört nicht in diesen Commit) vorübergehend beiseite
   parken.
4. `git add anleitungen/openshift-atlas.html` — nur die eine Datei. Der pre-commit-Haken
   baut `suchindex.js` selbst neu und legt sie dazu.
5. `git commit` — jetzt ein sauberer Zwei-Datei-Commit, inhaltlich gleich dem kaputten,
   nur ohne Ballast.
6. `git checkout stash@{0} -- index.html` und `git stash drop` — die geparkte
   User-Änderung zurückholen, die veraltete `suchindex.js` aus dem Stash verwerfen (wird
   ohnehin generiert).
7. `git push --force-with-lease origin main` — den kaputten Commit auf dem Server durch
   den sauberen ersetzen.

**Warum `--force-with-lease` und nicht `--force`.** Der Server lehnt normalerweise jeden
Push ab, der vorhandene Historie überschreibt. `--force` erzwingt es bedingungslos und
würde dabei auch einen fremden Commit zerstören, der in der Zwischenzeit dazugekommen ist.
`--force-with-lease` prüft zuerst: steht `origin/main` noch genau dort, wo ich es zuletzt
gesehen habe. Nur dann drückt es. Hat sich der Server bewegt, bricht es ohne Schaden ab.

**Das „Was wäre wenn" — jemand hätte zwischenzeitlich gepusht.** Angenommen zwischen dem
kaputten Push und der Reparatur schiebt eine andere Maschine einen Commit `X` auf `origin`.

- `git push --force-with-lease` **schlägt fehl** — genau das ist der Schutz. `X` bleibt heil.
- `git fetch` holt den neuen Stand. `git log --oneline origin/main` zeigt `X` über dem
  kaputten Commit.
- `git rebase --onto <sauberer-commit> <kaputter-commit> origin/main` — nimm alle Commits
  *nach* dem kaputten (also `X`) und pflanze sie auf den sauberen um. Ergebnis: sauberer
  Commit, dann `X` obendrauf, Ballast raus.
- **Hier entsteht der Merge-Konflikt:** Hat `X` dieselben Zeilen in `openshift-atlas.html`
  angefasst wie der H/I-Einbau, hält der Rebase an und markiert die Stelle in der Datei mit
  `<<<<<<<`, `=======`, `>>>>>>>`. Dann: Datei öffnen, je markiertem Block die richtige
  Fassung wählen, Markierungen löschen, `git add <datei>`, `git rebase --continue`.
- `suchindex.js` **nie von Hand zusammenführen** — sie ist generiert. Bei Konflikt eine
  Seite nehmen (`git checkout --theirs suchindex.js`), dann `scripts/build-suchindex.ps1`
  einmal laufen lassen und das Ergebnis vormerken.
- Zum Schluss wieder `git push --force-with-lease`. Die Historie wurde umgeschrieben (der
  kaputte Commit ist raus), also bleibt der erzwungene Push nötig — aber die
  Lease-Prüfung sichert jetzt gegen `X` ab.

**Merksätze für den Atlas.**

- Immer `git add anleitungen/openshift-atlas.html` mit vollem Pfad, nie `git add -A` oder
  `git add .`. Der Haken kümmert sich um `suchindex.js`.
- `hyperframes*/` und `*.venv*` gehören in eine `.gitignore`, damit der Fehler nicht wieder
  möglich ist.
- Falscher Inhalt in einem schon gepushten Commit → `git reset --soft` plus gezielt neu
  committen plus `--force-with-lease`. **Nicht** `git revert` (hängt nur einen Gegen-Commit
  an, der Ballast bleibt in der Historie) und **nicht** `git rm` plus Commit (dasselbe
  Problem).

## Verwandte Dateien

- `diagramme-hetzner-und-crc.html` — die bestehende Diagrammserie, auf die der Atlas verweist
- `okd-single-node-hetzner.html` — SNO-Installation
- `okd-cluster-hetzner.html` — Multi-Node-Cluster (Cluster-Fenster)
- `bibliothek-enterprise-auf-crc.html` — CRC-Deploy der Referenz-App
- `bibliothek-enterprise-via-jenkins-auf-okd.html` — Jenkins→OKD-Pipeline
- `openshift-liberty-bibliothek.html` — Liberty-Gedankenspiel (Berührungspunkte mit Block C und H)
