ceph: SMART-Audit rehabilitiert Kingston NVMe (kein Austausch); mgr-union scraping

This commit is contained in:
Dominik Schön
2026-09-30 18:22:25 +00:00
parent 531d6bfbdd
commit cc2f237ca3
8 changed files with 183 additions and 8 deletions
+4
View File
@@ -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
+35
View File
@@ -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 <SHA>.
## [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)
+44
View File
@@ -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/<ADDR>/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 <vg>/<lv> && lvchange -ay -K <vg>/<lv>`
5. **Lesetest**: `dd if=/dev/<vg>/<lv> 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/<dm-name>; chmod 660` (sonst `bdev open: (13) Permission denied`).
7. `systemctl reset-failed ceph-osd@<id> && systemctl start ceph-osd@<id>`
8. `ceph osd in osd.<id>` + 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.
+23
View File
@@ -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
+28
View File
@@ -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 <svc>
```
**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
+22
View File
@@ -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/<name>/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`
+13 -1
View File
@@ -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.
+14 -7
View File
@@ -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 |