docs: cert-manager is on v1.21.1, and the mirror outage has its AAR
Seven minors in sequence as the documentation requires, each rolled out and verified before the next was pushed: three deployments on the new version and fifteen certificates Ready every time. Measured on the target images first, so the point was known before the work: eight critical findings become zero and a hundred and twenty-eight high become twenty-four. Two candidates were measured and deliberately left alone. Wiki.js runs a floating tag that points at a newer build than the release tags that look newer by number — upgrading to 2.5.277 would have tripled its critical findings from twelve to forty. Draupnir has no newer release at all, which sharpens what pile A means: a package having a fix is not the same as an image existing that carries it. The mirror outage gets its own review. Between step one and two the pipeline stood for an hour because git.lab could not reach the operating host on 443 while its firewall was being changed. The cluster never noticed, because the CoreDNS pointer added yesterday sends the name down the private path — the design doc warned about the opposite failure, and the mirror image of it is what happened.
This commit is contained in:
@@ -120,7 +120,7 @@ Bedeutung der Meilensteine: siehe [roadmap.md](roadmap.md).
|
||||
| [0026](docs/adr/0026-pruefziele-werden-abgeleitet-nicht-gepflegt.md) | accepted | ADR-0026: Prüfziele werden abgeleitet, nicht gepflegt — und das Ausbleiben der Herleitung alarmiert |
|
||||
| [0027](docs/adr/0027-zuletzt-eigener-meilenstein.md) | accepted | ADR-0027: „Zuletzt" wird ein eigener Meilenstein (M6) |
|
||||
|
||||
## Open AARs (8)
|
||||
## Open AARs (9)
|
||||
|
||||
- [AAR — Alle geplanten Prüfungen waren dauerhaft rot und meldeten damit nichts mehr](docs/aar/2026-08-18-alle-pruefungen-dauerhaft-rot.md)
|
||||
- [AAR — Nach der Freischaltung sendete Safari ungefiltert weiter](docs/aar/2026-08-18-safari-sendete-ungefiltert.md)
|
||||
@@ -130,6 +130,7 @@ Bedeutung der Meilensteine: siehe [roadmap.md](roadmap.md).
|
||||
- [AAR — rohana lief voll, der ThreadNet-Web-Spiegel riss](docs/aar/2026-08-20-rohana-platte-voll-spiegel-gerissen.md)
|
||||
- [AAR: Clarks Calls und Identitäts-Reset — vier Fehldiagnosen bis zur bekannten Ursache](docs/aar/2026-08-21-clark-calls-reset-vier-fehldiagnosen.md)
|
||||
- [AAR: Deploy der abgeleiteten CVE-Zielmenge (#0106)](docs/aar/2026-08-21-cve-zielmenge-deploy.md)
|
||||
- [AAR: Die Ausrollstrecke stand eine Stunde — der Push-Spiegel kam nicht durch](docs/aar/2026-08-21-spiegel-ausfall.md)
|
||||
|
||||
## Fehlerklassen (18)
|
||||
|
||||
|
||||
@@ -0,0 +1,103 @@
|
||||
---
|
||||
type: aar
|
||||
status: open
|
||||
date: 2026-08-21
|
||||
related:
|
||||
- "docs/design/2026-08-21-cve-remediation.md"
|
||||
- "docs/issues/0051-cve-remediation-pass.md"
|
||||
---
|
||||
|
||||
# AAR: Die Ausrollstrecke stand eine Stunde — der Push-Spiegel kam nicht durch
|
||||
|
||||
**Schwere:** MEDIUM (kein Produktionsausfall; die Auslieferung neuer Stände war
|
||||
blockiert) · **Dauer:** ~15:52 bis ~16:57
|
||||
|
||||
## What was planned / expected
|
||||
|
||||
cert-manager sollte in sieben Fassungssprüngen von v1.14.0 auf v1.21.1 gebracht
|
||||
werden (#0051). Erwartet war: Commit nach git.lab → Push-Spiegel nach rohana →
|
||||
Flux zieht binnen einer Minute → Prüfung → nächste Stufe.
|
||||
|
||||
## What happened
|
||||
|
||||
Stufe 1 (v1.15.5) lief planmäßig; letzter erfolgreicher Spiegel **15:51:56**.
|
||||
|
||||
Stufe 2 (v1.16.5) wurde gepusht und **kam nie im Cluster an**. Die Warteschleife
|
||||
lief sechs Minuten ins Leere, bevor sie abbrach.
|
||||
|
||||
Die Kette, Glied für Glied gemessen:
|
||||
|
||||
| Prüfung | Ergebnis |
|
||||
|---|---|
|
||||
| Commit auf git.lab? | ja, `d90861e` |
|
||||
| Flux-Kustomization gesund? | `Ready=True`, angewandte Revision `93155c2` |
|
||||
| GitRepository-Quelle? | `Ready=True`, Artefakt bei `93155c2` |
|
||||
| Hat **rohana** den Commit? | **nein** — `93155c2` |
|
||||
| Push-Spiegel auf git.lab? | **`to_retry`**, Fehler: *„unable to access … port 443 after 134551 ms: Could not connect to server"* |
|
||||
|
||||
Damit war die Ursache benannt: **git.lab erreichte rohana auf 443 nicht.**
|
||||
|
||||
Nachgemessen aus drei Netzen: Von sorbs Netz **und** aus dem Hetzner-Cluster war
|
||||
`188.245.193.243:443` tot, während `:2248` (SSH) antwortete und Gitea über den
|
||||
**privaten** Pfad `10.0.0.3` gesund war (Version 1.27.0, 0,068 s). Traefik auf
|
||||
dem Host lief zu dem Zeitpunkt seit **sieben Tagen** durch — es war kein
|
||||
Dienstausfall.
|
||||
|
||||
**Ursache laut sorb:** Auf dem Betriebs-Host wurde an `ufw` und `iptables`
|
||||
gearbeitet. Der öffentliche Web-Zugang war währenddessen zu.
|
||||
|
||||
**Nach der Wiederherstellung des Netzwegs lief der Spiegel trotzdem nicht.**
|
||||
GitLab hatte nach den Fehlschlägen die Wartezeit hochgesetzt; weder
|
||||
`enabled=true` noch Aus- und Wiedereinschalten setzte sie zurück. Erst ein
|
||||
**echtes Push-Ereignis** (ein leerer Commit) stieß ihn an — 15 Sekunden später
|
||||
`finished`, Flux zog nach, Stufe 2 rollte aus.
|
||||
|
||||
## Why the difference
|
||||
|
||||
**Routing-Klasse: spec issue** — an der Annahme, nicht am Code.
|
||||
|
||||
Der Entwurf zu #0051 kannte den Rückweg jeder Stufe, aber nicht die
|
||||
Voraussetzung, dass die Strecke überhaupt trägt. Zwischen „Commit gepusht" und
|
||||
„im Cluster wirksam" liegen bei uns **drei** Glieder — git.lab, der
|
||||
Push-Spiegel, Flux — und keines davon wird vor einem mehrstufigen Vorhaben
|
||||
geprüft.
|
||||
|
||||
⚠️ Erschwerend, und das ist die eigentliche Pointe: **Der Cluster hat vom
|
||||
Ausfall nichts gemerkt.** Seit dem 2026-08-21 (#0088) zeigt ein CoreDNS-Eintrag
|
||||
`rohana.axion1337.de` clusterintern auf `10.0.0.3`. Der Entwurf dazu warnte
|
||||
ausdrücklich vor dem **umgekehrten** Fall: *„Fällt 10.0.0.3 aus, ist rohana aus
|
||||
dem Cluster nicht erreichbar, obwohl der öffentliche Weg funktionieren würde."*
|
||||
Eingetreten ist das Spiegelbild — öffentlich tot, privat gesund. Der Zeiger hat
|
||||
den Cluster gerettet und zugleich verdeckt, dass draußen etwas kaputt war.
|
||||
|
||||
## Learnings
|
||||
|
||||
- ⚠️ **Vor einem mehrstufigen Ausrollvorhaben gehört die Strecke selbst
|
||||
geprüft**, nicht nur der Rückweg. Ein Commit, der git.lab erreicht, ist noch
|
||||
lange nicht ausgerollt.
|
||||
- **Ein Push-Spiegel erholt sich nicht von selbst, wenn das Ziel zurückkommt.**
|
||||
GitLabs Wartezeit-Erhöhung überlebt `enabled=true` und das Aus-/Einschalten;
|
||||
es braucht ein Push-Ereignis. Ein leerer Commit ist dafür das sauberste
|
||||
Werkzeug — er ändert den Baum nicht, überspringt also keine Stufe.
|
||||
- ⚠️ **Bei gestuften Upgrades darf nicht auf Vorrat gepusht werden.** Läge der
|
||||
Spiegel und stünden fünf Stufen gestapelt im Repo, wendete Flux nach der
|
||||
Erholung nur den **letzten** Commit an — und übersprang fünf Minor-Fassungen,
|
||||
was cert-manager ausdrücklich verbietet. Die Regel lautet: erst ausrollen und
|
||||
prüfen, dann die nächste Stufe pushen.
|
||||
- **Ein redundanter Pfad verdeckt den Ausfall des anderen**, wenn nichts den
|
||||
ungenutzten prüft. Der CoreDNS-Zeiger ist richtig und bleibt — aber niemand
|
||||
merkt, wenn der öffentliche Weg wegbricht.
|
||||
|
||||
## Actions
|
||||
|
||||
- [x] Spiegel wieder in Betrieb (leerer Commit `5507f13`), Flux zog nach.
|
||||
- [x] cert-manager in sieben Stufen bis v1.21.1 abgeschlossen, jede Stufe
|
||||
einzeln geprüft.
|
||||
- [ ] **Offen:** Es gibt **keine Prüfung**, die einen hängenden Push-Spiegel
|
||||
meldet. Er stand eine Stunde, und aufgefallen ist es nur, weil ich zufällig
|
||||
in dem Fenster ausrollen wollte. Eine Regel auf `update_status != finished`
|
||||
oder auf das Alter von `last_successful_update_at` wäre billig — gehört
|
||||
als Issue vorgeschlagen, nicht hier entschieden.
|
||||
- [ ] **Offen:** Ebenso wenig meldet etwas, wenn rohanas **öffentlicher** Weg
|
||||
wegbricht, solange der private trägt. Der CoreDNS-Zeiger macht den Cluster
|
||||
unempfindlich und damit blind.
|
||||
@@ -437,3 +437,63 @@ neun Kommentarzeilen, also am **Diff vor dem Commit**, nicht am Ergebnis.
|
||||
Soll-Menge") steht kurz vor seinem Nachweis: Die Herleitung läuft stündlich,
|
||||
die letzte lag vor dem Upgrade. Erscheint `2026.8.0` von selbst, ist das
|
||||
letzte offene Kriterium von #0106 erfüllt.
|
||||
|
||||
### Haufen A, zweiter Posten: cert-manager v1.14.0 → v1.21.1 (sieben Stufen)
|
||||
|
||||
**Recherche zuerst.** Die Anleitung lässt nur zwei Wege: *„one minor version at a
|
||||
time, always choosing the latest patch version"* — oder vollständige
|
||||
Deinstallation samt Neuinstallation. Gewählt: die sieben Stufen.
|
||||
|
||||
In sieben Fassungssprüngen gibt es **zwei** potenziell brechende Änderungen,
|
||||
beide gegen unseren Stand geprüft und **gegenstandslos**:
|
||||
|
||||
| Bruchstelle | Stufe | Bei uns |
|
||||
|---|---|---|
|
||||
| ACME-Metriken: `path`-Label entfällt zugunsten von `action` | 1.18→1.19 | `certmanager_acme*` wird **nirgends** ausgewertet |
|
||||
| `cert-manager-edit` verliert `create` auf Challenges/Orders | 1.19→1.20 | **null** Bindungen auf diese ClusterRole |
|
||||
|
||||
**Durchgeführt, jede Stufe einzeln ausgerollt und geprüft:**
|
||||
|
||||
| Stufe | Fassung | Deployments | Zertifikate |
|
||||
|---|---|---|---|
|
||||
| 1 | v1.15.5 | 3/3 | 15/15 Ready |
|
||||
| 2 | v1.16.5 | 3/3 | 15/15 Ready |
|
||||
| 3 | v1.17.4 | 3/3 | 15/15 Ready |
|
||||
| 4 | v1.18.6 | 3/3 | 15/15 Ready |
|
||||
| 5 | v1.19.6 | 3/3 | 15/15 Ready |
|
||||
| 6 | v1.20.3 | 3/3 | 15/15 Ready |
|
||||
| 7 | **v1.21.1** | 3/3 | **15/15 Ready** |
|
||||
|
||||
**Ergebnis, am Zielimage vorab gemessen:** CRITICAL **8 → 0**, HIGH **128 → 24**
|
||||
über Controller, Webhook und CAInjector.
|
||||
|
||||
**Funktionsprobe nach dem letzten Sprung:** Helm `Ready=True`, null
|
||||
Controller-Fehler in fünf Minuten, alle 15 Zertifikate mit gesetzter
|
||||
`renewalTime` (die neue Fassung hat sie also gelesen und eingeplant), 15 Orders
|
||||
im Zustand `valid`, **null** offene Challenges. Es wird nichts neu ausgestellt.
|
||||
|
||||
⚠️ **Unterbrochen von einem Vorfall**, siehe `docs/aar/2026-08-21-spiegel-ausfall.md`:
|
||||
Zwischen Stufe 1 und 2 stand die Ausrollstrecke rund eine Stunde, weil der
|
||||
Push-Spiegel nach git.lab → rohana nicht mehr durchkam.
|
||||
|
||||
### Zwei Kandidaten, die nach Messung NICHT angefasst wurden
|
||||
|
||||
**Wiki.js — das „Update" wäre eine Verschlechterung gewesen.** Wir fahren den
|
||||
gleitenden Tag `2.5`. Es gibt Release-Tags `2.5.275/276/277`, die nach
|
||||
Versionsnummer neuer aussehen. Gescannt:
|
||||
|
||||
| | CRITICAL | HIGH |
|
||||
|---|---|---|
|
||||
| `wiki:2.5` (läuft) | **12** | **114** |
|
||||
| `wiki:2.5.277` | **40** | **247** |
|
||||
|
||||
Der gleitende Tag zeigt auf einen **neueren Build** als das Release-Tag. Wer
|
||||
nach Nummer geurteilt hätte, hätte die kritischen Befunde verdreifacht. Das ist
|
||||
der beste Beleg dafür, warum „vor dem Update das Zielimage scannen" ins Runbook
|
||||
gehört.
|
||||
|
||||
**Draupnir** — `v3.1.0` ist die neueste Fassung (2026-05-07); `develop` ist kein
|
||||
Release. Seine 5 als „behebbar" gezählten CRITICAL sind es für uns **nicht**:
|
||||
Ein Paket-Fix nützt nichts, solange niemand das Image neu baut. ⚠️ Das ist eine
|
||||
Verfeinerung von Haufen A insgesamt — „behebbar" heißt *Paket hat einen Fix*,
|
||||
nicht *es gibt ein neueres Image*.
|
||||
|
||||
Reference in New Issue
Block a user