docs(sesja): 2026-07-06 — recon cutoveru wmergowany + Etap 0 udowodniony end-to-end (AlertTestEtap0)
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
parent
d94bb38e69
commit
3d437976b1
106
docs/sessions/2026-07-06.md
Normal file
106
docs/sessions/2026-07-06.md
Normal file
|
|
@ -0,0 +1,106 @@
|
|||
# Sesja 2026-07-06 — cutover liveności na Prometheus: recon starego toru + Etap 0 udowodniony w boju
|
||||
|
||||
## Cel
|
||||
|
||||
Główny projekt: Prometheus jako źródło prawdy liveności floty. Dwa kroki tej sesji:
|
||||
(1) read-only recon starego toru liveności z dokładnymi punktami przełączenia
|
||||
i planem etapowym; (2) Etap 0 cutoveru — bojowy dowód end-to-end toru
|
||||
Prometheus → brain-watchdog → Telegram, którego brakowało od 2026-06-30.
|
||||
|
||||
---
|
||||
|
||||
## ZROBIONE
|
||||
|
||||
### Recon cutoveru — wmergowany (commit `d94bb38`)
|
||||
|
||||
Wynik: `docs/infra/prometheus-cutover-recon-2026-07-06.md` (517 linii, read-only,
|
||||
zero zmian w kodzie). Kluczowe ustalenia:
|
||||
|
||||
- **Cutover to podmiana klasyfikacji liveności w JEDNYM miejscu** —
|
||||
`_prune_stale_world` w `scripts/observer/observer.py:312-323` + neutralizacja
|
||||
event-driven flipów `:438-446` — a NIE odłączanie rury. Fizycznie nic nie znika.
|
||||
- **`node_health` wozi też metryki** disk/mem/cpu do panelu i `disk_pressure`
|
||||
do supervisora → rsync + eventy ZOSTAJĄ w całości.
|
||||
- **Supervisor-remediacja i executor są CAŁKOWICIE niezależne od liveności węzłów**
|
||||
— supervisor czyta z `nodes.json` wyłącznie `disk_pressure`. Jedyny konsument
|
||||
liveności po stronie supervisora to syntetyczne eventy przejść
|
||||
(`node_offline/stale/online` → alert_only → Telegram).
|
||||
- **Różnica semantyk**: `up{}` mierzy "host żyje (exporter odpowiada)",
|
||||
eventowy `node_health` mierzy "node-agent żyje + cały łańcuch SSH/rsync działa".
|
||||
Cutover ZWĘŻA definicję liveności — padnięty node-agent przy żywym węźle zmienia
|
||||
werdykt. Do świadomej akceptacji w etapie 2; rozważyć `up{job=node-agent}`.
|
||||
- **chelsty-infra ma liveność WYŁĄCZNIE z eventów** (Prometheus go nie scrape'uje
|
||||
po LTE) → cutover MUSI być per-węzeł (`PROM_LIVENESS_NODES`), nigdy globalny.
|
||||
- **Prometheus po cutoverze = niepilnowany SPOF** (`mem_limit 512m`,
|
||||
`oom_score_adj 200` — ubijalny przed control-plane) → fail-open na stary tor
|
||||
obowiązkowy + watchdog na sam Prometheus (mały task przy etapie 3).
|
||||
- Exportery piha/solaria/lustro istnieją **poza GitOps** (brak definicji w repo)
|
||||
— rozjazd, osobny wątek.
|
||||
|
||||
### Etap 0 cutoveru — DONE, dowód bojowy end-to-end
|
||||
|
||||
Tor **Prometheus → brain-watchdog → Telegram udowodniony END-TO-END po raz
|
||||
pierwszy w produkcji**. Test punktowy na VPS (celowo NIE w repo): tymczasowa
|
||||
reguła `AlertTestEtap0` (`up{node="vps"}==1`, `for: 0s`) dodana do
|
||||
`services/fleet-prometheus/rules/` na VPS + reload. Cztery punkty potwierdzenia:
|
||||
|
||||
1. **Firing w Prometheusie**: `/api/v1/alerts` → `AlertTestEtap0` firing, node vps.
|
||||
2. **Watchdog spollował z PIHA**: log `[prometheus] sent alert: AlertTestEtap0:vps`
|
||||
— przy okazji widoczne dwa niezależne tory (ping mózgu OK co 60 s + poll
|
||||
Prometheusa osobno), zgodnie z architekturą A.
|
||||
3. **Alert doleciał na Telegram** (@okitaialerts_bot): „Prometheus alert:
|
||||
AlertTestEtap0, Node: vps, Summary: …".
|
||||
4. **Rollback czysty**: reguła usunięta, reload, firing=0.
|
||||
|
||||
Zamyka pending z 2026-06-30 („czy watchdog realnie polluje" — recon 2026-07-02
|
||||
potwierdził konfigurację, dziś potwierdzone działanie end-to-end). Reguła testowa
|
||||
NIE trafiła do repo — to diagnostyka, nie architektura; katalog `rules/` ma
|
||||
nadal tylko `liveness.yml`.
|
||||
|
||||
### Realny dowód „czemu cutover" — chelsty NOMINAL-zonk
|
||||
|
||||
Panel agents.okit.pl pokazuje **chelsty NOMINAL + Runtime online, mimo że chelsty
|
||||
jest OFFLINE od 34 dni** (`tailscale status`). U wszystkich węzłów: Last Seen
|
||||
„Invalid Date", Connectivity/Incidents `undefined`, a status NOMINAL — observer
|
||||
NIE egzekwuje świeżości `last_seen` (bug TTL wraca, patrz backlog „Observer
|
||||
staleness"). Cutover na Prometheus `up{}` to naprawia: chelsty nie-scrape'owany →
|
||||
down, nie fałszywie NOMINAL.
|
||||
|
||||
Snapshot panelu potwierdził też dwa zaległe drobiazgi (dopisane do backlogu):
|
||||
|
||||
- **Ghosty B wróciły/nieposprzątane** — hash-prefixed kontenery control-plane
|
||||
widoczne na VPS (wpis „zniknęły" z 2026-07-02 zdezaktualizowany).
|
||||
- **elasticsearch + diskover w stanie error na PIHA** — usunięte w module 0
|
||||
(2026-07-02), ale observer wciąż je zna i raportuje.
|
||||
|
||||
---
|
||||
|
||||
## PLAN — następne etapy cutoveru (osobne sesje)
|
||||
|
||||
- **Etap 1 — shadow-read**: observer czyta OBA źródła (eventy I Prometheus
|
||||
`up{}`), pisze nienaruszające pola `prom_*` w `nodes.json`, loguje rozbieżności,
|
||||
NIC nie przełącza (parallel-run, fail-open). Realna zmiana w
|
||||
`observer.py:312-323` → worktree/CC.
|
||||
- **Etap 2 — analiza**: ≥ 7 dni zgodności → klasyfikacja rozbieżności
|
||||
(semantyka vs bug) → decyzja mappingu (rekomendacja: `timestamp(up)` jako
|
||||
prom-last_seen przez istniejące `compute_liveness`).
|
||||
- **Etap 3 — przełączenie per-węzeł** za flagą `PROM_LIVENESS_NODES`:
|
||||
najpierw solaria+lustro (najmniejsza szkoda przy pomyłce), potem vps+piha.
|
||||
**chelsty-infra ZOSTAJE na eventach.** Rollback = wyczyszczenie flagi.
|
||||
|
||||
---
|
||||
|
||||
## Wnioski
|
||||
|
||||
- **Etap 0 zamknął fundamentalną niepewność wiszącą od 2026-06-30**: „czy tor
|
||||
alertowy Prometheus→watchdog→Telegram w ogóle działa" przestało być wnioskowaniem
|
||||
z konfiguracji (recon 2026-07-02), a stało się faktem dowiedzionym w produkcji.
|
||||
Dalsze etapy cutoveru budują na sprawdzonym fundamencie, nie na założeniu.
|
||||
- **verify-before-fix w reconie obalił założenie architektoniczne**: observer NIE
|
||||
jest jednym modułem w `services/control-plane/src/` — to `scripts/observer/observer.py`
|
||||
+ wydzielona maszyna stanów `liveness.py` importowana przez trzy konsumentów.
|
||||
Bez reconu plan cutoveru celowałby w złe miejsce.
|
||||
- **Test punktowy (reguła for:0s + rollback) to tani sposób na dowód bojowy toru
|
||||
alertowego** — bez czekania na realną awarię i bez commitowania diagnostyki do repo.
|
||||
- Hashe sesji: `d94bb38` (recon cutoveru); Etap 0 = czynność operatorska na
|
||||
runtime (bez commitu, zgodnie z planem z reconu).
|
||||
Loading…
Reference in a new issue