From 1df533edbaaf61b4f1854f1b07d2c02929d02434 Mon Sep 17 00:00:00 2001 From: Claude Agent Date: Fri, 31 Jul 2026 10:14:54 +0000 Subject: [PATCH] docs(lxc110): incident DNS/OOM 2026-07-31 + zram pe pve1 + limite TTS LXC 110 (moltbot) a picat dupa un OOM local containerului urmat de reboot: tailscaled a ramas delogat, iar containerul mostenea resolv.conf-ul Tailscale de la host-ul pve1 (doar MagicDNS 100.100.100.100) -> rezolutie DNS zero desi L3 era functional -> echo-core in crash-loop pe telegram.error.TimedOut. Fixuri aplicate: - pct set 110 --nameserver '10.0.20.1 1.1.1.1' (elimina dependenta de Tailscale) - zram-tools pe pve1 (8G zstd, prio 100) - `swap: 4096` din config era fictiv, host-ul nu avea niciun swap; root pe ZFS deci zram, nu swapfile - MemoryHigh/MemoryMax pe pocket-tts + supertonic-tts - toate serviciile user rulau cu limite `infinity`, de unde OOM-uri recurente (Apr 25, May 28 x4) cu victime aleatorii alese dupa oom_score_adj Documentatie: - nou post-mortem in cluster/incidents/, adaugat in indexuri - README lxc110: host corectat pveelite -> pve1 (+ RAM/CPU/storage reale), comenzile pct redirectionate spre nodul corect - README lxc171: tabel cu starea swap pe cele 3 noduri (pveelite are zvol, nu zram - nu necesita acelasi fix) Co-Authored-By: Claude Opus 5 (1M context) --- proxmox/README.md | 4 +- proxmox/cluster/README.md | 2 + .../2026-07-31-lxc110-dns-tailscale-oom.md | 191 ++++++++++++++++++ proxmox/lxc110-moltbot/README.md | 100 +++++++-- proxmox/lxc171-claude-agent/README.md | 12 ++ 5 files changed, 292 insertions(+), 17 deletions(-) create mode 100644 proxmox/cluster/incidents/2026-07-31-lxc110-dns-tailscale-oom.md diff --git a/proxmox/README.md b/proxmox/README.md index 973851d..2d2392a 100644 --- a/proxmox/README.md +++ b/proxmox/README.md @@ -10,7 +10,9 @@ proxmox/ │ ├── README.md # Ghid SSH, HA, corosync tuning, diagnostic tools, mail relay, OOM alert │ ├── cluster-ha-monitor.sh # Script monitorizare HA │ ├── incidents/ # Post-mortems incidente cluster -│ │ └── 2026-04-20-cluster-outage.md # Cascadă OOM pveelite + USB LAN watchdog +│ │ ├── 2026-04-20-cluster-outage.md # Cascadă OOM pveelite + USB LAN watchdog +│ │ ├── 2026-04-30-pvemini-backup-ssd-hang.md # Kingston SSD hang → emergency mode +│ │ └── 2026-07-31-lxc110-dns-tailscale-oom.md # DNS mort (Tailscale logout) + zram pe pve1 │ └── ups/ # Sistem UPS pentru cluster │ ├── README.md │ ├── docs/ diff --git a/proxmox/cluster/README.md b/proxmox/cluster/README.md index 8288ae1..201c4cb 100644 --- a/proxmox/cluster/README.md +++ b/proxmox/cluster/README.md @@ -738,6 +738,8 @@ swapon -a ### Incidents - **2026-04-20 Cluster Outage:** `incidents/2026-04-20-cluster-outage.md` — post-mortem complet + plan prevenție +- **2026-04-30 pvemini backup SSD hang:** `incidents/2026-04-30-pvemini-backup-ssd-hang.md` — Kingston thermal hang → emergency mode +- **2026-07-31 LXC 110 DNS + OOM:** `incidents/2026-07-31-lxc110-dns-tailscale-oom.md` — logout Tailscale → DNS mort; zram instalat pe pve1 ### LXC Containers - **LXC 108 - Oracle Database:** `../lxc108-oracle/README.md` diff --git a/proxmox/cluster/incidents/2026-07-31-lxc110-dns-tailscale-oom.md b/proxmox/cluster/incidents/2026-07-31-lxc110-dns-tailscale-oom.md new file mode 100644 index 0000000..19400ac --- /dev/null +++ b/proxmox/cluster/incidents/2026-07-31-lxc110-dns-tailscale-oom.md @@ -0,0 +1,191 @@ +# Incident 2026-07-31 — LXC 110 (moltbot): DNS mort după logout Tailscale + OOM + +**Severity:** Medium (serviciu `echo-core` indisponibil ~8 min; fără pierdere de date) +**Detected:** 2026-07-31 ~09:28 EEST (user — „nu mai răspunde la SSH, nu mai merge echo") +**Resolved:** 2026-07-31 09:34 EEST (fix DNS) + 09:5x EEST (zram pe pve1) +**Author:** Claude Code (mmarius28@gmail.com) + +--- + +## TL;DR — lanțul cauzal + +1. **06:26 UTC** — LXC 110 se oprește după **65 zile uptime**. În log-urile de shutdown: + `user-1000.slice: A process of this unit has been killed by the OOM killer`. + OOM **local containerului** (plafon 8GB), NU la nivel de host — pve1 nu a avut niciun + OOM în 30 de zile și avea 18GB available. +2. **06:26:59** — la revenire, `tailscaled` generează nodekey nou și rămâne **delogat** + (`machineAuthorized=false`, `authURL=true`). +3. **DNS moare complet.** LXC 110 nu avea `nameserver` în `pct config`, deci moștenea + `/etc/resolv.conf` de la host-ul **pve1** — iar acolo fișierul e scris de Tailscale și + conținea **doar MagicDNS** (`100.100.100.100` + `fd7a:115c:a1e0::53`). Cu Tailscale + delogat, resolverul devine inaccesibil. +4. **`echo-core.service` intră în crash-loop** cu `telegram.error.TimedOut` (restart + counter ajunsese la **11**). + +**Capcana de diagnostic:** rețeaua L3 era perfect funcțională — `ping 8.8.8.8` OK, +gateway OK, rută OK. Doar **rezoluția numelor** pica. Ușor de interpretat greșit ca +„bot stricat" sau „internet căzut". + +SSH-ul „care nu răspundea" era doar containerul în curs de repornire — la verificare +funcționa deja normal. + +--- + +## Diagnostic — comenzi cheie + +```bash +# NU te lua după ping — verifică întâi rezoluția +getent hosts api.telegram.org # gol => DNS mort +cat /etc/resolv.conf # doar 100.100.100.100 => depinde de Tailscale +ping -c2 8.8.8.8 # OK => L3 e sănătos, problema e DNS +tailscale status # "Logged out." + +# serviciile echo rulează ca user systemd (user moltbot) +su - moltbot -c 'XDG_RUNTIME_DIR=/run/user/1000 systemctl --user status echo-core' +``` + +## Fix 1 — DNS explicit (aplicat) + +```bash +# pe pve1 +pct set 110 --nameserver '10.0.20.1 1.1.1.1' # persistent, aplicat la următorul start + +# live, fără restart de container (backup: /etc/resolv.conf.bak-2026-07-31) +printf '# --- BEGIN PVE ---\nnameserver 10.0.20.1\nnameserver 1.1.1.1\n# --- END PVE ---\n' \ + > /etc/resolv.conf + +su - moltbot -c 'XDG_RUNTIME_DIR=/run/user/1000 systemctl --user restart echo-core' +``` + +Rezultat: Telegram `getUpdates` → 200 OK, Discord online, 0 restarturi ulterioare. + +> **Expunere similară:** orice alt LXC de pe pve1 **fără `nameserver` explicit** moștenește +> același resolv.conf Tailscale și va pica identic la un logout Tailscale. + +## Fix 2 — zram swap pe pve1 (aplicat) + +`pct config 110` avea `swap: 4096`, dar în container `free -h` arăta **`Swap: 0B`**. +Cauza: limita cgroup exista corect pe host… + +``` +/sys/fs/cgroup/lxc/110/memory.max = 8589934592 (8 GB) +/sys/fs/cgroup/lxc/110/memory.swap.max = 4294967296 (4 GB) <- plafon OK +/sys/fs/cgroup/lxc/110/memory.swap.current = 0 <- nimic nu-l umple +``` + +…dar **pve1 nu avea niciun swap** (`swapon --show` gol, nimic în `/etc/fstab`). Limita +cgroup e doar un *plafon* peste swap-ul host-ului; fără backing store fizic, kernelul nu +are unde scrie paginile. Root-ul pve1 e pe ZFS (`rpool/ROOT/pve-1`), deci swapfile e +exclus (risc de deadlock) — aceeași situație rezolvată pe pvemini în 2026-06-24. + +```bash +# pe pve1 (host) — identic cu pvemini +apt install -y zram-tools +cat > /etc/default/zramswap <<'EOF' +# zram swap config - host buffer pentru spike-uri OOM (ex: LXC 110 moltbot) +ALGO=zstd +SIZE=8192 +PRIORITY=100 +EOF +systemctl restart zramswap.service # enabled persistent la boot +swapon --show # /dev/zram0 8G prio 100 +``` + +Verificare în container — cei 4GB au acum backing real: + +``` +free -h → Swap: 4.0Gi +``` + +Vârfurile tranzitorii fac swap-out în loc de OOM-kill instant. + +--- + +## Rămas de făcut (necesită acțiune user) + +| Item | Detalii | +|------|---------| +| **Re-auth Tailscale în LXC 110** | Necesită login interactiv din browser (`tailscale up` regenerează URL-ul). Până atunci IP-ul 100.120.119.70 nu răspunde; accesul pe 10.0.20.173 e normal. | +| **Bridge WhatsApp deconectat** | `{"connected":false,"qr":null}` pe `127.0.0.1:8098`. Discord + Telegram merg. Probabil necesită re-pairing prin QR. | +| **Monitorizare** | De urmărit dacă `MemoryHigh` pe TTS chiar oprește recurența — următorul episod ar trebui să se manifeste ca throttling, nu ca kill. | + +## OOM-ul NU e izolat — istoric recurent + +Verificarea jurnalului complet (nu doar boot-ul curent) arată că OOM-ul din 31 iulie e +**al cincilea episod**, nu un accident: + +``` +Apr 25 08:34:53 echo-core.service: Failed with result 'oom-kill' +May 28 14:09:36 echo-core.service: Failed with result 'oom-kill' <- 1.4G memory peak +May 28 14:15:44 echo-core.service: Failed with result 'oom-kill' +May 28 14:18:13 echo-core.service: Failed with result 'oom-kill' +May 28 14:18:13 supertonic-tts.service: Failed with result 'oom-kill' +Jul 31 06:26:22 user-1000.slice: killed by the OOM killer -> reboot +``` + +Pe 28 mai: **4 kill-uri în 9 minute**, `echo-core` luând cu el și `supertonic-tts`. +Log-ul de atunci confirmă lipsa swap-ului: `1.4G memory peak, 0B memory swap peak` — +fără backing store, kernelul trece direct la kill. + +### Cauza structurală: servicii fără limite + +Cele 7 servicii user systemd (`echo-core`, `echo-taskboard`, `echo-whatsapp-bridge`, +`pocket-tts`, `supertonic-tts`, `romfast-website`, `dbus`) rulează **toate fără plafon**: + +``` +MemoryMax=infinity +MemoryHigh=infinity +``` + +Deci orice serviciu poate consuma singur toți cei 8 GB ai containerului, iar OOM killer-ul +alege victime după `oom_score_adj` — de unde procesele mici ucise aiurea (`dbus-daemon`, +`sd-pam`) care fac diagnosticul derutant. Stiva TTS e cea mai grea: +`pocket-tts` ~945 MB + `supertonic` ~500 MB, în repaus. + +### Fix 3 — MemoryHigh pe stiva TTS (aplicat) + +`MemoryHigh` face **throttling + reclaim** în loc de kill, deci serviciul degradează elegant +sub presiune. `MemoryMax` e plasa de siguranță: izolează un eventual kill **în interiorul +serviciului**, în loc să lase OOM killer-ul să aleagă victime aleatorii în tot containerul. + +Drop-in-uri în `~/.config/systemd/user/.service.d/limits.conf` (user `moltbot`): + +| Serviciu | RSS repaus | MemoryHigh | MemoryMax | +|----------|-----------|------------|-----------| +| `pocket-tts` | ~945 MB | 1536M | 2G | +| `supertonic-tts` | ~500 MB | 1024M | 1536M | + +```bash +su - moltbot +mkdir -p ~/.config/systemd/user/pocket-tts.service.d +cat > ~/.config/systemd/user/pocket-tts.service.d/limits.conf <<'EOF' +[Service] +MemoryHigh=1536M +MemoryMax=2G +EOF +export XDG_RUNTIME_DIR=/run/user/1000 +systemctl --user daemon-reload +systemctl --user restart pocket-tts supertonic-tts +systemctl --user show pocket-tts -p MemoryHigh,MemoryMax,MemoryCurrent # verificare +``` + +Verificat post-aplicare: ambele `active/running`, porturile 7788 + 7789 deschise, +`echo-core` neîntrerupt. Consum după restart: pocket-tts 773M, supertonic 463M. + +> Restul serviciilor (`echo-core`, `echo-taskboard`, `echo-whatsapp-bridge`, +> `romfast-website`) au rămas **fără limite** — TTS-ul e consumatorul dominant. De +> reevaluat dacă apar OOM-uri cu altă victimă. + +## Prevenție + +- **zram pe pve1** amortizează spike-urile (aplicat) — dar singur e paliativ: fără limite pe + servicii, swap-ul doar întârzie kill-ul. Fixul de fond e `MemoryHigh` pe TTS (aplicat). +- **DNS explicit pe LXC 110** elimină dependența de Tailscale (aplicat). +- De evaluat același `--nameserver` pentru celelalte LXC-uri de pe pve1. +- Alertare pe `NRestarts` la serviciile user systemd ar fi prins crash-loop-ul mai devreme + decât raportarea manuală. + +--- + +**Legături:** `../../lxc110-moltbot/README.md` · `../../lxc171-claude-agent/README.md` +(secțiunea „Memorie & OOM" — incidentul zram pvemini 2026-06-24) diff --git a/proxmox/lxc110-moltbot/README.md b/proxmox/lxc110-moltbot/README.md index dee98b0..36bdef1 100644 --- a/proxmox/lxc110-moltbot/README.md +++ b/proxmox/lxc110-moltbot/README.md @@ -3,7 +3,7 @@ **Director:** `proxmox/lxc110-moltbot/` **VMID:** 110 **IP:** 10.0.20.173 (intern) | 100.120.119.70 (Tailscale) -**Host Proxmox:** pveelite (10.0.20.202) +**Host Proxmox:** pve1 (10.0.20.200) **Rol:** Bot AI pentru Telegram și WhatsApp cu Claude Opus 4.5 --- @@ -16,12 +16,13 @@ | Hostname | moltbot | | IP intern | 10.0.20.173 | | IP Tailscale | 100.120.119.70 | -| Host Proxmox | pveelite (10.0.20.202) | +| Host Proxmox | pve1 (10.0.20.200) | | User serviciu | `moltbot` | | Parola user | `Moltbot2026!` | -| Storage | local-zfs (8GB) | -| RAM | 4GB | -| CPU | 2 cores | +| Storage | local-zfs (50GB) | +| RAM | 8GB (+ 4GB swap) | +| CPU | 6 cores | +| DNS | `10.0.20.1 1.1.1.1` (explicit, vezi mai jos) | | OS | Ubuntu 24.04 LTS | ## Componente Instalate @@ -196,22 +197,85 @@ journalctl --user -u clawdbot-gateway -f ## Administrare via Proxmox -### De pe pvemini (sau alt nod cluster) +### De pe pve1 (sau alt nod cluster) ```bash # Status container -ssh root@10.0.20.202 "pct status 110" +ssh root@10.0.20.200 "pct status 110" # Exec comandă -ssh root@10.0.20.202 "pct exec 110 -- " +ssh root@10.0.20.200 "pct exec 110 -- " # Stop/Start -ssh root@10.0.20.202 "pct stop 110" -ssh root@10.0.20.202 "pct start 110" +ssh root@10.0.20.200 "pct stop 110" +ssh root@10.0.20.200 "pct start 110" # Console -ssh root@10.0.20.202 "pct enter 110" +ssh root@10.0.20.200 "pct enter 110" ``` +## DNS & Swap (incident 2026-07-31) + +### DNS — nu depinde de Tailscale + +Containerul **nu** avea `nameserver` în `pct config`, deci moștenea `/etc/resolv.conf` de +la host-ul pve1 — unde fișierul e scris de Tailscale și conținea doar MagicDNS +(`100.100.100.100`). Când `tailscaled` din container s-a delogat, DNS-ul a murit complet +(deși L3 era OK: `ping 8.8.8.8` funcționa) → `echo-core` în crash-loop pe +`telegram.error.TimedOut`. + +Fix aplicat — nameserver explicit: + +```bash +ssh root@10.0.20.200 "pct set 110 --nameserver '10.0.20.1 1.1.1.1'" +``` + +> **Regula de diagnostic:** la „nu mai ajunge la internet", verifică întâi +> `getent hosts api.telegram.org` și `cat /etc/resolv.conf`, **nu** ping-ul. +> Ping-ul poate merge perfect cu DNS-ul complet mort. + +### Swap — necesită zram pe host + +`swap: 4096` din `pct config` e doar o limită cgroup (`memory.swap.max`), nu un backing +store. Cât timp pve1 nu avea swap deloc, în container `free -h` arăta `Swap: 0B`. +Rezolvat prin zram pe pve1 (root-ul e pe ZFS → swapfile exclus): + +```bash +# pe pve1 (host) +apt install -y zram-tools +cat > /etc/default/zramswap <<'EOF' +ALGO=zstd +SIZE=8192 +PRIORITY=100 +EOF +systemctl restart zramswap.service +swapon --show # /dev/zram0 8G prio 100 +``` + +Verificare în container: `free -h` → `Swap: 4.0Gi`. + +### Limite de memorie pe TTS + +Serviciile user systemd rulau toate cu `MemoryMax=infinity` / `MemoryHigh=infinity`, deci +oricare putea consuma singur cei 8 GB → OOM-uri recurente (Apr 25, May 28 ×4, Jul 31), cu +victime aparent aleatorii (`dbus-daemon`, `sd-pam`) alese după `oom_score_adj`. + +Aplicat pe stiva TTS — `MemoryHigh` face throttle + reclaim în loc de kill: + +| Serviciu | RSS repaus | MemoryHigh | MemoryMax | +|----------|-----------|------------|-----------| +| `pocket-tts` | ~945 MB | 1536M | 2G | +| `supertonic-tts` | ~500 MB | 1024M | 1536M | + +Drop-in-uri: `~/.config/systemd/user/.service.d/limits.conf` + +```bash +su - moltbot +export XDG_RUNTIME_DIR=/run/user/1000 +systemctl --user show pocket-tts -p MemoryHigh,MemoryMax,MemoryCurrent +``` + +**Post-mortem complet:** `../cluster/incidents/2026-07-31-lxc110-dns-tailscale-oom.md` + ## Troubleshooting ### OpenClaw gateway se restartează continuu (OOM kill) @@ -223,10 +287,14 @@ journalctl --user -u openclaw-gateway | grep -i oom free -h systemctl --user status openclaw-gateway -# Soluție: Crește RAM-ul containerului pe Proxmox -# ssh root@pveelite +# Verifică dacă OOM-ul e local containerului sau al host-ului +# ssh root@10.0.20.200 "cat /sys/fs/cgroup/lxc/110/memory.events" # oom_kill > 0 => local +# ssh root@10.0.20.200 "free -h; swapon --show" # zram0 8G activ? + +# Soluție: Crește RAM-ul containerului pe Proxmox (actual: 8192) +# ssh root@10.0.20.200 # pct stop 110 -# pct set 110 --memory 4096 # 4GB (minim recomandat pentru OpenClaw) +# pct set 110 --memory 12288 # pct start 110 # Curăță sesiunile vechi pentru a reduce consumul @@ -303,7 +371,7 @@ scp -r moltbot@10.0.20.173:~/.clawdbot ./backup-moltbot-$(date +%Y%m%d)/ ### Backup complet LXC (via Proxmox) ```bash -ssh root@10.0.20.202 "vzdump 110 --storage local --compress zstd" +ssh root@10.0.20.200 "vzdump 110 --storage local --compress zstd" ``` ## Provider AI - Anthropic @@ -347,5 +415,5 @@ clawdbot onboard --- **Data setup:** 2026-01-29 -**Ultima actualizare:** 2026-01-29 +**Ultima actualizare:** 2026-07-31 (host pve1, DNS explicit, zram — incident DNS/OOM) **Autor:** Claude Code diff --git a/proxmox/lxc171-claude-agent/README.md b/proxmox/lxc171-claude-agent/README.md index a9c3e6e..181b9fb 100644 --- a/proxmox/lxc171-claude-agent/README.md +++ b/proxmox/lxc171-claude-agent/README.md @@ -214,6 +214,18 @@ zramctl; swapon --show # verificare: /dev/zram0 8G zstd Acum cei 8GB `swap` din configul LXC 171 au backing real → vârfurile tranzitorii fac swap-out în loc de OOM-kill instant. +> **Același fix aplicat pe pve1 în 2026-07-31** (aceeași cauză: LXC 110 moltbot cu +> `swap: 4096` fictiv → OOM-kill în cgroup + reboot). Config identic, `SIZE=8192`. +> Vezi `../cluster/incidents/2026-07-31-lxc110-dns-tailscale-oom.md`. + +**Stare swap pe cluster (2026-07-31):** + +| Nod | Swap | Tip | +|-----|------|-----| +| pvemini | 8G | zram0 (zstd, prio 100) | +| pve1 | 8G | zram0 (zstd, prio 100) | +| pveelite | 8G | zvol `/dev/zd64` (prio -2) — swap real, nu necesită zram | + ### Fix 2 — reaping orfane (`scripts/reap-orphans.sh`, cron în 171) Script conservator care rulează ca root **în interiorul containerului**, la fiecare 6 ore: