diff --git a/STATUS.md b/STATUS.md index c98b9ee..4125d05 100644 --- a/STATUS.md +++ b/STATUS.md @@ -88,7 +88,7 @@ Bedeutung der Meilensteine: siehe [roadmap.md](roadmap.md). | Design | Gate | Title | |---|---|---| -| [2026-08-22-k3s-patch-1-34-10](docs/design/2026-08-22-k3s-patch-1-34-10.md) | gate-1 | Design: k3s v1.34.6 → v1.34.10 — die mitgelieferten Komponenten nachziehen | +| [2026-08-22-k3s-patch-1-34-10](docs/design/2026-08-22-k3s-patch-1-34-10.md) | gate-2 | Design: k3s v1.34.6 → v1.34.10 — die mitgelieferten Komponenten nachziehen | ## ADRs (27) diff --git a/docs/design/2026-08-22-k3s-patch-1-34-10.md b/docs/design/2026-08-22-k3s-patch-1-34-10.md index 661e79d..2ddbe0f 100644 --- a/docs/design/2026-08-22-k3s-patch-1-34-10.md +++ b/docs/design/2026-08-22-k3s-patch-1-34-10.md @@ -1,6 +1,6 @@ --- type: design -status: gate-1 +status: gate-2 date: 2026-08-22 size: L related: @@ -119,3 +119,151 @@ angefasst wird. Der Preis ist ein Neustart der Plattform und ein Chart-Major bei Traefik — beides plan- und prüfbar, aber nicht nebenbei. > **STOP — wartet auf Gate-1-Freigabe.** + +## Gate 2 — Architecture + +### Inputs read + +- **AAR 2026-08-21 (MAS/haproxy)** — die Lehre „vor einem Chart-Sprung + vergleichen, welche internen Ziele sich verschieben". Hier angewandt: der + Traefik-Chart-Major ist gerendert und verglichen, **bevor** etwas startet. +- **AAR 2026-08-21 (Spiegel-Ausfall)** — „erst ausrollen und prüfen, dann die + nächste Stufe". Hier gibt es nur eine Stufe, aber dieselbe Regel gilt für den + Rückweg: er wird hergestellt, nicht angenommen. +- **#0088** — die NetworkPolicies. Sie verweisen auf `kube-system` über das + Namensraum-Label, nicht über Adressen; Traefik bleibt in `kube-system`. + **Von diesem Sprung nicht berührt** (geprüft, nicht vermutet). +- **ADR-0026** — Prüfziele werden abgeleitet. Nach dem Sprung fallen die alten + `rancher/*`-Ziele von selbst aus der Menge; ihre Einträge in + `entscheidungen.json` werden dann als `ohne_befund` sichtbar und entfernt. + +### Zielfassungen — gepinnt, nicht geschätzt + +Aus `k3s-images.txt` der Release **v1.34.10+k3s1**, nicht aus Tag-Listen: + +| Komponente | läuft | v1.34.10 | HIGH | CRITICAL | +|---|---|---|---|---| +| klipper-helm | v0.9.14-build20260309 | **v0.13.3-build20260727** | 73 → **23** | 4 → **0** | +| traefik | 3.6.10 | **3.7.8** | 64 → **15** | 4 → **0** | +| coredns | 1.14.2 | **1.14.6** | 50 → **21** | 1 → **0** | +| metrics-server | v0.8.1 | **v0.9.0** | 40 → **11** | 2 → **0** | +| local-path-provisioner | v0.0.35 | **v0.0.36** | 39 → **19** | 2 → **0** | +| klipper-lb | v0.4.15 | **v0.4.17** | 12 → **0** | 2 → **0** | +| | | **Summe** | **278 → 89** | **15 → 0** | + +⚠️ **Das korrigiert Abnahmekriterium 2 nach unten.** Gate 1 verlangte „≥ −200 +HIGH"; das war gegen die **neuesten** Tags gemessen, nicht gegen die, die diese +Release mitbringt (z. B. CoreDNS 1.14.7 statt 1.14.6). Exakt sind es **−189 +HIGH und −15 CRITICAL**. Die Zahl wird hier vor der Arbeit berichtigt und nicht +hinterher passend gemacht — das Kriterium lautet ab jetzt **−189 HIGH**. + +### Der Traefik-Chart-Major ist ein Nicht-Ereignis + +Chart **39.0.501+up39.0.5 → 40.1.4+up40.1.0**. Verglichen wurde das **echte** +Chart von der Platte des Knotens gegen upstream 40.1.0, gerendert mit den +Werten, die k3s tatsächlich setzt (aus der `HelmChart`-Ressource): + +| | | +|---|---| +| Objekte | identisch | +| Dienst `traefik`, Ports, targetPorts | identisch | +| Selektoren (Deployment und Service) | identisch | +| Container-Ports | identisch | +| RBAC-Ressourcen | identisch | +| Container-Argumente | identisch | + +Einziger Unterschied im gesamten Rendering: das Image trägt neu ein +`docker.io/`-Präfix. Die von k3s benannte Bruchstelle des Majors +(`kubernetesIngressNginx` → `kubernetesIngressNGINX`) betrifft uns nicht: es +gibt kein ingress-nginx, die einzige IngressClass ist `traefik`, und wir setzen +**keine** `HelmChartConfig`. + +### Ausfallzeit — aus der eigenen Historie gemessen + +Der letzte Neustart des Dienstes war am **2026-08-01 19:37:06**. Er hat **kein +einziges Pod-Objekt** neu erzeugt (die kube-system-Pods datieren auf April), +aber **alle Container** neu gestartet: + +``` +19:37:06 k3s startet +19:37:10 local-path 19:37:12 traefik 19:37:13 clamav, svclb +19:37:16 postgres 19:38:14 draupnir (letzter) +``` + +**~70 Sekunden**, dann war alles wieder oben. Das ersetzt die Schätzung +„einige Minuten" aus Gate 1. + +### ⚠️ Der eigentliche Fund: drei Flags, die seit der Installation nichts tun + +`ExecStart` der Unit lautet — seit dem 2026-04-21 unverändert —: + +``` +/usr/local/bin/k3s server server --disable=traefik --disable=servicelb --node-ip=10.0.0.2 +``` + +**`server` steht zweimal da.** Das zweite ist ein Positionsargument; alles +danach wird nicht mehr als Flag gelesen. Belegt am laufenden System, nicht +hergeleitet: + +| Beleg | Wert | +|---|---| +| `k3s.io/node-args` (Knoten-Annotation) | `["server","server","--disable","traefik","--disable","servicelb","--node-ip","10.0.0.2"]` | +| `k3s.io/internal-ip` | **`49.13.132.245,2a01:…`** — die öffentliche Adresse, nicht `10.0.0.2` | +| `/var/lib/rancher/k3s/server/manifests/` | enthält **`traefik.yaml`**, geschrieben beim letzten Start | +| Cluster | Traefik **und** `svclb-traefik` laufen | + +k3s hat die Flags also entgegengenommen und **keines davon angewandt**. + +**Warum das dieses Vorhaben bestimmt:** Das Installationsskript **schreibt +`k3s.service` neu**. Was es schreibt, wird nicht dieselbe kaputte Zeile sein. +Werden die Flags dabei wirksam, dann beim nächsten Start: + +- **Traefik und servicelb werden entfernt** — der gesamte eingehende Verkehr, + `axion1337.chat` und `wiki.axion1337.chat` inbegriffen, ist weg. +- **Die Knoten-Adresse wechselt** von der öffentlichen auf `10.0.0.2`. Das + betrifft die Server-Zertifikate (SANs), die Kubeconfig, den svclb und alles, + was den Knoten über seine angekündigte Adresse findet. + +Das ist ein größeres Risiko als alles, was in Gate 1 stand — und es hat mit +dem Fassungssprung nichts zu tun. Es liegt seit vier Monaten scharf und wartet +auf irgendeinen Neustart. + +### Optionen für die Unit — zu entscheiden, nicht von mir + +| | Was | Preis | +|---|---|---| +| **A** | ExecStart bewusst auf `k3s server` setzen: die drei Flags werden **gestrichen**, der Ist-Zustand wird zur Absicht. | Traefik und servicelb bleiben k3s-verwaltet. Ändert nichts am Verhalten — macht nur wahr, was ohnehin läuft. | +| B | Die Flags **wirksam** machen. | Braucht vorher einen Ersatz für den Ingress und eine Entscheidung über die Knoten-Adresse. Ein eigenes Vorhaben, nicht dieses. | +| C | Die kaputte Zeile wörtlich erhalten. | Das Installationsskript müsste daran gehindert werden. Fragil, und der nächste Mensch stolpert genauso. | + +**Meine Empfehlung: A** — und weil das eine dauerhafte Aussage über die +Verdrahtung dieses Clusters ist, gehört sie in ein ADR, nicht in einen +Commit-Text. + +### Randbedingungen + +- **Ein Knoten, sqlite** (`state.db`, 60 MB), 114 GB frei. Kein etcd, also kein + `etcd-snapshot`; der Rückweg ist ein Dateiabzug bei gestopptem Dienst. +- **Kein `config.yaml`** unter `/etc/rancher/k3s/`, keine systemd-Drop-ins. Die + gesamte Konfiguration steckt in der einen ExecStart-Zeile. +- **Kubeconfig** zeigt auf die öffentliche Adresse; eine Änderung der + Knoten-Adresse würde sie mitreißen. + +### Rückweg + +Vor dem Start, in dieser Reihenfolge: + +1. `cp /usr/local/bin/k3s /root/k3s-v1.34.6+k3s1.bak` — das laufende Binary. +2. `systemctl stop k3s`, dann `cp -a /var/lib/rancher/k3s/server/db /root/db-vor-1.34.10/` — **bei gestopptem Dienst**, sonst ist die sqlite-Datei kein konsistenter Abzug. +3. `cp /etc/systemd/system/k3s.service /root/k3s.service.bak` — die Unit, deren Neuschreiben das Risiko ist. + +Zurück: Dienst stoppen, Binary und Unit zurücklegen, `db` zurückspielen, +starten. Ein Patch-Rückschritt innerhalb derselben Minor-Reihe ist unterstützt. + +### Neue ADRs + +**Einer**: „Die drei nie wirksamen k3s-Flags werden gestrichen, nicht +repariert." Begründung, Beleg und die verworfenen Optionen B und C gehören +festgehalten — sonst schreibt sie der nächste Mensch aus guter Absicht zurück. + +> **STOP — wartet auf Gate-2-Freigabe.** diff --git a/docs/ledger/2026-08-22-k3s-patch-1-34-10.md b/docs/ledger/2026-08-22-k3s-patch-1-34-10.md index 402f34f..f543bb2 100644 --- a/docs/ledger/2026-08-22-k3s-patch-1-34-10.md +++ b/docs/ledger/2026-08-22-k3s-patch-1-34-10.md @@ -15,6 +15,7 @@ related: | gate | commit | approval | status | note | |---|---|---|---|---| | 1 | bf2d87a | sorb | DONE | Umfang, sechs Abnahmekriterien, zwei offene Entscheidungen (Ausfallzeit, Traefik-Chart-Major); ⚠️ korrigiert die eigene Aussage „grosses Vorhaben" — es ist ein Patch auf der eigenen Minor-Reihe. | +| 2 | PENDING | sorb | DONE_WITH_CONCERNS | Fassungen gepinnt, Traefik-Major gerendert (identisch), Ausfallzeit aus der Historie gemessen (~70 s); ⚠️ Fund: drei k3s-Flags sind seit der Installation unwirksam, und das Installationsskript schreibt die Unit neu. | ## Slices @@ -29,7 +30,11 @@ related: | ob die mitgelieferten Images ueberhaupt neuere Fassungen haben | alle sechs haben welche; die Tag-Listen sind alphabetisch sortiert und taeuschen (1.9.4 steht dort hinter 1.14.2) | reused: eine Sortierung nach Zahlenfolge statt der Voreinstellung — sonst waere der Befund „nichts Neueres" gewesen | | | welche k3s-Release welche Komponenten mitbringt, statt Tags zu raten | die Release-Notes zu v1.34.10+k3s1 nennen jede Fassung einzeln — Traefik v3.7.8, CoreDNS v1.14.6, metrics-server v0.9.0, local-path v0.0.36, helm-controller v0.16.26 | reused: die Herausgeber-Notizen als Quelle; damit steht fest, dass ein PATCH genuegt und kein Minor-Sprung noetig ist | | | ob wir k3s' Vorgaben irgendwo ueberschreiben | keine einzige `HelmChartConfig` im Cluster, keine im Repo; einzige IngressClass ist `traefik` | reused: der eigene Bestand als Pruefmassstab — die benannte Bruchstelle des Chart-Majors (ingress-nginx-Provider) trifft uns damit nicht | | -| ob die Gesamtzahl „4000 CVEs" ueberhaupt bearbeitbar ist | 1578 HIGH sind 238 verschiedene Kennungen; 2438 MEDIUM/LOW existieren NUR als Zaehler, ohne CVE, Paket oder Fix-Fassung | reused: nichts — aber der Befund grenzt das Vorhaben ab: MEDIUM ist keine Arbeit, sondern zuerst eine Datenfrage | | +| ob die Gesamtzahl „4000 CVEs" ueberhaupt bearbeitbar ist | 1578 HIGH sind 238 verschiedene Kennungen; 2438 MEDIUM/LOW existieren NUR als Zaehler, ohne CVE, Paket oder Fix-Fassung | reused: nichts — aber der Befund grenzt das Vorhaben ab: MEDIUM ist keine Arbeit, sondern zuerst eine Datenfrage | bf2d87a | +| die genauen Fassungen der Release, statt die neuesten Tags zu nehmen | `k3s-images.txt` der Release nennt jedes Image mit Tag — klipper-helm v0.13.3-build20260727, coredns 1.14.6, local-path v0.0.36 | reused: das Herausgeber-Verzeichnis; die Korrektur kostet 29 HIGH gegenueber meiner Schaetzung und wird VOR der Arbeit im Kriterium nachgezogen | | +| das ECHTE laufende Traefik-Chart, statt upstream als Stellvertreter zu nehmen | k3s legt die Chart-Tarballs unter `/var/lib/rancher/k3s/server/static/charts/` ab; von dort geholt und mit den echten `HelmChart`-Werten gerendert | reused: der laufende Bestand als Vergleichsseite — Objekte, Dienste, Ports, Selektoren, RBAC und Argumente sind identisch | | +| wie lange ein k3s-Neustart wirklich kostet, statt „einige Minuten" zu schaetzen | der Neustart vom 2026-08-01 steht in den Container-Startzeiten: 19:37:06 Dienst, 19:38:14 letzter Container | reused: die eigene Historie als Messung — ~70 s statt einer Vermutung, und kein Pod-Objekt wurde neu erzeugt | | +| ob die Unit ueberhaupt das tut, was sie sagt | NEIN: `server` steht zweimal in ExecStart, alles danach wird als Positionsargument gelesen. `k3s.io/node-args` fuehrt die Flags, `k3s.io/internal-ip` zeigt die oeffentliche Adresse, `traefik.yaml` ist ausgerollt | built: nichts — aber der Fund bestimmt das ganze Vorhaben: das Installationsskript schreibt die Unit neu, und dann werden drei seit vier Monaten stille Flags scharf | | ## Notes