From cc2f237ca3b2851e10572e11ea1ddc2761d5b68d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Dominik=20Sch=C3=B6n?= Date: Wed, 30 Sep 2026 18:22:25 +0000 Subject: [PATCH] ceph: SMART-Audit rehabilitiert Kingston NVMe (kein Austausch); mgr-union scraping --- index.md | 4 +++ log.md | 35 ++++++++++++++++++++ patterns/ceph-dead-nvme-resurrection.md | 44 +++++++++++++++++++++++++ patterns/placement-guardrails.md | 23 +++++++++++++ patterns/prometheus-config-rescue.md | 28 ++++++++++++++++ patterns/pve-notification-webhook.md | 22 +++++++++++++ systems/ceph-cluster.md | 14 +++++++- systems/proxmox-cluster.md | 21 ++++++++---- 8 files changed, 183 insertions(+), 8 deletions(-) create mode 100644 patterns/ceph-dead-nvme-resurrection.md create mode 100644 patterns/placement-guardrails.md create mode 100644 patterns/prometheus-config-rescue.md create mode 100644 patterns/pve-notification-webhook.md diff --git a/index.md b/index.md index 4ddc046..f0dde64 100644 --- a/index.md +++ b/index.md @@ -62,6 +62,10 @@ - [[patterns/ansible-default-ipv6]] — lablabs.rke2 role fails on IPv6-less VMs (PAT-008) - [[patterns/k8s-stale-nbd-devices]] — RBD swap leaves stale NBD mappings (PAT-009) - [[patterns/pve-oom-frozen-guest]] — Host-OOM friert Gast als Zombie ein, RSS-Kollaps-Signatur (PAT-010) +- [[patterns/pve-notification-webhook]] — PVE Webhook→Telegram: Endpoint-Drift, Base64-Trap, Handlebars-Escape (PAT-011) +- [[patterns/placement-guardrails]] — 70% RAM-Deckel + Swap-Verbot als Prometheus-Rules (PAT-012) +- [[patterns/prometheus-config-rescue]] — grep -vn Gift/Crashloop, LXC-Rootfs-Direct-Mount-Rescue (PAT-013) +- [[patterns/ceph-dead-nvme-resurrection]] — PCI-Reset→lvchange→chown-Falle, Weight-Management bei Reintegration (PAT-014) - [[patterns/skill-impact]] — Skill Modification Audit Trail ## Memory Layer Architektur diff --git a/log.md b/log.md index a31847c..8885d8e 100644 --- a/log.md +++ b/log.md @@ -1,5 +1,40 @@ # Memory Log +## [2026-09-30] ceph-osd-resurrection | NVMe-Revival osd.2 + osd.3-Weight-Drama + ubuntu-Hosts-Fix (PAT-014) +- osd.2 (ubuntu, Kingston SFYRDK2000G) tot: NVMe-Controller state=dead, VG verschwunden, errno-5. Revival-Kette: PCI remove/rescan (Ctrl kam als nvme2 zurück!) → pvscan --cache → lvchange -ay -K (stale DM-Table) → dd-Lesetest 1,4 GB/s → chown ceph:ceph am Mapper-Device (udev-Falle) → ACTIVE, Weight 1.0, 495 GiB. Drive = Replacement-Kandidatin. +- osd.3-Lehre: re-in mit Weight 1.0 → instant 96 % voll → backfillfull, 13 PGs blockiert. Korrekt: `crush reweight osd.3 0.05` + in. Cluster 17/17 up/in, Degraded 0,78 % fallend. +- ubuntu-Hosts-Fix: `10.0.20.100 ubuntu` in /etc/hosts aller 8 PVE-Nodes → GUI-500 „hostname lookup failed" behoben. +- Doc: bug-fixes/2026-09-30-ceph-osd2-nvme-resurrection-osd3-drain.md, Pattern PAT-014. + +## [2026-09-30] watchdog-self-healed | Guardrail-Rollout begleitender Incidents (PAT-013) +- Beim Guardrail-Rollout entdeckt: Phantom-ICMP-Targets .10/.20 lebten NOCHMAL im blackbox_icmp-Abschnitt (erste Bereinigung traf nur node_exporter-Liste) → HostUnreachableICMP-Alerts. Entfernt, 12 ICMP-Probes, alle grün. +- Eigener Fehler: `grep -vn`-Rewrite fügte Zeilennummer-Präfixe ("1:global:") in prometheus.yml ein → Prometheus Crashloop. **Rescue-Pfad etabliert:** CT-Rootfs direkt am Host mounten (`mount /dev/rbd2 /mnt/...` — rbd2 = CT141-Disk), Fix außerhalb des pct-Kanals, Container recreation. Prometheus wieder HEALTHY, 28 Targets, DOWN=[], alle Rules ok. +- **Lessons**: (a) NIEMALS `grep -n`-Ausgaben als Rewrite-Source verwenden; (b) LXC-Rootfs-Host-Mount = universeller Rescue-Kanal wenn pct exec zickt; (c) nach jedem Rewrite YAML-validieren BEVOR recreate. +- Doc: bug-fixes/2026-09-30-prometheus-yaml-prefix-crashloop.md, Commit . + +## [2026-09-30] guardrails-live | Placement-Policies maschinell erzwingbar (PAT-012) +- Zwei neue Rules in CT141 (`placement_guardrails`): PVEPlacementCeilingBreached (>70% RAM, 15m) + HVResidentSwapNonzero (>100MiB, 10m). Alle Rules health=ok. +- Baseline: proxmox3 80,6% / p4 79,3% / p5 75,5% / p6 72,6% ÜBER Deckel → Warnbursts erwartet (Rebalancing-Backlog Richtung ms-a2-1/-2 mit 74%/Headroom). +- Doc: architecture/2026-09-30-placement-guardrails-ram-ceiling.md, Commit 66f2172. + +## [2026-09-30] webhook-fixed | PVE→Telegram Notification-Pipeline repariert (PAT-011) +- Ursachenkette (dreifach gestapelt): Endpoint-Drift .99→.141 (Bridge wohnt in CT141), fehlender `body`-Attr (Leere Posts → 400), unescapte Handlebars-Interpolation (Apostrophe/Multiline → invalides JSON). +- Fix: URL korrigiert, Body via pvesh (BASE64-Pflicht!) mit `{{escape title}}`/`{{escape message}}` (Space-Syntax, NICHT Colon). Offizieller Test grün, Bridge loggt POST /pve 200. +- Diagnose-Technik: Mini-Sniffer (temp URL-Redirect, Bytes kapern, URL restaurieren) enthüllte exakten Wire-Body. +- Doc: bug-fixes/2026-09-30-pve-webhook-notifications-drift-base64-escape.md, Commit 38622ff. Residue ge cleaned (HV+/tmp+lokales). + +## [2026-09-30] legacy-alert-cleanup | Alerts bereinigt, mysqld_exporter VM300 nachgezogen +- proxmox3 /boot/efi 100%: 17 alte Kernel-Pakete gepurged (-17/-19/-12 behalten) → 30%. +- Phantom-Targets .10/.20 entfernt, ICMP→TCP-Probe für Offsite-PBS (ICMP upstream gefiltert) → 30 Targets. +- VM300 mysqld_exporter 0.15.1 nachdeployt (war aspirational Target): GitHub-Download via qm guest exec+b64, exporter-User (vorgeschädigte exporter@localhost-Shadow!) PW-Align, UFW 9104←10.0.30.141. Alle 3 Galera-Exporte UP. +- Cleanup: alle /tmp-Skripts (HV+CT141+VM300), lokale Scratch-Dirs entfernt. + +## [2026-09-30] remediation-complete | Vorfall-Nacharbeiten: GPU restored, PSI/OOM-Alerts live, p6 entlastet +- GPU (VM102/ms-a2-2): hostpci0 ohne x-vga restauriert → renderD128 lebt. **x-vga=1 bricht AMD-Passthrough** (SeaBIOS Shadow-ROM → VBIOS-Zugriff tot, amdgpu -22). Doc-Update in 2026-07-21-amd-gpu-passthrough-rombar.md. +- Monitoring (CT141): Regelgruppe `pressure_alerts` (5 Regeln: PSI mem waiting/stalled, oom_kill, Swap-Churn, MajFault-Storm) live; node_exporter auf ms-a2-1/-2 nachinstalliert (Blindspots!), 32 Targets. **LXC-Bindmount-Inode-Trap:** sed-i/In-Place-Rewrites unsichtbar für Docker bis Force-Recreate → neues Doc. +- proxmox6: VM301 → proxmox7 (HA relocate, na-vm301 live verifiziert). Swap 6,3G→0B, RAM 8,4/15G. Nur noch CT151 auf p6. Altlast-Alerts sichtbar geworden (NodeDown .10/.20 Phantoms, proxmox3 /boot/efi 100%, ICMP 213.95.54.60) — Cleanup offen. +- Docs: bug-fixes/2026-09-30-prometheus-lxc-bindmount-inode-trap.md (neu), INDEX.md aktualisiert. + ## [2026-09-30] incident-fix | worker-05 Freeze: proxmox6 Doppel-OOM → Zombie-VM (PAT-010) - Symptom: KubeDaemonSetRolloutStuck (Traefik DS misscheduled=1), worker-05 NotReady 19h - Root Cause: proxmox6 RAM-Oversubscription (~47.8 GB alloc / 16 GB, 7.3/8 GB Swap) → OOM-Killer tötete kvm (VM102) 2× (29.09. 18:43 + 20:44); 2. Revival = Zombie (QEMU running, Gast inert, RSS 239MB/12GB) diff --git a/patterns/ceph-dead-nvme-resurrection.md b/patterns/ceph-dead-nvme-resurrection.md new file mode 100644 index 0000000..fb02940 --- /dev/null +++ b/patterns/ceph-dead-nvme-resurrection.md @@ -0,0 +1,44 @@ +# PAT-014 — Dead-NVMe-Resurrection für Ceph-OSD + +## Trigger +Ceph-OSD auf externem/non-Corosync-Host startet nicht: KernelDevice errno-5 I/O-Errors beim +Label-Lesen, Symlink `/var/lib/ceph/osd/ceph-*/block` ins Leere, VG „verschwindet". + +## Root Cause +NVMe-Controller im PCIe-Fabric gestorben (state=dead, Namespace 0B) — NICHT das Medium selbst. +Nach PCI-reset kehrt der Controller oft unter NEUER Nummer zurück (nvme0 → nvme2!), alte +Device-Mapper-Tabelle bleibt stale. + +## Resurrection-Sequence (verifizierte Reihenfolge) +1. **Korrekte PCI-Addr finden**: über sysfs-Pfad des Namespaces (`/sys/class/block/nvmeXnY/device`), + NICHT raten — erster Versuch traf den falschen (gesunden!) Controller. +2. `echo 1 > /sys/bus/pci/devices//remove && echo 1 > /sys/bus/pci/rescan` + → Controller kommt als neue Instanz zurück, Namespaces wieder da. +3. `pvscan --cache` → VG/LV wieder sichtbar. +4. **Stale DM-Table**: `lvchange -an / && lvchange -ay -K /` +5. **Lesetest**: `dd if=/dev// bs=4M count=8 of=/dev/null` — bei weiteren errno-5: + NAND/Media defekt → OSD out lassen, Drive tauschen. +6. **Permissions-Falle nach lvchange**: udev setzt Owner root → + `chown ceph:ceph /dev/mapper/; chmod 660` (sonst `bdev open: (13) Permission denied`). +7. `systemctl reset-failed ceph-osd@ && systemctl start ceph-osd@` +8. `ceph osd in osd.` + Weight restaurieren. + +## Begleitregeln +- Klein/niedergewichtetes OSD niemals mit Weight 1.0 reintegrieren, solange Pools an + Full-Ratios kratzen → sonst `backfillfull`/`backfill_toofull`-Blockade (Fall osd.3: + re-in@1.0 → 96 % voll instant → 13 PGs blocked; Fix: `crush reweight osd.3 0.05`). +- Externe Non-Corosync-Hosts in `/etc/hosts` ALLER PVE-Nodes pflegen (GUI-500 + „hostname lookup failed"), oder echter DNS-Record. + +## Verified +2026-09-30: osd.2 revived (Kingston SFYRDK2000G, PCI 03:00.0, → nvme2), 495 GiB, Weight 1.0; +Cluster 17/17 up/in; Degraded 0,78 % fallend. osd.3 stabilized @ weight 0.05. + +## Smart-Log-Abgleich 2026-09-30 (korrigiert frühere Alters-These) +Kingston SFYRDK2000G (nvme0n2, trägt osd.2): percentage_used **6 %**, media_errors **0**, +available_spare 100 %, unsafe_shutdowns 2, power_on_hours 1469, power_cycles 3. +Geschwisterplatte nvme1n1 identisches Profil (6 % wear, 0 media errors). +⇒ Drive ist MEDIZINISCH GESUND — der Vorfall war rein Controller-(PCI)-Ebene, kein +Media-Verschleiß. **Kein Austausch nötig.** Einziges Beobachtungsfeld: Temperatur 70 °C / +Sensor2 78 °C (thermisches Throttling T1 3× aktiviert) — Kühlung prüfen wäre sinnvoll, +aber keine Akutgefahr. diff --git a/patterns/placement-guardrails.md b/patterns/placement-guardrails.md new file mode 100644 index 0000000..4aacb43 --- /dev/null +++ b/patterns/placement-guardrails.md @@ -0,0 +1,23 @@ +# PAT-012 — Placement Guardrails (RAM-Deckel + Swap-Verbot) + +**Trigger**: Neue Gastplatzierung oder Kapazitätsfrage auf einem PVE-Node. + +**Policy**: +- Committed RAM pro Hypervisor ≤ 70 % physikalisch. Über Deckel = "voll", + Guests redistribuieren BEVOR neue Last kommt. +- Resident Swap > 100 MiB für >10 min = Politikverstoß → Placements prüfen, + nie als Normalzustand akzeptieren. + +**Enforcement (live)**: Gruppe `placement_guardrails` in CT141 +(`/opt/monitoring/prometheus/rules/alerting_rules.yml`): +- `PVEPlacementCeilingBreached` (ratio > 0.70, for 15m, warning) +- `HVResidentSwapNonzero` (SwapTotal-Free > 100MiB, for 10m, warning) + +**Vor jeder Platzierung**: Ratio-Query ziehen +(`pve_memory_usage_bytes{id=~"node/.*"} / pve_memory_size_bytes{id=~"node/.*"}`) +— >70 %-Nodes meiden, Headroom liegt primär auf ms-a2-1/ms-a2-2. + +Baseline-Rollout 30.09.: proxmox3 80,6 / p4 79,3 / p5 75,5 / p6 72,6 % +über Deckel (Warnburst erwartet = Rebalancing-Backlog, kein Emergency). + +Ref: docs/solutions/architecture/2026-09-30-placement-guardrails-ram-ceiling.md diff --git a/patterns/prometheus-config-rescue.md b/patterns/prometheus-config-rescue.md new file mode 100644 index 0000000..c914c4e --- /dev/null +++ b/patterns/prometheus-config-rescue.md @@ -0,0 +1,28 @@ +# PAT-013 — Prometheus Config Rescue (Crashloop + LXC Rootfs Channel) + +**Trigger**: Prometheus crashloop nach Config-Rewrite, oder pct exec unbrauchbar. + +**Iron Rules**: +1. NIEMALS `grep -n`-Ausgabe als Rewrite-Source — Nummernpräfixe verseuchen die Datei. + Nutze `grep -v` (ohne -n) oder Python/awk. +2. YAML validieren BEVOR Container recreate (sonst Crashloop = totale Blindheit). +3. Beim Löschen von Targets/IPs ALLE Locations sweeppen — Dubletten leben gern in + mehreren Jobs derselben Datei (node_exporter-Liste ≠ blackbox-Liste). + +**Rescue-Kanal (universell für LXC auf RBD)**: +```bash +# Auf dem Hyper visor, der den CT hostet: +lsblk # rbdX finden (size matchen) +mount /dev/rbdX /mnt/rescue +# Dateien direkt editieren unter /mnt/rescue/opt/... +umount /mnt/refuge +# im CT: docker compose up -d --force-recreate +``` + +**Symptom-Signature Crashloop**: `docker logs prometheus` → "yaml: line N: mapping +values are not allowed in this context" = klassisches NN:-Präfix-Gift. + +**Stale-Series-Note**: gelöschte Targets erscheinen sekundenweise weiter in Queries — +erst nach Scrape-Zyklus-Gap re-checken, dann Erfolg erklären. + +Ref: docs/solutions/bug-fixes/2026-09-30-prometheus-yaml-prefix-crashloop.md diff --git a/patterns/pve-notification-webhook.md b/patterns/pve-notification-webhook.md new file mode 100644 index 0000000..4760e8a --- /dev/null +++ b/patterns/pve-notification-webhook.md @@ -0,0 +1,22 @@ +# PAT-011 — PVE Webhook Notifications Pipeline Repair + +**Trigger**: PVE notifications (esp. vzdump) reach Telegram not / test returns 500. + +**Signature diagnosis ladder**: +1. `pvesh create /cluster/notifications/targets//test` — error taxonomy: + - `Connection refused` → transport/down (check URL target alive) + - `failed to render webhook body` → template broken (syntax/base64) + - `http status: 400` → bridge rejected payload (escaping!) +2. Listener-Sweep über VLAN: `for ip in .xx…; do /dev/tcp/$ip/port probe; done` +3. Byte-Level-Truth via temp mini-sniffer (redirect URL, capture, restore!). + +**Hard rules**: +- Mutations an `/etc/pve/notifications.cfg` NUR via `pvesh set` (hand-edits poison + global deserialization!). Vorher Snapshot. +- `body`/header-values/secrets = **base64 blobs**: `printf '%s' tpl | base64 -w0`. +- Handlebars helpers: `{{escape title}}` (Space!), NICHT `{{escape:title}}`. +- Immer `{{escape title}}`/`{{escape message}}` verwenden — rohe Interpolation bricht + bei Apostrophen/Multiline (Backup-Reports!). +- Sniffer-Redirect URL IMMER restaurieren. + +Reference: `docs/solutions/bug-fixes/2026-09-30-pve-webhook-notifications-drift-base64-escape.md` diff --git a/systems/ceph-cluster.md b/systems/ceph-cluster.md index a2736fe..653d262 100644 --- a/systems/ceph-cluster.md +++ b/systems/ceph-cluster.md @@ -23,7 +23,7 @@ modified: "2026-09-26" |-----|-------|------|------|----------|-------| | 1 | hdd | 3.7 TiB | n5pro | 1.0 | | | 2 | ssd | 1.8 TiB | ubuntu | 1.0 | Moved to ubuntu host | -| 3 | ssd | 233 GB | proxmox4 | 1.0 | | +| 3 | ssd | 233 GB | proxmox4 | 0.05 | 2026-09-30: reweighted 0.05 nach Full-Drama (war 1.0) — Plate 238G, sonst backfillfull | | 4 | ssd | 227 GB | proxmox3 | 0.30 | Small, reweighted down | | 5 | ssd | 150 GB | proxmox5 | 0.30 | Small, reweighted down | | 6 | hdd | 3.6 TiB | n5pro | 1.0 | | @@ -73,6 +73,18 @@ Fix: `ceph config set mon mon_allow_insecure_global_id_reclaim false` (if not al osd.4 (227GB, proxmox3) and osd.5 (150GB, proxmox5) reweighted to 0.30 — too small for meaningful capacity. Consider removing from CRUSH or replacing with larger drives. +### NVMe-Controller-Death auf ubuntu + Recovery (2026-09-30, PAT-014) +Kingston SFYRDK2000G (PCI 03:00.0) starb (state=dead, VG verschwand) → osd.2 down/out. +Revived via PCI remove/rescan + lvchange -ay -K + chown-Falle am mapper-device. +Details: patterns/ceph-dead-nvme-resurrection (PAT-014). **Update 2026-09-30 (Abend): SMART- +Audit spricht FREI — percentage_used 6 %, media_errors 0, spare 100 %, PoH 1469. Vorfall war +rein Controller-Ebene, kein Media-Verschleiß, KEIN Austausch nötig. Beobachten: Temps 70/78 °C, +thermal throttle T1 3×.** + +### ubuntu-Host in /etc/hosts aller PVE-Nodes (2026-09-30) +Ohne DNS-Record wirft die PVE-GUI `hostname lookup 'ubuntu' failed (500)`. +Fix: hosts-Eintrag `10.0.20.100 ubuntu` fleetweit auf allen 8 Nodes. + ### worker-04 (VM 139) NotReady in K8s Node offline — not a Ceph issue but affects Ceph CSI attachments. diff --git a/systems/proxmox-cluster.md b/systems/proxmox-cluster.md index 2087818..fc4967c 100644 --- a/systems/proxmox-cluster.md +++ b/systems/proxmox-cluster.md @@ -50,17 +50,24 @@ pvesh get /cluster/resources --type vm # Alle VMs/CTs - Benötigte modprobe.d Config: - `blacklist amdgpu` + `blacklist drm` + `blacklist drm_kms_helper` - `options vfio-pci ids=1002:13c0` + `softdep amdgpu pre: vfio-pci` -- Worker-05 (VM 102): GPU-Passthrough funktionierte historisch auf ms-a2-2 (identische Hardware). 2026-09-29 stand VM auf proxmox6 (OHNE GPU) wegen Anti-Collocation; seit 2026-09-30 hat HA die VM nach ms-a2-2 zurückplatziert (nach OOM-Freezer-Incident, siehe PAT-010). GPU-Status nach Return prüfen/renderD128 verifizieren. Hinweis: Die frühere node-affinity-Regel `na-vm102` (NICHT ms-a2-2) existiert live nicht mehr — nur noch resource-affinity (anti-colloc vs 128/139). +- Worker-05 (VM 102): GPU-Passthrough seit 2026-09-30 WIEDER AKTIV auf ms-a2-2 — + `hostpci0: 0000:01:00.0,pcie=1,rombar=1` (OHNE x-vga!) → renderD128 verifiziert. + **Kritische Lehre:** `x-vga=1` bricht moderne AMD-Karten (SeaBIOS Shadow-ROM zerstört + VBIOS-Zugriff, amdgpu error -22 "Unable to locate a BIOS ROM"). Für Headless- + Render-Nodes NIEMALS x-vga kombinieren. Frühere node-affinity `na-vm102` existiert + live NICHT (affinity.cfg verifiziert 30.09.) — nur resource-affinity vs 128/139. ## Bekannte Probleme - CT110 kaputte libc — Reparatur ausstehend (still stopped) - osd.5 reweight 0.30 (kleine SSD, 150GB) — entlasten oder austauschen - osd.4 reweight 0.30 (kleine SSD, 227GB auf proxmox3) — gleiche Situation -- **proxmox6 RAM-Oversubscription (STRUKTURELL):** ~28 GB Gast-Allokation - (VM301 8G + CT151 Frigate 8G [+ VM102-Rückkehr möglich 12G]) auf 16 GB - Host. Führte 2026-09-29/30 zu Doppel-OOM-Kill von VM102 (Zombie-VM, - PAT-010). Akut entschärft durch Laya-CT152-Migration nach proxmox3. - TODO: Placement-Ceiling (~70% RAM) + PSI/OOM-Alerts pro Node (CT141). +- **proxmox6 RAM-Oversubscription (AKUT ENTSCHÄRFT 30.09.):** VM301 (Galera db2, + 8G) am 30.09. via `ha-manager relocate vm:301 proxmox7` migriert (na-vm301 = + 5/6/7 verifiziert; Anti-Collocs 300⊥301, 301⊥302 gewahrt). Danach: 8,4/15G RAM, + Swap 6,3G→2,8G, per swapoff/on geleert → 0B. Verbleibt auf p6: nur CT151 + Frigate (8G) — innerhalb Ceiling. TODO bleibt: Placement-Ceiling (~70%) als + Guardrail formalisieren. PSI/OOM-Alerts: LIVE in CT141 (Regelgruppe + `pressure_alerts`, 5 Regeln; node_exporter nachinstalliert auf ms-a2-1/-2). ## HA Rules (PVE 9.2 Rules System) Seit 2026-09-28: HA Groups → Rules migriert. Anti-Collocation + Node-Affinity. @@ -119,7 +126,7 @@ Seit 2026-09-29: RKE2 CP/Worker + Hermes hinzugefügt. | RKE2 Worker-05 | 102 | ms-a2-2 (seit 30.09.; vorher proxmox6, davor ms-a2-2) | | Hermes-Agent-01 | 230 | n5pro | | Galera db1 | 300 | n5pro | -| Galera db2 | 301 | proxmox6 | +| Galera db2 | 301 | **proxmox7** (seit 30.09. relocate; vorher proxmox6) | | Galera db3 | 302 | ms-a2-2 | | MaxScale-01 | 310 | proxmox7 | | MaxScale-02 | 311 | ms-a2-1 |