docs(infra): monitoring coverage recon — co biega vs co monitorowane + plan domknięcia
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
parent
d5139c99ca
commit
31e30b04d1
479
docs/infra/monitoring-coverage-2026-07-14.md
Normal file
479
docs/infra/monitoring-coverage-2026-07-14.md
Normal file
|
|
@ -0,0 +1,479 @@
|
|||
# Monitoring coverage — co biega vs co jest monitorowane (recon 2026-07-14)
|
||||
|
||||
**Pytanie:** czy wszystkie serwisy floty są monitorowane?
|
||||
**Odpowiedź krótka:** NIE. Biega **76 kontenerów** na 5 osiągalnych węzłach, alertowanych jest **15** (~20%).
|
||||
**61 kontenerów** działa bez alertowania — w tym krytyczne: vaultwarden (hasła), forgejo (git = źródło
|
||||
prawdy GitOps), immich (zdjęcia), homeassistant5 (dom), obie instancje NPM (ingress), agent-system-telegram-bot
|
||||
(sam kanał alertów).
|
||||
|
||||
---
|
||||
|
||||
## Metadane zbierania danych
|
||||
|
||||
| | |
|
||||
|---|---|
|
||||
| **Data zebrania** | 2026-07-14, 17:16–17:17 UTC |
|
||||
| **Metoda** | `docker ps --format '{{.Names}}\t{{.Image}}\t{{.Status}}\t{{.Ports}}'` |
|
||||
| **PIHA** | ssh `piha` (100.108.208.3, user oskar) — 17:16:37Z |
|
||||
| **VPS** | ssh `vps` (100.95.58.48, user oskar) — 17:16:39Z |
|
||||
| **SOLARIA** | lokalnie (sesja biegła na solarii) — 17:16:41Z |
|
||||
| **LUSTRO** | ssh `pi@100.99.85.73` (uwaga: user **pi**, nie oskar) — 17:17:11Z |
|
||||
| **SATURN** | ssh `oskar@100.121.168.72` — 17:17:21Z |
|
||||
| **CHELSTY-INFRA / CHELSTY-HA** | OFFLINE — `tailscale status`: last seen 42 dni temu. **Do weryfikacji po powrocie online.** |
|
||||
| **Kod** | branch `task/monitoring-coverage-recon` @ parent `d5139c9` (master) |
|
||||
|
||||
Sekcje A–C to **STAN NA DZIEŃ ZBIERANIA** (zmienny — przy odświeżaniu przewalidować w całości).
|
||||
Sekcja E (klasyfikacja) i F (plan) to **DECYZJE** (trwałe — przy odświeżaniu tylko dopisać nowe kontenery).
|
||||
|
||||
---
|
||||
|
||||
## Jak działa monitoring w tym systemie (zweryfikowane w kodzie, stan na d5139c9)
|
||||
|
||||
Warstwy, od detekcji do alertu:
|
||||
|
||||
1. **node-agent** (`services/node-agent/src/node_agent.py`, `check_containers()` ~linia 305):
|
||||
czyta docker socket i emituje eventy dla **WSZYSTKICH kontenerów z restart policy**
|
||||
(`unless-stopped`/`always`/`on-failure`) — NIE filtruje po services.yaml.
|
||||
Emituje: `containers_not_running` (exited/dead), `healthcheck_failed` (running+unhealthy),
|
||||
`service_healthy` (running). Kontenery w stanie `created` pomija. **Uwaga (gap):** kontener
|
||||
w stanie `restarting` (crash-loop) nie pasuje ani do `exited/dead` ani do `running` —
|
||||
**crash-loop nie generuje żadnego eventu** (zaobserwowane na lustro/watchtower, patrz niżej).
|
||||
Nazwa kanoniczna = label `com.docker.compose.service` (fallback: nazwa kontenera).
|
||||
Zdeployowany na: piha, vps, solaria, lustro (na saturnie NIE).
|
||||
2. **stability-agent** (`services/stability-agent/src/stability_agent.py`): również raportuje
|
||||
wszystkie kontenery (bez filtra) — eventy `containers_not_running`, `mqtt_unreachable`,
|
||||
`disk_usage_high` + publikacja do Redis. Biega na piha, vps, solaria (poza services.yaml!).
|
||||
3. **Observer** (`scripts/observer/observer.py`, uruchamiany w control-plane@VPS): syntetyzuje
|
||||
eventy do `/opt/homelab/world/{services,nodes,incidents}.json`. Rejestruje **wszystko**
|
||||
(na dziś 116 wpisów w services.json, w tym wszystkie shadow kontenery). Widoczność ≠ alert.
|
||||
4. **Supervisor** (`services/control-plane/src/supervisor.py`, `reconcile()` linia 288):
|
||||
generuje akcje (`redeploy`/`container_restart` → pending → Telegram → operator) **WYŁĄCZNIE
|
||||
dla serwisów zadeklarowanych w `hosts/<node>/services.yaml`** (`_load_desired_state()`,
|
||||
linie 161–195). Flaga `monitor: false` (linie 182–186) wyklucza serwis z desired-state —
|
||||
serwis jest udokumentowany, ale supervisor go pomija. **To jest jedyny filtr: detekcja jest
|
||||
flotowa, alertowanie tylko dla zadeklarowanych.** Dodatkowo supervisor routuje niezależnie
|
||||
od desired-state: eventy `ha_*` (z ha-diag-agent), `node_offline/stale/online` (liveness
|
||||
węzłów z heartbeatów node-agenta) i `disk_pressure`.
|
||||
5. **fleet-prometheus** (`services/fleet-prometheus/`, VPS): scrape node_exporterów =
|
||||
**liveness HOSTA, nie serwisów**. Scrape'uje: vps, piha, solaria, lustro. Świadomie NIE:
|
||||
saturn (workstation, często off), chelsty (LTE, exporter DOWN — do zbadania osobno).
|
||||
Alert `NodeDown` (rules/liveness.yml) tylko dla `vps|piha` (solaria/lustro bywają planowo
|
||||
wyłączane). Bez Alertmanagera — alerty odbiera brain-watchdog.
|
||||
6. **brain-watchdog** (`services/brain-watchdog/`, PIHA): pilnuje świeżości control-plane
|
||||
(/summary) + polluje `PROMETHEUS_URL/api/v1/alerts` i forwarduje do Telegrama.
|
||||
7. **ha-diag-agent** (piha → HA "ken" localhost:8123; chelsty-infra → chelsty-ha): diagnostyka
|
||||
HA (websocket, integracje, encje) → supervisor routuje na alert/restart **niezależnie od
|
||||
services.yaml** (dziś wisi `container-restart-piha-homeassistant` mimo braku wpisu HA
|
||||
w hosts/piha/services.yaml).
|
||||
|
||||
**Definicja "monitorowany" w tym raporcie** = supervisor wygeneruje akcję/alert gdy serwis
|
||||
padnie = wpis w `hosts/<node>/services.yaml` bez `monitor: false`, z nazwą zgodną z nazwą
|
||||
compose-service kontenera.
|
||||
|
||||
---
|
||||
|
||||
## A. Stan faktyczny — pełne listy kontenerów (STAN NA 2026-07-14)
|
||||
|
||||
### PIHA — 42 kontenery
|
||||
|
||||
| Kontener | Obraz | Status | Porty |
|
||||
|---|---|---|---|
|
||||
| node-agent | node-agent-node-agent | Up 22h (healthy) | — |
|
||||
| paperless | ghcr.io/paperless-ngx/paperless-ngx:2.14 | Up 47h (healthy) | 192.168.31.5:8210→8000 |
|
||||
| vikunja | vikunja/vikunja:latest | Up 4d | 0.0.0.0:3456→3456 |
|
||||
| vikunja-db | postgres:16-alpine | Up 4d (healthy) | 5432 (internal) |
|
||||
| brain-watchdog | brain-watchdog-brain-watchdog | Up 4d (healthy) | — |
|
||||
| paperless-db | postgres:16-alpine | Up 4d (healthy) | 192.168.31.5:5434→5432 |
|
||||
| paperless-broker | redis:7-alpine | Up 4d (healthy) | 192.168.31.5:6380→6379 |
|
||||
| llm-gateway | llm-gateway-llm-gateway | Up 11d (healthy) | 100.108.208.3:8080→8080 |
|
||||
| kb-postgres | pgvector/pgvector:pg16 | Up 2w (healthy) | 0.0.0.0:5433→5432 |
|
||||
| agent-system-webui | agent-system-webui | Up 2w | 0.0.0.0:18180→8080 |
|
||||
| agent-system-runtime-materializer | agent-system-runtime-materializer | Up 2w | — |
|
||||
| agent-system-telegram-bot | agent-system-telegram-bot | Up 2w | — |
|
||||
| ha-diag-agent | ha-diag-agent-ha-diag-agent | Up 2w (healthy) | — |
|
||||
| stability-agent | stability-agent-stability-agent | Up 2w (healthy) | — |
|
||||
| agent-system-redis | redis:7 | Up 2w | 0.0.0.0:6379→6379 |
|
||||
| nginxproxymanager-app-1 | jc21/nginx-proxy-manager:latest | Up 2w | 0.0.0.0:80-81→80-81, 443→443 |
|
||||
| homeassistant5 | ghcr.io/home-assistant/home-assistant:stable | Up 2w | (host network, :8123) |
|
||||
| immich_server | ghcr.io/immich-app/immich-server:release | Up 2w (healthy) | 0.0.0.0:2283→2283, 8081-8082 |
|
||||
| immich_postgres | tensorchord/pgvecto-rs:pg14-v0.2.0 | Up 2w (healthy) | 5432 (internal) |
|
||||
| immich_machine_learning | ghcr.io/immich-app/immich-machine-learning:release | Up 2w (healthy) | — |
|
||||
| immich_redis | redis:6.2-alpine | Up 2w (healthy) | 6379 (internal) |
|
||||
| forgejo_dind | docker:dind | Up 2w | 2375-2376 (internal) |
|
||||
| forgejo | codeberg.org/forgejo/forgejo:7 | Up 12d | 0.0.0.0:3000→3000, 222→22 |
|
||||
| forgejo-db-1 | postgres:14 | Up 2w | 5432 (internal) |
|
||||
| zigbee2mqtt | koenkk/zigbee2mqtt | Up 3d | 0.0.0.0:8087→8080 |
|
||||
| audiobookshelf | ghcr.io/advplyr/audiobookshelf:latest | Up 2w | 0.0.0.0:13378→80 |
|
||||
| grafana | grafana/grafana-enterprise:latest | Up 2w | 0.0.0.0:9003→3000 |
|
||||
| wikijs-db-1 | postgres:15-alpine | Up 2w | 5432 (internal) |
|
||||
| code-server | lscr.io/linuxserver/code-server:latest | Up 2w | 0.0.0.0:8443→8443 |
|
||||
| portainer | portainer/portainer-ce:latest | Up 2w | 0.0.0.0:8008→8000, 9009→9000 |
|
||||
| prom | prom/prometheus:latest | Up 2w | 0.0.0.0:9090→9090 |
|
||||
| homepage | ghcr.io/gethomepage/homepage:latest | Up 2w (healthy) | 0.0.0.0:3033→3000 |
|
||||
| actual-server | actualbudget/actual-server:latest-alpine | Up 2w | 0.0.0.0:5006→5006 |
|
||||
| mqtt-exporter-mqtt-exporter-1 | kpetrem/mqtt-exporter:latest | Up 2w | 0.0.0.0:9000→9000 |
|
||||
| node-exporter | quay.io/prometheus/node-exporter:latest | Up 2w | — |
|
||||
| wikijs-wiki-1 | ghcr.io/requarks/wiki:2 | Up 2w | 0.0.0.0:3300→3000 |
|
||||
| owntracks-recorder | owntracks/recorder:latest | Up 2w | 0.0.0.0:8083→8083 |
|
||||
| vaultwarden | vaultwarden/server:latest | Up 2w (healthy) | 0.0.0.0:3012→80 |
|
||||
| pihole-exporter | ekofr/pihole-exporter:latest | Up 2w | 0.0.0.0:9617→9617 |
|
||||
| fail2ban-prometheus-exporter-exporter-1 | registry.gitlab.com/hctrdev/fail2ban-prometheus-exporter:latest | Up 2w **(unhealthy)** | 0.0.0.0:9191→9191 |
|
||||
| owntracks-prometheus-exporter-prometheus-owntracks-exporter-1 | linusgroh/prometheus-owntracks-exporter | Up 2w | 0.0.0.0:8780→80 |
|
||||
| own-tracks-frontend-owntracks-frontend-1 | owntracks/frontend | Up 2w | 0.0.0.0:8084→80 |
|
||||
|
||||
Zmiany vs audyt 2026-06-30 (`docs/infra/inventory-2026-06-30.md`): **przybyły** paperless,
|
||||
paperless-db, paperless-broker (Deploy 1, 2026-07-10); **zniknęły** diskover i elasticsearch
|
||||
(w audycie 06-30 były w 33 shadow; dziś nie biegają). 06-30: 40 kontenerów → dziś: 42.
|
||||
|
||||
### VPS — 24 kontenery
|
||||
|
||||
| Kontener | Obraz | Status | Porty |
|
||||
|---|---|---|---|
|
||||
| control-plane-executor | control-plane-executor | Up 46m (healthy) | — |
|
||||
| control-plane-observer | control-plane-observer | Up 46m (healthy) | — |
|
||||
| control-plane-supervisor | control-plane-supervisor | Up 46m (healthy) | — |
|
||||
| control-plane-ui | control-plane-operator-ui | Up 46m (healthy) | 0.0.0.0:18180→8080 |
|
||||
| fleet-prometheus | prom/prometheus:v3.5.0 | Up 2w (healthy) | 100.95.58.48:9090→9090 |
|
||||
| node-agent | node-agent-node-agent | Up 2w (healthy) | — |
|
||||
| humanai-mailer | humanai-mailer | Up 2w | — |
|
||||
| humanai-landing | humanai-landing | Up 2w | 80 (internal) |
|
||||
| umami | ghcr.io/umami-software/umami:postgresql-latest | Up 2w (healthy) | 3000 (internal) |
|
||||
| umami-db | postgres:16-alpine | Up 2w (healthy) | 5432 (internal) |
|
||||
| node_exporter | quay.io/prometheus/node-exporter:latest | Up 5w | (host network :9100) |
|
||||
| stability-agent | stability-agent-stability-agent | Up 5w (healthy) | — |
|
||||
| outline-outline-1 | outlinewiki/outline:1.6.1 | Up 5w (healthy) | 0.0.0.0:3000→3000 |
|
||||
| outline-postgres-1 | 4e6e670bb069 (anonimowy image ID!) | Up 5w (healthy) | 5432 (internal) |
|
||||
| outline-redis-1 | redis:7-alpine | Up 5w (healthy) | 6379 (internal) |
|
||||
| ai-cluster-service-ops-worker-1 | ai-cluster-service-ops-worker | Up 5w | — |
|
||||
| ai-cluster-codex-worker-1 | ai-cluster-codex-worker | Up 5w | — |
|
||||
| ai-cluster-openclaw-1 | ai-cluster-openclaw | Up 5w (healthy) | 0.0.0.0:8000→8000 |
|
||||
| ai-cluster-planner-worker-1 | ai-cluster-planner-worker | Up 5w | — |
|
||||
| ai-cluster-redis-1 | redis:7-alpine | Up 5w | 6379 (internal) |
|
||||
| mosquitto | eclipse-mosquitto:2 | Up 5w | 100.95.58.48:1883→1883 |
|
||||
| joplin-server | joplin/server:latest | Up 5w | 127.0.0.1:22300→22300 |
|
||||
| npm | jc21/nginx-proxy-manager:latest | Up 5w | 0.0.0.0:80-81→80-81, 443→443 |
|
||||
| joplin-db | postgres:18 (pre-release tag!) | Up 5w (healthy) | 5432 (internal) |
|
||||
|
||||
**gokapi NIE biega** mimo deklaracji w hosts/vps/services.yaml — supervisor poprawnie to wykrył:
|
||||
w `/opt/homelab/actions/pending/` wisi `redeploy-vps-gokapi.json`. To dowód, że monitoring
|
||||
desired-state DZIAŁA dla zadeklarowanych serwisów.
|
||||
|
||||
### SOLARIA — 5 kontenerów
|
||||
|
||||
| Kontener | Obraz | Status | Porty |
|
||||
|---|---|---|---|
|
||||
| paperless-worker | ghcr.io/paperless-ngx/paperless-ngx:2.14 | Up 5h (healthy) | 8000 (internal) |
|
||||
| planner-agent | planner-agent-planner-agent | Up 5h (healthy) | — |
|
||||
| node-agent | node-agent-node-agent | Up 5h (healthy) | — |
|
||||
| stability-agent | stability-agent-stability-agent | Up 5h (healthy) | — |
|
||||
| node_exporter | quay.io/prometheus/node-exporter:latest | Up 5h | (host network :9100) |
|
||||
|
||||
### LUSTRO — 4 kontenery
|
||||
|
||||
| Kontener | Obraz | Status | Porty |
|
||||
|---|---|---|---|
|
||||
| node-agent | node-agent-node-agent | Up 20h (healthy) | — |
|
||||
| node-exporter | quay.io/prometheus/node-exporter:latest | Up 20h | (host network :9100) |
|
||||
| piper-tts | piper-tts-rpi5 | Up 20h | 0.0.0.0:5000→5000, 10200→10200 |
|
||||
| pi-watchtower-1 | containrrr/watchtower | **Restarting (1) — crash-loop!** | — |
|
||||
|
||||
**pi-watchtower-1 jest w crash-loopie** i przez lukę w node-agencie (stan `restarting` nie
|
||||
generuje eventu, patrz sekcja o mechanizmie) — **nikt tego nie widzi**; world-state pokazuje
|
||||
`lustro/watchtower healthy` (stary event `service_healthy`).
|
||||
|
||||
### SATURN — 1 kontener
|
||||
|
||||
| Kontener | Obraz | Status | Porty |
|
||||
|---|---|---|---|
|
||||
| agent-system-webui | agent-system-webui | Up 9h | 0.0.0.0:8080→8080 |
|
||||
|
||||
Stack control-plane z audytu 06-30 (executor/observer/supervisor/ui) już NIE biega na saturnie
|
||||
— posprzątane. Saturn nie ma node-agenta, nie ma services.yaml, nie jest scrape'owany przez
|
||||
fleet-prometheus → **węzeł całkowicie poza monitoringiem** (świadomie: workstation, często off).
|
||||
|
||||
### CHELSTY-INFRA / CHELSTY-HA — OFFLINE (42 dni)
|
||||
|
||||
Niedostępne przez Tailscale (last seen ~2026-06-02). Deklaracje: chelsty-infra = ha-diag-agent,
|
||||
node-agent, mosquitto, zigbee2mqtt, frigate; chelsty-ha = homeassistant (`monitor: false`).
|
||||
`world/services.json` nadal pokazuje serwisy chelsty-infra jako "healthy" — to STĘCHŁY stan
|
||||
(status serwisów nie wygasa; liveness wygasa tylko na poziomie węzła). **Do weryfikacji po
|
||||
powrocie online**, w tym: czy alerty `node_offline` dla chelsty odpaliły 42 dni temu.
|
||||
|
||||
---
|
||||
|
||||
## B. Stan deklarowany — hosts/<node>/services.yaml (STAN NA 2026-07-14)
|
||||
|
||||
| Węzeł | Zadeklarowane serwisy | monitor: false? |
|
||||
|---|---|---|
|
||||
| piha | ha-diag-agent, node-agent, brain-watchdog, vikunja, llm-gateway, kb-postgres | — |
|
||||
| vps | node-agent, control-plane, node_exporter, fleet-prometheus, gokapi | — |
|
||||
| solaria | node-agent | — |
|
||||
| lustro | node-agent | — |
|
||||
| saturn | **BRAK PLIKU services.yaml** | — |
|
||||
| chelsty-infra | ha-diag-agent, node-agent, mosquitto, zigbee2mqtt, frigate | — |
|
||||
| chelsty-ha | homeassistant | **TAK** (node-agent tam nie zdeployowany; HA kryty pośrednio przez MQTT) |
|
||||
|
||||
Razem: **18 deklaracji alertowalnych** (w tym 5 na offline'owym chelsty-infra) + 1 z monitor:false.
|
||||
|
||||
Uwaga: `stability-agent` ma katalogi w `hosts/{piha,solaria,vps}/runtime/`, ale NIE ma wpisów
|
||||
w żadnym services.yaml — sam strażnik nie jest pilnowany.
|
||||
|
||||
---
|
||||
|
||||
## C. Luka — biega, ale poza alertowaniem (STAN NA 2026-07-14)
|
||||
|
||||
Pokrycie per węzeł (kontenery alertowane / biegające):
|
||||
|
||||
| Węzeł | Biega | Alertowane | Luka |
|
||||
|---|---|---|---|
|
||||
| PIHA | 42 | 6 (node-agent, ha-diag-agent, brain-watchdog, vikunja, llm-gateway, kb-postgres) | **36** |
|
||||
| VPS | 24 | 7 (node-agent, control-plane ×4¹, node_exporter, fleet-prometheus) | **17** |
|
||||
| SOLARIA | 5 | 1 (node-agent) | **4** |
|
||||
| LUSTRO | 4 | 1 (node-agent) | **3** |
|
||||
| SATURN | 1 | 0 | **1** |
|
||||
| **RAZEM** | **76** | **15** | **61 (~80%)** |
|
||||
|
||||
¹ control-plane to 1 deklaracja pokrywająca 4 kontenery — node-agent na VPS probe'uje endpoint
|
||||
HTTP :18180/summary i emituje `service_healthy`/`service_unhealthy` dla logicznego serwisu
|
||||
"control-plane" (`_check_control_plane_health()`).
|
||||
|
||||
Częściowe pokrycie (nie liczone jako "alertowane" powyżej):
|
||||
- **homeassistant5@piha** — ha-diag-agent pilnuje websocketu HA i supervisor generuje
|
||||
`container_restart`/`alert_only` niezależnie od services.yaml. Padnięcie HA zostanie
|
||||
zauważone. Brak jednak wpisu desired-state (drift "kontener zniknął" nie będzie wykryty).
|
||||
- **node-exporter@piha** — jego padnięcie = `up==0` w fleet-prometheus = alert NodeDown
|
||||
(piha) przez brain-watchdog → Telegram. Pośrednio alertowany.
|
||||
- **node_exporter@solaria, node-exporter@lustro** — scrape'owane, ale świadomie wyłączone
|
||||
z reguły NodeDown (węzły planowo wyłączane) → brak alertu.
|
||||
- **gokapi@vps** — zadeklarowany, NIE biega; drift poprawnie wykryty (pending
|
||||
`redeploy-vps-gokapi.json`). Luka deploymentu, nie monitoringu.
|
||||
|
||||
---
|
||||
|
||||
## D. Nowe serwisy KB — weryfikacja wpisu z backlogu (f135365)
|
||||
|
||||
Backlog ("Nowe serwisy KB nie sa w monitoringu", 2026-07-12) **potwierdzony w połowie** —
|
||||
paperless i paperless-worker faktycznie poza monitoringiem; gokapi/llm-gateway/kb-postgres są OK:
|
||||
|
||||
| Serwis | services/<name>/ w repo? | hosts/*/services.yaml? | Biega? | Alertowany? |
|
||||
|---|---|---|---|---|
|
||||
| paperless (+db, +broker) | ✓ (+ hosts/piha/runtime/paperless) | ✗ | ✓ piha (healthy) | **✗ LUKA** |
|
||||
| paperless-worker | ✓ (owner_node: solaria) | ✗ | ✓ solaria (healthy) | **✗ LUKA** |
|
||||
| nextcloud | ✓ (owner_node: piha, commit 7e5577c) | ✗ | ✗ nigdzie (nie zdeployowany) | ✗ (nie dotyczy — dodać wpis RAZEM z deployem) |
|
||||
| gokapi | ✓ (owner_node: vps) | ✓ hosts/vps | **✗ nie biega** | ✓ — drift wykryty, wisi `redeploy-vps-gokapi` |
|
||||
| llm-gateway | ✓ (owner_node: piha) | ✓ hosts/piha | ✓ piha (healthy) | ✓ |
|
||||
| kb-postgres | ✓ (owner_node: piha) | ✓ hosts/piha | ✓ piha (healthy) | ✓ |
|
||||
|
||||
---
|
||||
|
||||
## E. Klasyfikacja niemonitorowanych kontenerów (DECYZJA — trwała)
|
||||
|
||||
Kategorie:
|
||||
- **A (pełny GitOps):** krytyczny — docelowo compose w `services/`, service.yaml, deploy przez
|
||||
deploy.sh. Każde A dostaje NAJPIERW wpis monitoringowy (krok B) — tanio, od razu.
|
||||
- **B (tylko monitoring):** deployment zostaje jak jest; dodać do `hosts/<node>/services.yaml`
|
||||
→ supervisor alarmuje gdy padnie.
|
||||
- **C (świadomie poza):** padnięcie nie boli / narzędzie jednorazowe. Uzasadnienie obowiązkowe.
|
||||
|
||||
Kontenery pomocnicze stacka (db/redis/broker) dziedziczą kategorię stacka — w services.yaml
|
||||
deklaruje się serwis główny (padnięcie db zwykle wywala healthcheck głównego kontenera).
|
||||
|
||||
### PIHA (36 luk)
|
||||
|
||||
| Kontener | Co robi | Kategoria | Uzasadnienie |
|
||||
|---|---|---|---|
|
||||
| vaultwarden | menedżer haseł | **A** (najpierw B) | Hasła całej rodziny — padnięcie/utrata danych boli maksymalnie; musi być w GitOps z backupem i alertem |
|
||||
| forgejo, forgejo-db-1, forgejo_dind | git hosting + CI | **A** (najpierw B) | Źródło prawdy GitOps + OIDC dla vikunji; bez forgejo nie ma deployów; już zidentyfikowane w audycie 06-30 (owner_node błędnie=saturn) |
|
||||
| homeassistant5 | Home Assistant "ken" (dom) | **A** (najpierw B) | Automatyka domu; częściowo kryty przez ha-diag-agent (websocket), ale bez wpisu desired-state; wpis `homeassistant` w services.yaml domknie lukę |
|
||||
| immich_server, immich_postgres, immich_machine_learning, immich_redis | zdjęcia rodzinne | **A** (najpierw B) | Dane niereprodukowalne (zdjęcia); padnięcie = brak backupu telefonów w tle, zauważalne późno |
|
||||
| nginxproxymanager-app-1 | ingress LAN (*.kapala.org: HA, immich, paperless, cloud…) | **A** (najpierw B) | Pojedynczy punkt wejścia do wszystkich usług domowych; padnięcie = "wszystko nie działa" |
|
||||
| paperless, paperless-db, paperless-broker | KB: dokumenty (OCR pipeline) | **B** | Już w GitOps (services/paperless + runtime override) — brakuje TYLKO wpisu w services.yaml; przypadek z backlogu f135365 |
|
||||
| stability-agent | watchdog węzła | **B** | Repo-managed (runtime override jest); strażnik musi być pilnowany; dotyczy też vps i solarii |
|
||||
| zigbee2mqtt | bridge Zigbee→MQTT (ken) | **B** | services/zigbee2mqtt istnieje (owner=piha); sensory domowe przestają raportować gdy padnie |
|
||||
| agent-system-telegram-bot | kanał alertów Telegram | **B** | Jak padnie, ŻADEN alert nie dojdzie — a nikt się nie dowie; pilnować w pierwszej kolejności |
|
||||
| agent-system-webui | operator UI (approve akcji) | **B** | Bez niego nie da się zatwierdzać akcji z przeglądarki; część pętli human-in-the-loop |
|
||||
| agent-system-redis | redis dla agent-system | **B** | Zależność telegram-bota i webui; tani wpis |
|
||||
| agent-system-runtime-materializer | materializacja runtime agentów | **B** | Część stacka agent-system; padnięcie cichaczem psuje odświeżanie stanu |
|
||||
| wikijs-wiki-1, wikijs-db-1 | wiki | **B** | Notatki/dokumentacja domowa — padnięcie boli umiarkowanie, wpis jest tani |
|
||||
| actual-server | budżet domowy | **B** | Dane finansowe; używany regularnie, padnięcie zauważalne przy wpisywaniu wydatków |
|
||||
| prom | domowy Prometheus (LAN) | **B** | Źródło metryk domowych (HA, piha OS); padnięcie = dziura w historii; UWAGA: ma plaintext token HAOS (anti-pattern, patrz services/fleet-prometheus/prometheus.yml komentarz) |
|
||||
| owntracks-recorder | lokalizacja rodziny (backend) | **C** | Hobby/eksperyment; padnięcie = luka w śladzie lokalizacji, nie boli operacyjnie |
|
||||
| own-tracks-frontend-… | frontend owntracks | **C** | Czysta wizualizacja |
|
||||
| owntracks-prometheus-exporter-… | exporter owntracks | **C** | Pomocniczy; objaw padnięcia = brak metryk, widoczny w grafanie |
|
||||
| mqtt-exporter-mqtt-exporter-1 | exporter MQTT→prom | **C** | Jak wyżej |
|
||||
| pihole-exporter | exporter pihole | **C** | Jak wyżej |
|
||||
| fail2ban-prometheus-exporter-… | exporter fail2ban | **C** | Jak wyżej; DZIŚ unhealthy — naprawić lub usunąć (follow-up) |
|
||||
| node-exporter | metryki hosta dla fleet-prometheus | **C** | Pośrednio alertowany: padnięcie = up==0 = NodeDown(piha) przez brain-watchdog |
|
||||
| grafana | dashboardy | **C** | Wizualizacja; padnięcie zauważalne przy wejściu, zero utraty danych (provisioning/db na dysku) |
|
||||
| homepage | strona startowa | **C** | Kosmetyka |
|
||||
| audiobookshelf | audiobooki | **C** | Media; restart ręczny wystarczy |
|
||||
| code-server | IDE w przeglądarce | **C** | Narzędzie dev, używane ad-hoc |
|
||||
| portainer | GUI dockera | **C** | Narzędzie administracyjne ad-hoc; wręcz kandydat do usunięcia (GitOps ma być źródłem prawdy) |
|
||||
|
||||
### VPS (17 luk)
|
||||
|
||||
| Kontener | Co robi | Kategoria | Uzasadnienie |
|
||||
|---|---|---|---|
|
||||
| npm | publiczny ingress okit.pl | **A** (najpierw B) | Cała publiczna powierzchnia (share.okit.pl, vikunja.okit.pl…); manifesty A już istnieją na NIEZMERGOWANEJ gałęzi `feat/vps-service-migration` (commit 862c04a, cutover niewykonany) |
|
||||
| mosquitto | broker MQTT ai-cluster | **B** | services/mosquitto istnieje ale owner_node=piha (błąd — biega na VPS od tygodni, audyt 06-30 poz. 3); szyna komunikacji ai-cluster |
|
||||
| stability-agent | watchdog węzła | **B** | Jak na piha |
|
||||
| outline-outline-1, outline-postgres-1, outline-redis-1 | wiki zespołowa | **B** | Notatki; manifesty na gałęzi feat/vps-service-migration; przy okazji naprawić anonimowy image ID postgresa (audyt 06-30 poz. 19) |
|
||||
| joplin-server, joplin-db | sync notatek | **B** | Notatki osobiste; przy okazji zejść z postgres:18 pre-release (audyt 06-30 poz. 20) |
|
||||
| ai-cluster-codex-worker-1, ai-cluster-planner-worker-1, ai-cluster-service-ops-worker-1, ai-cluster-openclaw-1, ai-cluster-redis-1 | workery agentowe | **B** | Padnięcie = agenci przestają mielić kolejki (objawia się późno); docelowo migracja compute na SOLARIA (CLAUDE.md), monitoring dodać już teraz |
|
||||
| humanai-landing, humanai-mailer | strona publiczna + mailer | **B** | Publiczna wizytówka — padnięcie boli reputacyjnie i cicho (nikt nie patrzy); brak w repo (audyt 06-30 poz. 21) |
|
||||
| umami, umami-db | analityka www | **C** | Statystyki odwiedzin; padnięcie = luka w danych analitycznych, nie boli operacyjnie |
|
||||
|
||||
### SOLARIA (4 luki)
|
||||
|
||||
| Kontener | Co robi | Kategoria | Uzasadnienie |
|
||||
|---|---|---|---|
|
||||
| paperless-worker | OCR/konsument kolejki KB | **B** | Przypadek wprost z backlogu f135365: "jesli worker padnie (…) dowiesz sie po tym, ze kolejka nie jest przetwarzana"; repo+runtime są, brakuje wpisu |
|
||||
| planner-agent | agent planowania | **B** | services/planner-agent istnieje (owner=solaria ✓); audyt 06-30 poz. 14 |
|
||||
| stability-agent | watchdog węzła | **B** | Jak na piha/vps |
|
||||
| node_exporter | metryki hosta | **C** | Scrape'owany, ale solaria świadomie poza NodeDown (planowe wyłączenia); alerting wróci z anomaly-detection (backlog) |
|
||||
|
||||
### LUSTRO (3 luki)
|
||||
|
||||
| Kontener | Co robi | Kategoria | Uzasadnienie |
|
||||
|---|---|---|---|
|
||||
| piper-tts | TTS dla magic mirror | **C** | Padnięcie = lustro nie mówi; kosmetyka. Jeśli tani wpis — można podnieść do B przy okazji |
|
||||
| node-exporter | metryki hosta | **C** | Jak solaria — świadomie poza NodeDown |
|
||||
| pi-watchtower-1 | auto-update obrazów | **C** + **follow-up PILNY** | DZIŚ w crash-loopie, niewykrywalnym przez node-agent (luka na stan `restarting`). Decyzja operatora: naprawić albo USUNĄĆ (watchtower na edge = niekontrolowane pulle, sprzeczne z GitOps) |
|
||||
|
||||
### SATURN (1 luka)
|
||||
|
||||
| Kontener | Co robi | Kategoria | Uzasadnienie |
|
||||
|---|---|---|---|
|
||||
| agent-system-webui | operator UI (kopia dev?) | **C** | Saturn = workstation, często wyłączony; świadomie poza monitoringiem (jak w fleet-prometheus). Wyjaśnić czemu biega duplikat UI z pihy (follow-up) |
|
||||
|
||||
---
|
||||
|
||||
## F. Plan domknięcia — paczki na jedną sesję każda (DECYZJA — trwała)
|
||||
|
||||
**Zasada procesowa (z backlogu, do utrwalenia):** wpis w `hosts/<node>/services.yaml` +
|
||||
`inventory/topology.yaml` to CZĘŚĆ deployu każdego nowego serwisu, nie osobny krok "kiedyś".
|
||||
|
||||
**⚠ Gotcha techniczna dla WSZYSTKICH paczek (sprawdzić przed każdym wpisem):** supervisor
|
||||
matchuje klucz `node/nazwa-serwisu` z nazwą kanoniczną kontenera = label
|
||||
`com.docker.compose.service` (node_agent.py `_canonical_container_name()`). Dla stacków
|
||||
compose'owych to NIE jest nazwa kontenera: np. `nginxproxymanager-app-1` ma compose-service
|
||||
**"app"**, `wikijs-wiki-1` → "wiki", stąd w world/services.json wiszą kolizyjne klucze typu
|
||||
`piha/app`, `piha/db`, `piha/redis`, `piha/database`. Przed dodaniem wpisu sprawdzić na hoście:
|
||||
`docker inspect <kontener> --format '{{ index .Config.Labels "com.docker.compose.service" }}'`
|
||||
— i jeśli label koliduje/jest ogólnikowy, najpierw nadać `container_name` + porządny compose
|
||||
project name albo poprawić observer (patrz follow-upy). Bez tego wpis będzie wiecznym
|
||||
`missing_service` i zaspamuje kolejkę akcji.
|
||||
|
||||
### Paczka 1 — KB + już-zGitOps'owane serwisy (najtańsza-najważniejsza; czysta kategoria B)
|
||||
|
||||
Serwisy, które JUŻ są w repo (services/ + runtime overrides) — brakuje tylko rejestracji:
|
||||
|
||||
1. `hosts/piha/services.yaml`: + paperless, + stability-agent, + zigbee2mqtt
|
||||
2. `hosts/solaria/services.yaml`: + paperless-worker, + planner-agent, + stability-agent
|
||||
3. `hosts/vps/services.yaml`: + stability-agent, + npm, + mosquitto (i naprawić
|
||||
`services/mosquitto/service.yaml` owner_node: piha→vps oraz `services/npm` — potwierdzić
|
||||
że nazwa compose-service = "npm")
|
||||
4. `inventory/topology.yaml`: dopisać ww. do sekcji węzłów
|
||||
5. Weryfikacja: po 1–2 cyklach supervisora `world/services.json` ma klucze o zgodnych nazwach,
|
||||
kolejka pending NIE zawiera fałszywych `missing_service`; test driftu: `docker stop
|
||||
paperless-worker` na chwilę → pojawia się akcja → `docker start` → akcja auto-cancelled
|
||||
(test wymaga zgody operatora; alternatywnie tylko obserwacja biernie)
|
||||
6. Domknięcie wiszącego driftu: zdeployować gokapi na VPS (akcja `redeploy-vps-gokapi` już
|
||||
czeka na approve) — UWAGA: brak `hosts/vps/runtime/gokapi/docker-compose.override.yml`
|
||||
z mem_limit (reguła VPS 4GB) — dodać przed deployem.
|
||||
|
||||
### Paczka 2 — krytyczne shadow na PIHA (kategoria B dla przyszłych A)
|
||||
|
||||
Wpisy monitoringowe (bez ruszania deploymentu!) dla: vaultwarden, forgejo, homeassistant
|
||||
(kontener homeassistant5), immich, nginxproxymanager (compose-service prawdopodobnie "app" —
|
||||
patrz gotcha!), agent-system (telegram-bot, webui, redis, runtime-materializer), wikijs,
|
||||
actual-server, prom. Każdy wpis poprzedzony sprawdzeniem compose-label na hoście.
|
||||
Jeśli labels kolidują (db/app/redis) — najpierw follow-up "canonical naming" (niżej) albo
|
||||
wpis odroczony z adnotacją.
|
||||
|
||||
### Paczka 3 — VPS shadow (kategoria B + przygotowanie cutover)
|
||||
|
||||
1. Wpisy: outline, joplin, ai-cluster, humanai-landing, humanai-mailer (+ umami jeśli tanio)
|
||||
2. Przejrzeć gałąź `feat/vps-service-migration` (commit 862c04a: manifesty npm/outline/joplin/
|
||||
ai-cluster; cutover NIE wykonany) — zdecydować: merge + cutover per checklista z CLAUDE.md,
|
||||
czy przepisać od nowa. UWAGA: CLAUDE.md już dziś twierdzi "All VPS services are now
|
||||
GitOps-managed" — to NIEPRAWDA na masterze; poprawić doc albo zmergować gałąź.
|
||||
|
||||
### Paczka 4 — pełny GitOps dla krytycznych (kategoria A; JEDEN serwis = JEDNA sesja)
|
||||
|
||||
Kolejność wg bólu: 1) vaultwarden, 2) forgejo, 3) npm@piha + npm@vps (cutover), 4) immich,
|
||||
5) homeassistant5. Dla każdego: compose do `services/<name>/`, service.yaml, env.example,
|
||||
healthcheck.sh, runtime override w `hosts/piha/runtime/`, deploy przez deploy.sh.
|
||||
**Reguła migracji danych: ścieżki danych zostają NA MIEJSCU** (CLAUDE.md) — zero przenoszenia
|
||||
wolumenów bez osobnego planu.
|
||||
|
||||
### Paczka 5 — porządki i decyzje C (follow-upy)
|
||||
|
||||
- **lustro/pi-watchtower-1**: naprawić albo usunąć (crash-loop TERAZ; watchtower vs GitOps)
|
||||
- **piha/fail2ban-exporter**: unhealthy od ≥2 tyg. — naprawić albo usunąć
|
||||
- **saturn/agent-system-webui**: wyjaśnić czemu biega; usunąć jeśli pozostałość dev
|
||||
- **nextcloud**: przy deployu (osobna sesja per plan KB) wpis do services.yaml OD RAZU
|
||||
- **chelsty**: po powrocie online powtórzyć inwentaryzację (sekcja "Jak odświeżyć")
|
||||
- **saturn**: decyzja czy dostaje node-agenta + services.yaml (dziś świadomie poza)
|
||||
|
||||
### Follow-upy techniczne w kodzie monitoringu (poza zakresem tego reconu, do osobnych tasków)
|
||||
|
||||
1. **node-agent nie widzi stanu `restarting`** (crash-loop = cisza) — dodać gałąź dla
|
||||
`status == "restarting"` w `check_containers()` → event `containers_not_running` lub nowy
|
||||
typ `container_crash_loop`. Dowód: lustro/pi-watchtower-1.
|
||||
2. **Kolizje nazw kanonicznych** w observerze/node-agencie: label `com.docker.compose.service`
|
||||
bez project-name daje klucze `piha/db`, `piha/app`, `piha/redis` (dziś w world/services.json
|
||||
są duplikaty typu `piha/immich_server` I `piha/immich-server`). Propozycja: klucz
|
||||
`<project>_<service>` albo preferować container_name gdy label jest ogólnikowy.
|
||||
3. **Stęchły world-state dla offline węzłów**: serwisy chelsty-infra "healthy" 42 dni po
|
||||
zniknięciu węzła — status serwisu powinien degradować się razem z liveness węzła.
|
||||
4. **Alerting solaria/lustro**: świadomie wyłączone z NodeDown; docelowo anomaly detection
|
||||
(istniejący backlog "Plan: Monitoring floty — Prometheus jako źródło prawdy").
|
||||
|
||||
---
|
||||
|
||||
## TL;DR
|
||||
|
||||
- **Biega:** 76 kontenerów (42 piha, 24 vps, 5 solaria, 4 lustro, 1 saturn); chelsty-infra/ha
|
||||
offline od ~42 dni — niezweryfikowane.
|
||||
- **Alertowane:** 15 kontenerów przez 13 deklaracji desired-state (+ HA częściowo przez
|
||||
ha-diag-agent, + node-exporter@piha pośrednio przez NodeDown, + gokapi: zadeklarowany,
|
||||
niezdeployowany, drift POPRAWNIE wykryty i wisi w pending).
|
||||
- **Luka:** 61 kontenerów (~80%) bez alertowania. Detekcja (node-agent/observer) widzi
|
||||
wszystko; filtr jest w supervisorze — alertuje TYLKO to, co wpisane w
|
||||
`hosts/<node>/services.yaml` (bez `monitor: false`).
|
||||
- **Najboleśniejsze luki:** vaultwarden (hasła), forgejo (git), immich (zdjęcia),
|
||||
homeassistant5 (dom, częściowo kryty), npm ×2 (cały ingress), agent-system-telegram-bot
|
||||
(kanał alertów pilnujący wszystkiego innego, sam niepilnowany).
|
||||
- **Znaleziska przy okazji:** lustro/watchtower w crash-loopie niewykrywalnym przez node-agent
|
||||
(luka na stan `restarting`); fail2ban-exporter@piha unhealthy; gokapi czeka na deploy;
|
||||
CLAUDE.md błędnie twierdzi że VPS jest w pełni GitOps (manifesty na niezmergowanej gałęzi).
|
||||
- **Co najpierw:** Paczka 1 (wpisy dla paperless, paperless-worker, stability-agent ×3,
|
||||
zigbee2mqtt, npm, mosquitto, planner-agent — wszystko już w repo, tylko rejestracja)
|
||||
→ Paczka 2 (krytyczne shadow PIHA) → Paczka 3 (VPS) → Paczka 4 (pełny GitOps po kolei).
|
||||
|
||||
---
|
||||
|
||||
## Jak odświeżyć ten dokument
|
||||
|
||||
1. Stan faktyczny (sekcja A) — jedna pętla (uwaga na userów ssh: lustro=pi, reszta=oskar;
|
||||
solaria/saturn wg tego skąd odpalasz):
|
||||
|
||||
```bash
|
||||
for target in oskar@100.108.208.3 oskar@100.95.58.48 oskar@100.100.231.104 \
|
||||
pi@100.99.85.73 oskar@100.121.168.72 oskar@100.98.91.98; do
|
||||
echo "===== $target ====="
|
||||
ssh -o ConnectTimeout=10 -o BatchMode=yes "$target" \
|
||||
"date -u +%Y-%m-%dT%H:%M:%SZ; docker ps --format '{{.Names}}\t{{.Image}}\t{{.Status}}\t{{.Ports}}'"
|
||||
done
|
||||
```
|
||||
(kolejno: piha, vps, solaria, lustro, saturn, chelsty-infra; chelsty-infra pomiń jeśli offline)
|
||||
|
||||
2. Stan deklarowany (sekcja B): `grep -A2 "^services:" hosts/*/services.yaml` + ręcznie
|
||||
sprawdzić flagi `monitor: false`.
|
||||
3. Luka (sekcja C): porównać 1 z 2 per węzeł; pamiętać że 1 deklaracja może pokrywać stack
|
||||
wielokontenerowy (control-plane, vikunja) i że match idzie po labelu
|
||||
`com.docker.compose.service`, nie po nazwie kontenera.
|
||||
4. Wiszące akcje/drifty: `ssh vps ls /opt/homelab/actions/pending/`.
|
||||
5. Sekcje E–F: NIE odtwarzać — tylko dopisać nowe kontenery i odhaczyć wykonane paczki.
|
||||
Zmienić klasyfikację wolno tylko świadomą decyzją (to sekcje DECYZYJNE).
|
||||
Loading…
Reference in a new issue