homelab-codex-ws/docs/sessions/2026-06-22.md
oskar 1136a48222 docs(session): 2026-06-22 — decyzja Prometheus-as-truth dla liveness floty
Osobny fleet-Prometheus (pull, up{}) zastępuje warstwę wykrywania
node-agent->rsync->observer. Bez Alertmanagera (brain-watchdog drugie wejście).
Placement VPS. Swap 4G done. Plan kroków OTWARTE.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-22 22:15:16 +02:00

6 KiB

Sesja 2026-06-22 — decyzja: Prometheus jako źródło prawdy dla liveness floty

Cel

Rozstrzygnięcie architektoniczne: czym zastąpić obecną rurę wykrywania liveness floty node-agent → rsync/ssh → observer (warstwa sensoryczno-transportowa będąca przyczyną większości nawracających awarii). Plus precondition infrastrukturalny pod nowy serwis na VPS (swap).


DECYZJA: Prometheus (pull, up{}) zastępuje WYKRYWANIE liveness

Co zastępujemy (warstwa sensoryczno-transportowa)

Prometheus pull + metryka up{} przejmuje rolę dotychczasowej rury:

  • node-agent jako shipper eventów,
  • rsync/ssh transport,
  • pliki eventów,
  • observer prune/checkpoint,
  • egzekwowanie TTL liveness.

To była przyczyna większości nawracających awarii:

  • uid 1004 != 1000 — strict ownership check OpenSSH wywalał shipping,
  • ślepy ssh-mount (LUSTRO, /root/.ssh vs /home/homelab/.ssh),
  • bloat (~242k eventów na VPS),
  • race prunecheckpoint w observerze,
  • NOMINAL-bez-TTL (martwy node pokazywany jako zdrowy).

Pull eliminuje całą warstwę push: brak kluczy, brak ownership, brak event-store do prune'owania, brak ręcznego TTL — up==0 przez czas for: jest stanem prawdy.

Świadoma granica zakresu — co ZOSTAJE

Prometheus zastępuje wykrywanie, NIE cały system. Nietknięte:

  • supervisor — remediacja (container_restart / redeploy),
  • observer / panel agents.okit.pl — do przepięcia na źródło Prometheus (OTWARTE, największy znak zapytania przy cutoverze),
  • ha-diag-agent — logika domenowa HA (diff system_health, encje unavailable, WS heartbeat) — Prometheus tego nie widzi,
  • historia incydentów / lifecycle,
  • out-of-band watchdog.

BEZ Alertmanagera — świadoma decyzja

Jeden kanał Telegram (@okitaialerts_bot). Rolę dostarczania przejmuje brain-watchdog: dochodzi mu drugie wejście — odpytanie Prometheus /api/v1/alerts — obok obecnego pingu mózgu. Reguły alertowe z histerezą (for:) po stronie Prometheusa; watchdog pozostaje cienki (odczyt firing + Telegram). Nie wprowadzamy osobnego Alertmanagera, żeby nie mnożyć kanałów ani komponentu do utrzymania.

Uwaga: ta decyzja zastępuje wcześniejszy szkic z sesji 2026-06-17 (blackbox_exporter + Alertmanager). Wybrano pull up{} + watchdog jako tor alertu.


Osobny fleet-Prometheus pod GitOps — NIE adopcja domowego instance

Stawiamy osobny Prometheus floty, zarządzany przez GitOps. NIE adoptujemy domowego instance na PIHA.

Powód — domowy prom na PIHA to liability nie wart adopcji:

  • LAN-only (scrape 192.168.31.x), mija nody tylko-Tailscale (VPS, chelsty),
  • poza repo (/home/pi/monitoring/prometheus.yml, konfigurowany ręcznie),
  • bez alertingu (alerting: i rule_files: puste),
  • sekrety plaintext w configu (long-lived token HAOS + bearer watchtower — do rotacji).

Adopcja = dziedziczenie liability (migracja, ekstrakcja sekretów) plus blast-radius na działający monitoring bezpieczeństwa domu (crowdsec / fail2ban / haos) za znikomą wygraną. Osobny instance izoluje flotę od domu.

Placement: VPS

  • Host: VPS (ubuntu-4gb-hel1-1, 100.95.58.48).
  • Out-of-band zachowane: watchdog na PIHA pilnuje VPS z innej maszyny — Prometheus na VPS nie jest sędzią własnej śmierci.
  • VPS ma już node_exporter (role: metrics-exporter) = pierwszy target floty gotowy.

ZROBIONE w tej sesji

Swap 4 GB na VPS — precondition pod Prometheusa

  • /swapfile aktywny i trwały (wpis w /etc/fstab).
  • vm.swappiness=10 ustawione na żywo i w /etc/sysctl.conf.
  • Weryfikacja: free -hSwap: 4.0Gi (0B used); /proc/swaps zawiera /swapfile.
  • Powód: VPS ma 3.7 GB RAM, wcześniej swap=0 — przyczyna OOM 2026-06-01. Prometheus jest RAM-głodny; swap to bufor bezpieczeństwa.
  • ⚠️ To host-level one-off — nie czysto GitOps-owalne, wykonane świadomie gotowcem. Zapisane jako celowy host-state w hosts/vps/host.yaml, żeby przy odtwarzaniu VPS nie zniknęło cicho (wzorzec jak uid/grupy po 8-dniowej awarii).

Plan następnych kroków (OTWARTE — NIE realizowane w tej sesji)

Kolejność = priorytet:

  1. Scaffold serwisu fleet-prometheus pod GitOps — worktree task/fleet-prometheus, wzorzec services/vikunja/: docker-compose.yml + env.example + service.yaml + README.md + healthcheck.sh. Rejestracja w hosts/vps/services.yaml + inventory/topology.yaml. Exposure: tailscale-internal. Pusty scrape na start (self + lokalny node_exporter VPS).
  2. Inwentaryzacja nodów floty 100.x do scrape (osobny krok).
  3. Container-layer exporter (cAdvisor lub lekki docker-state) — brakujący klocek; node_exporter nie widzi kontenerów.
  4. Reguły liveness (up==0 for: 5m) w Prometheusie.
  5. brain-watchdog: drugie wejście — odpyt Prometheus firing → Telegram, bez ruszania działającego toru token → chat_id.
  6. Rotacja tokenu HAOS w domowym prom (plaintext).
  7. Przepięcie observer / panel agents.okit.pl na Prometheus jako źródło — największy znak zapytania przy cutoverze.
  8. Parallel-run obok rury eventowej; cutover dopiero gdy Prometheus-truth się udowodni.

Wnioski

  • Klasa awarii (push shipping: klucze, ownership, bloat, race, TTL) znika nie przez kolejny fix, lecz przez zmianę modelu transportu na pull — Prometheus widzi martwy target jako up==0, bez warstwy dostarczania do zepsucia.
  • Granica zakresu trzymana świadomie: Prometheus = wykrywanie, nie remediacja ani logika domenowa HA. Zastępujemy sensor, nie mózg.
  • Osobny instance > adopcja: nie dziedziczy się liability ani blast-radius na monitoring bezpieczeństwa domu dla wygody współdzielenia.
  • BEZ Alertmanagera: cienki watchdog z drugim wejściem zamiast nowego komponentu — jeden kanał Telegram pozostaje jeden.
  • Swap = precondition, nie cel — odblokowuje RAM-ciasny VPS pod nowy serwis; udokumentowany jako celowy host-state, nie ukryta ręczna zmiana.