diff --git a/STATUS.md b/STATUS.md index 4125d05..768952d 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-2 | 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-4 | 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 2ddbe0f..b93f4ca 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-2 +status: gate-4 date: 2026-08-22 size: L related: @@ -267,3 +267,98 @@ 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.** + +## Gate 3 + 4 — Program Design und Slices + +Zusammengelegt: Es gibt **eine** zu ändernde Datei und eine Kommandofolge; ein +getrenntes Gate 4 hätte dieselbe Liste zweimal. + +### Die einzige Datei + +`/etc/systemd/system/k3s.service` — nichts sonst. Kein Manifest, kein +Helm-Wert, keine Zeile in einem Repo. + +⚠️ **Und das ist selbst ein Befund.** Die gesamte Konfiguration dieses Clusters +steht in einer Unit auf einem Host und in **keinem** Repository. Genau die +Lücke, die [#0110](../issues/0110-haertung-lebt-auf-dem-host-das-repo-weiss-nichts-davon.md) +für den Betriebs-Stack beschreibt — hier trifft sie den Cluster selbst. + +**Neue ExecStart-Zeile:** + +``` +/usr/local/bin/k3s server \ + --node-ip=10.0.0.2 \ + --node-external-ip=49.13.132.245 \ + --tls-san=49.13.132.245 +``` + +Drei Flags, jedes mit einem Grund: + +| Flag | warum | +|---|---| +| `--node-ip=10.0.0.2` | Der Knoten kündigt heute seine **öffentliche** Adresse als `InternalIP` an. Der vSwitch liegt auf `enp7s0`, die Route zu CFGMON geht darüber. | +| `--node-external-ip=49.13.132.245` | ⚠️ **Sonst veröffentlicht `servicelb` die private Adresse.** Der Traefik-Dienst trägt heute `49.13.132.245`, und **jeder** Ingress veröffentlicht sie. Ohne dieses Flag stünde dort `10.0.0.2`. | +| `--tls-san=49.13.132.245` | ⚠️ Die SANs des API-Zertifikats sind heute `49.13.132.245`, die öffentliche IPv6, `10.43.0.1`, `127.0.0.1`, `localhost`, `matrix`. **`10.0.0.2` fehlt.** Beim Adresswechsel wird das Zertifikat neu erzeugt; ohne dieses Flag kann die öffentliche Adresse herausfallen — und unsere Kubeconfig zeigt genau dorthin. | + +**Nicht** in der Zeile: `--disable=traefik`, `--disable=servicelb`. Sie werden +gestrichen, nicht repariert — der Ingress bleibt vorerst k3s-verwaltet. + +### Was der Adresswechsel NICHT anfasst — geprüft, nicht angenommen + +| | | +|---|---| +| **Alloy** | scrapt ausschließlich `role = "pod"`, keinen Kubelet und keine Knoten-Rolle. Unberührt. | +| **cert-manager** | HTTP01 über die IngressClass `traefik`; Let's Encrypt kommt über den öffentlichen Namen, der Weg ändert sich nicht. | +| **NetworkPolicies** | verweisen auf `kube-system` per Namensraum-Label, nicht auf Adressen. | +| **Prometheus remote-write** | geht aus dem Cluster nach `10.0.0.3` — Gegenrichtung, unberührt. | +| **Flux** | spricht `kubernetes.default` im Cluster an. | + +⚠️ **Was sich ändert und in die Abnahme gehört:** Der Knoten verliert seine +öffentliche **IPv6** als `InternalIP` (`--node-ip` setzt IPv4). Die Pod-CIDRs +sind ohnehin IPv4-only (in #0088 gemessen), aber die Serie `kube_node_info` +ändert sich — und damit möglicherweise Panels, die daran hängen. + +### Ablauf + +⚠️ **Ein Stopp, nicht zwei.** Der Datenbank-Abzug verlangt einen gestoppten +Dienst (eine offene sqlite-Datei ist kein konsistenter Abzug). Also wird +gestoppt, gesichert, aufgerüstet und gestartet — der Ausfall beginnt mit der +Sicherung, nicht mit dem Upgrade. + +| Slice | Was | Prüfung danach | +|---|---|---| +| **0** | **Vorher-Bild festhalten:** Pod-Liste, `kubectl get nodes -o wide`, SAN-Liste, Antwort von `axion1337.chat` und `wiki.axion1337.chat`, CVE-Zahlen. | Datei liegt vor; ohne sie ist „danach ist alles wie vorher" nicht belegbar. | +| **1** | `systemctl stop k3s`; `cp /usr/local/bin/k3s /root/k3s-v1.34.6.bak`; `cp /etc/systemd/system/k3s.service /root/k3s.service.bak`; `cp -a /var/lib/rancher/k3s/server/db /root/db-vor-1.34.10/` | Alle drei existieren, `db` ist ~60 MB. ⚠️ **Ohne diesen Beleg wird nicht weitergemacht.** | +| **2** | Installationsskript mit `INSTALL_K3S_VERSION=v1.34.10+k3s1`, `INSTALL_K3S_EXEC="server --node-ip=10.0.0.2 --node-external-ip=49.13.132.245 --tls-san=49.13.132.245"` und **`INSTALL_K3S_SKIP_START=true`** | ⚠️ **Nicht starten.** Erst die geschriebene Unit **lesen** und gegen die obige Zeile halten — genau hier liegt das Risiko dieses Vorhabens. | +| **3** | `systemctl start k3s` | Innerhalb ~70 s: Knoten `Ready`, Fassung `v1.34.10+k3s1`, alle Pods `Running`. | +| **4** | Abnahme gegen das Vorher-Bild | Ingress von außen, Anmeldung, SANs, Knoten-Adressen, sechs Komponenten-Fassungen. | +| **5** | Nacharbeit: die sechs `rancher/*`-Einträge aus `entscheidungen.json` entfernen, ADR schreiben, Ledger schließen | `cve_critical_offen` = 0, `cve_entscheidungen_ohne_befund` = 0. | + +### Grenzen — DO NOT CHANGE + +- **Kein `--disable`.** Nicht in dieser Zeile, nicht „schon mal vorbereitet". +- **Keine Minor-Sprünge.** Ziel ist exakt `v1.34.10+k3s1`. +- **Keine `HelmChartConfig`.** Traefik bleibt auf k3s-Vorgaben. +- **Kein Anfassen der Arbeitslasten.** Wer während des Fensters „schnell noch" + etwas ausrollt, macht die Abnahme wertlos. + +### Wackeligste Annahmen + +1. **Dass das Installationsskript `INSTALL_K3S_EXEC` so übernimmt, wie erwartet.** + Deshalb Slice 2 mit `SKIP_START` und Lesen statt Vertrauen. Wenn die Unit + anders aussieht: anhalten, nicht korrigieren und weiterlaufen. +2. **Dass ein Patch-Rückschritt trägt.** Innerhalb derselben Minor-Reihe ist er + unterstützt; sicher ist erst der Datenbank-Abzug daneben. +3. **Dass 70 Sekunden reichen.** Gemessen am Neustart vom 2026-08-01 — der war + allerdings **ohne** Fassungswechsel und ohne neue Images. Diesmal müssen + sechs Images gezogen werden. ⚠️ Realistisch also länger; die Images können in + Slice 0 vorgezogen werden (`crictl pull`), dann bleibt es bei der Größenordnung. + +### Neue ADRs + +**Einer**, nach dem Sprung zu schreiben: „Der Ingress bleibt vorerst +k3s-verwaltet; die drei nie wirksamen Flags werden gestrichen, `--node-ip` +wird bewusst gesetzt." Mit Beleg, warum die Flags vier Monate lang nichts taten +— sonst schreibt der Nächste sie aus guter Absicht zurück. + +> **STOP — wartet auf Gate-3/4-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 bf8dd6d..2362680 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 @@ -16,6 +16,7 @@ related: |---|---|---|---|---| | 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 | 1d0d5f1 | 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. | +| 3+4 | PENDING | sorb | DONE | Eine Datei, sechs Slices; ExecStart um `--node-external-ip` und `--tls-san` ergaenzt, weil `--node-ip` allein die veroeffentlichte Adresse und das API-Zertifikat mitreisst. | ## Slices @@ -34,6 +35,8 @@ related: | 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 | | +| was der Adresswechsel sonst anfasst, statt nur an die Kubeconfig zu denken | `servicelb` veroeffentlicht die Knoten-Adresse: der Traefik-Dienst UND jeder Ingress tragen heute 49.13.132.245 — ohne `--node-external-ip` stuende dort kuenftig 10.0.0.2 | built: die ExecStart-Zeile traegt jetzt drei Flags statt einem; der Fund kam aus dem Nachsehen, nicht aus dem Nachdenken | | +| ob Alloy oder cert-manager an der Knoten-Adresse haengen | Alloy scrapt ausschliesslich `role = "pod"`, kein Kubelet, keine Knoten-Rolle; cert-manager loest HTTP01 ueber den oeffentlichen Namen | reused: die eigene Konfiguration als Pruefmassstab — zwei vermutete Risiken sind damit gegenstandslos, statt sie vorsorglich zu behandeln | | | 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