Session logi zostaja w docs/sessions/ (decyzja z etapu 1). Dodany wylacznie blok frontmattera: type: session-log, visibility: private, status: active, updated = data ostatniego commita pliku. Tresc nietknieta — kazdy plik to +9/-0 linii. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
141 lines
6.1 KiB
Markdown
141 lines
6.1 KiB
Markdown
---
|
|
okf: "0.1"
|
|
type: session-log
|
|
visibility: private
|
|
status: active
|
|
updated: 2026-06-22
|
|
links: []
|
|
---
|
|
|
|
# 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 `prune` ↔ `checkpoint` 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 -h` → `Swap: 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.
|