Этап 6: починка NO DATA в Grafana (3 причины)+relabel instance→hostname; исправлены имена garage-метрик в панелях и алертах; опыт в EXPERIENCE.md

This commit is contained in:
kpa39l
2026-09-03 08:39:53 +00:00
parent 7437864b50
commit 66ff07c52a
8 changed files with 927 additions and 189 deletions
+115 -5
View File
@@ -124,6 +124,100 @@ grafana.nixg.ru {
- В логах caddy много ошибок renew для старых доменов — они имеют
уже выпущенные сертификаты в caddy_data, работает всё.
## Опыт: дашборд Grafana пустой (NO DATA) — 3 причины подряд (2026-09-02)
> Дата: 2026-09-02. Ситуация: после этапа 6 (tproxy) пользователь сообщил,
> что дашборд Garage Cluster в Grafana полностью пустой (NO DATA).
### 12. NO DATA #1: у datasource не задан `uid` — Grafana генерит случайный
В `grafana/provisioning/datasources/datasources.yml` у Prometheus-датасорса
НЕ был задан `uid`. Grafana при провиженинге присваивает датасорсу **случайный
UID** (в БД видно для Loki: `P8E80F9AEF21F6940`), а все панели дашборда
ссылались на `"uid": "Prometheus"`. Панели искали датасорс с таким uid — не
находили → NO DATA.
**Решение:** в datasources.yml добавить датасорсу явный `uid: Prometheus`
(совпадение 1-в-1 с uid в панелях). Дашборды провиженятся каждые 30с,
а datasources — **только при старте** Grafana → после правки `docker compose
restart grafana`. Проверка из БД (`docker cp grafana:/var/lib/grafana/grafana.db`):
`SELECT name, uid, url FROM data_source` → uid стал `Prometheus`.
### 13. NO DATA #2: Prometheus на host-сети, а datasource URL `http://prometheus:9090`
Prometheus и blackbox запущены с `network_mode: host` (нужно для WG 10.8.0.0/24),
а Grafana — в bridge-сети. Внутри сети Grafana имя `prometheus` **не
резолвится** (проверено `docker exec grafana getent hosts prometheus` →
NO_RESOLVE), поэтому URL `http://prometheus:9090` недостижим → панели без
данных. Loki в той же bridge-сети — резолвится нормально.
**Решение:** datasource URL заменить на `http://172.28.0.1:9090` — IP хоста
со стороны bridge-сети Grafana (шлюз сети = адрес хоста). Определяется так:
```
docker inspect grafana --format '{{range .NetworkSettings.Networks}}{{.Gateway}} {{end}}'
# → 172.28.0.1
```
Проверено из контейнера: `wget http://172.28.0.1:9090/-/healthy` → OK.
ВАЖНО: шлюз bridge-сети docker стабилен (подсеть фиксированная),
но если пересоздать сеть — IP может смениться.
### 14. NO DATA #3 (частично): панели ссылались на НЕСУЩЕСТВУЮЩИЕ метрики
После починки datasource tproxy-панели ожили, а garage-панели (blocks,
RPC node health, S3 req/sec) остались пустыми. Причина: панели были написаны
под НЕСУЩЕСТВУЮЩИЕ имена метрик, которых в Prometheus нет:
- `garage_block_count` — в реальности `block_resync_queue_length` / `block_resync_errored_blocks`
- `garage_rpc_node_health_is_up` — в реальности `cluster_layout_node_connected`
- `garage_api_s3_request_counter` — в реальности `api_s3_request_counter`
Метрики Garage из admin API (10.8.0.x:3903) **не имеют префикса `garage_`**:
`api_s3_request_counter`, `api_s3_request_duration_*`, `block_resync_*`,
`cluster_*` (connected_nodes, healthy, partitions_all_ok, layout_node_connected),
`table_*`, `rpc_*`. Префикс `garage_` есть только у `garage_build_info`,
`garage_local_disk_avail/total`, `garage_replication_factor`.
Проверка реальных метрик: `curl 'http://127.0.0.1:9090/api/v1/label/__name__/values'`
и фильтр по `job=garage`. Панели переписаны на реальные метрики:
- Garage blocks (resync): `block_resync_queue_length` + `block_resync_errored_blocks`
- Garage node health (layout): `cluster_layout_node_connected` (легенда `{{ role_zone }}`)
- S3 requests /sec: `rate(api_s3_request_counter[5m])`
### 15. Алерты ссылались на те же несуществующие метрики
В alerts.yml алерты GarageResyncErrors и GarageNodeUnstable использовали те же
фантомные имена (`garage_block_resync_error_count`, `garage_rpc_node_health_is_up`),
поэтому никогда не сработали бы. Исправлено на реальные:
`block_resync_errored_blocks > 0` и `cluster_layout_node_connected == 0`.
После правки `promtool check config` → 6 rules found, все eval.
### 16. Relabel `instance` → hostname вместо IP (читаемые легенды)
По умолчанию instance = адрес скрейпа: у tproxy это `127.0.0.1:18081`
(локальный конец SSH-туннеля), у garage `10.8.0.x:3903`, у node `10.8.0.x:9100`.
В Grafana легенды показывали IP — некрасиво и непонятно. Не путать: это НЕ
«мониторинг локального интерфейса», просто лейбл instance = транспорт туннеля.
**Решение (на уровне Prometheus, не панелей)** — relabel_configs в пром.yml:
```yaml
relabel_configs:
- target_label: instance
replacement: vps03:8081 # для job tproxy
- source_labels: [__address__] # для garage/node — маппинг IP → hostname
regex: 10.8.0.2:3903
target_label: instance
replacement: bigbox:3903
```
Теперь легенды: `vps01:3903`, `bigbox:3903`, `vps02:3903` (garage),
`vps03:8081` (tproxy), `vps01:9100` и т.д. (node). Правило: правим источник
(prom.yml relabel), а не легенды в каждой панели — консистентно везде
(панели, explore, алерты).
### 17. Grafana provisioning: дашборды — каждые 30с, datasources — только при старте
Дашборды перечитываются автоматически (updateIntervalSeconds, по умолчанию 30с),
а datasources провиженятся только при старте Grafana. После правки
datasources.yml — обязателен `docker compose restart grafana`.
## Опыт: tproxy-server (WEB Proxy для Telegram Desktop) на vps03
> Дата: 2026-08-31
@@ -163,14 +257,30 @@ backend_dial_failures_total, bytes_up_total, bytes_down_total, limit_hits_total.
Ключевые для алертов: `backend_dial_failures_total` (рост = бэкенд недоступен),
`limit_hits_total` (DDOS/перегруз), `sessions_live` (активность).
### C. Подключение к Prometheus (стек /opt/monitoring, bigbox)
### C. Подключение к Prometheus (стек /opt/monitoring, bigbox) — РЕШЕНО через SSH-туннель
- vps03 НЕ в WG (10.8.0.0/24 = vps01/bigbox/vps02), поэтому прямого доступа
к 8081 с bigbox нет. Prometheus в стеке — `network_mode: host` (видит внешние IP).
- План: nft-правило на vps03 (разрешить TCP 8081 с publIP bigbox 178.176.197.2),
job 'tproxy' в prometheus.yml, targets ['77.67.89.154:8081'].
- ВАЖНО: admin-эндпоинты слушают только loopback. Открывать наружу ТОЛЬКО
по источнику (ip saddr bigbox), не публиковать всем.
- Изначальный план (nft-правило на vps03: разрешить TCP 8081 с publIP bigbox
178.176.197.2) **не сработал**: tproxy-server слушает `admin_listen: 127.0.0.1:8081`,
запрос с bigbox к `77.67.89.154:8081` вернул `Connection refused` (соединение
упёрлось в отсутствующего наружу слушателя, а не в файрвол).
- **Решение:** SSH-туннель bigbox → vps03 (паттерн systemd, как telegram-tunnel):
```ini
# /etc/systemd/system/tproxy-tunnel.service (bigbox)
User=estorozhenko
ExecStart=/usr/bin/ssh -i /home/estorozhenko/.ssh/hostkeyVPS \
-L 127.0.0.1:18081:127.0.0.1:8081 -N \
-o ServerAliveInterval=30 -o ServerAliveCountMax=3 \
-o ExitOnForwardFailure=yes -o StrictHostKeyChecking=accept-new \
root@77.67.89.154
Restart=always
```
Prometheus скрейпит `127.0.0.1:18081`. tproxy-server config/файрвол НЕ трогаются,
метрики остаются на loopback.
- **ВНИМАНИЕ с портом:** сначала взял `8081` — но он на bigbox уже занят ICQ-веб-чатом
(Converse.html на 0.0.0.0:8081), туннель конфликтовал и отдавал HTML чата вместо
метрик. Порт на bigbox выбирать свободный (взял 18081).
- readyz ходит ко ВСЕМ профилям: если добавить профиль с мёртвым бэкендом —
readyz станет 503 (фича, учтена при алертах).