mirror of
https://gitverse.ru/kpa39l/monitoring.git
synced 2026-09-29 09:55:09 +00:00
224 lines
12 KiB
Markdown
224 lines
12 KiB
Markdown
# Monitoring stack — Garage cluster (vps01 + bigbox + vps02) + Vinograd WAN
|
||
|
||
Стек мониторинга для S3-кластера Garage (репликация RF=3, WireGuard 10.8.0.0/24)
|
||
и внешнего канала связи объекта «Винный город» (провайдер Ростелеком).
|
||
Расположен на **bigbox** в `/opt/monitoring`.
|
||
|
||
## Архитектура
|
||
|
||
```
|
||
bigbox (10.8.0.2)
|
||
┌─────────────────────────────────────────────────┐
|
||
│ prometheus :9090 (host net) │
|
||
│ │ scrape ──► garage x3 :3903 (WG admin) │
|
||
│ ├──► node-exporter :9100 (bigbox) │
|
||
│ ├──► 10.8.0.1:3903 (vps01) │
|
||
│ ├──► 10.8.0.4:3903 (vps02) │
|
||
│ └──► blackbox :9115 (host net) → /health │
|
||
│ │
|
||
│ grafana :3001 (dashboards, alerts) │
|
||
│ loki :3100 (logs) │
|
||
│ promtail ── docker.sock ──► docker logs garage │
|
||
└─────────────────────────────────────────────────┘
|
||
│ │
|
||
▼ WireGuard 10.8.0.0/24 ▼ caddy (vps02)
|
||
vps01 (10.8.0.1) grafana.nixg.ru
|
||
vps02 (10.8.0.4) → 87.242.100.206 → reverse_proxy 10.8.0.2:3001
|
||
```
|
||
|
||
Прометеус и blackbox-exporter работают в **host network** (иначе не видят
|
||
WireGuard-подсеть 10.8.0.0/24 хостa). Остальные — в bridge-сети monitoring.
|
||
|
||
## Сервисы и порты
|
||
|
||
| Сервис | Порт | Доступ | Примечание |
|
||
|------------------|--------|---------------------|-------------------------------------|
|
||
| Prometheus | 9090 | локально/WG | host network, retention 30d (TSDB) |
|
||
| Grafana | 3001 | браузер + публично | 3000 занят gitea → 3001 |
|
||
| Loki | 3100 | локально | сбор логов, retention 7d |
|
||
| Promtail | — | docker.sock | docker logs garage и др. |
|
||
| blackbox-exporter| 9115 | host network | HTTP-пробы /health нод |
|
||
| node-exporter | 9100 | WG | на каждой ноде (apt) |
|
||
|
||
## Публичный доступ
|
||
|
||
```
|
||
grafana.nixg.ru → 87.242.100.206 (vps02) → caddy → reverse_proxy 10.8.0.2:3001
|
||
```
|
||
|
||
- Запись добавлена в `/opt/caddy/Caddyfile` на vps02:
|
||
`grafana.nixg.ru { reverse_proxy 10.8.0.2:3001 }`
|
||
- Caddy — docker-контейнер (`network_mode: host`), перезагрузка:
|
||
`docker exec caddy caddy reload --config /etc/caddy/Caddyfile`
|
||
- Сертификат Let's Encrypt выпускается автоматически.
|
||
- Логин: **estorozhenko** (сменён с admin через UI), пароль — задан пользователем.
|
||
- Read-only доступ: **it@vinogorod.ru** (роль **Viewer**, создан вручную в UI,
|
||
пароль `1qazXSW2`). Только просмотр дашбордов, без правки. Учётка в
|
||
`grafana-data` (переживает пересоздание контейнера).
|
||
|
||
## Garage admin API (метрики)
|
||
|
||
В Garage v2.1 admin API (включая `/metrics` в Prometheus-формате) слушает
|
||
**отдельный порт** `[admin] api_bind_addr`. На всех трёх нодах прописано:
|
||
|
||
```toml
|
||
[admin]
|
||
api_bind_addr = "<WG-IP>:3903" # bigbox 10.8.0.2, vps01 10.8.0.1, vps02 10.8.0.4
|
||
admin_token = "..."
|
||
metrics_token = "..."
|
||
```
|
||
|
||
Проверка метрик:
|
||
```
|
||
curl -H "Authorization: Bearer TOKEN" http://10.8.0.2:3903/metrics
|
||
```
|
||
`/health` возвращает 200 при кворуме (≥2 нод), 503 иначе.
|
||
|
||
Порты 3903 и 9100 открыты только для WG-подсети:
|
||
- vps01: `ufw allow from 10.8.0.0/24 to any port 3903` (и 9100 аналогично)
|
||
- vps02/bigbox: файрвол не блокирует (policy ACCEPT)
|
||
|
||
## Запуск
|
||
|
||
```
|
||
cd /opt/monitoring
|
||
docker compose up -d
|
||
```
|
||
|
||
Пароль Grafana — переменная `GRAFANA_ADMIN_PASSWORD` в `.env` (по умолчанию `admin`).
|
||
Пользователь Grafana: `estorozhenko` (сменён пользователем вручную).
|
||
|
||
## Полезные команды
|
||
|
||
```
|
||
# статус кластера
|
||
docker run --rm -v /opt/garage/garage.toml:/etc/garage.toml:ro \
|
||
-v /opt/garage/meta:/var/lib/garage/meta \
|
||
--entrypoint /garage dxflrs/garage:v2.1.0 status
|
||
|
||
# метрики одной ноды (Prometheus-формат)
|
||
curl -s -H "Authorization: Bearer TOKEN" http://10.8.0.2:3903/metrics | head
|
||
|
||
# health
|
||
curl -s -o /dev/null -w "%{http_code}" http://10.8.0.2:3903/health
|
||
|
||
# таргеты прометея (все должны быть UP)
|
||
curl http://127.0.0.1:9090/api/v1/targets
|
||
|
||
# принудительная синхронизация mirror'а в gitea
|
||
curl -X POST -H "Authorization: token GITEA_TOK" \
|
||
http://127.0.0.1:3000/api/v1/repos/estorozhenko/monitoring/mirror-sync
|
||
```
|
||
|
||
## Алерты (prometheus/alerts.yml)
|
||
|
||
| Алерт | Условие | Severity |
|
||
|--------------------|--------------------------------|----------|
|
||
| GarageNodeDown | `up{job="garage"} == 0` (2м) | critical |
|
||
| GarageNoQuorum | `<2` нод up (2м) | critical |
|
||
| GarageResyncErrors | `block_resync_errored_blocks > 0` (10м) | warning |
|
||
| GarageNodeUnstable | `cluster_layout_node_connected == 0` (5м) | warning |
|
||
| TProxyDown | `up{job="tproxy"} == 0` (2м) | critical |
|
||
| TProxyBackendErrors| `increase(tproxy_backend_dial_failures_total[5m]) > 0` (10м) | warning |
|
||
| VinogradRostelecomDown | `probe_success{job="vinograd_wan"} == 0` (2м) | critical |
|
||
|
||
Примечание: метрики Garage из admin API (:3903) НЕ имеют префикса `garage_` —
|
||
это `api_s3_request_counter`, `block_resync_*`, `cluster_*`. Префикс `garage_`
|
||
только у `garage_build_info`, `garage_local_disk_*`, `garage_replication_factor`.
|
||
|
||
## Vinograd WAN — внешний канал «Винный город» (Ростелеком)
|
||
|
||
Объект «Винный город» (г. Геленджик, ул. Туристическая, 25), канал Ростелеком
|
||
(договор Бастион, Static IP). Адреса из «Реестра внешних каналов связи.ods»
|
||
(закладка «Винный город»):
|
||
|
||
| Адрес | Роль |
|
||
|-------|------|
|
||
| 83.239.50.145 | Шлюз (gateway) — поднимается от РТК |
|
||
| 83.239.50.146 | Наше оборудование (CPE, Static IP, /30) |
|
||
|
||
Мониторинг через **blackbox-exporter (ICMP-проба)** → Prometheus job `vinograd_wan`:
|
||
|
||
- Интервал scrape: **30s** (графики скорости ответа каждые 30 секунд)
|
||
- Метрики:
|
||
- `probe_success{job="vinograd_wan"}` — доступность (1/0)
|
||
- `probe_icmp_duration_seconds{job="vinograd_wan",phase="rtt"}` — RTT, сек
|
||
- Лейблы `instance`: `vinograd-gw-83.239.50.145`, `vinograd-cpe-83.239.50.146`
|
||
- Алерт: **VinogradRostelecomDown** (critical, 2м подряд недоступен)
|
||
- Grafana: дашборд **Vinograd WAN** (RTT ms + availability), панели в фолдере Garage
|
||
|
||
Retention: глобальный 30d (прометеевский TSDB) — данные хранятся минимум неделю,
|
||
что покрывает требование «хранить неделю» с запасом (жёсткий 7d для одного job
|
||
требовал бы отдельного инстанса Prometheus).
|
||
|
||
Проверка вручную:
|
||
```bash
|
||
# ICMP-проба через blackbox (debug)
|
||
curl -s "http://127.0.0.1:9115/probe?target=83.239.50.146&module=icmp&debug=true"
|
||
# данные в Prometheus
|
||
curl -sG 'http://127.0.0.1:9090/api/v1/query' \
|
||
--data-urlencode 'query=probe_success{job="vinograd_wan"}'
|
||
```
|
||
|
||
> Статус 2026-09-08: шлюз 83.239.50.145 НЕ отвечает на ICMP (probe_success=0,
|
||
> совпадает с алертом UptimeKuma 08:07 MSK). Оборудование 83.239.50.146
|
||
> отвечает ~13ms. Алерт VinogradRostelecomDown в состоянии FIRE до восстановления
|
||
> канала — это корректное отражение реальной аварии.
|
||
|
||
## tproxy-server (vps03) — метрики WEB Proxy (этап 6, РЕШЕНО ✅)
|
||
|
||
tproxy-server (Telegram Desktop WEB Proxy) развёрнут на **vps03** (77.67.89.154),
|
||
admin-эндпоинты на loopback :8081: `/healthz`, `/readyz`, `/metrics`
|
||
(Prometheus-формат, 13 счётчиков `tproxy_*`).
|
||
|
||
> **2026-09-08: vps03 подключён к WireGuard (10.8.0.3)** — вместо SSH-туннеля.
|
||
> Админ-эндпоинты tproxy остались на loopback, но туннель `tproxy-tunnel.service`
|
||
> удалён не был (безвреден, оставлен на всякий случай). Prometheus берёт node-метрики
|
||
> vps03 напрямую по WG: `10.8.0.3:9100`.
|
||
|
||
- Локальный порт **18081** (не 8081 — тот на bigbox занят ICQ-веб-чатом!)
|
||
- Prometheus скрейпит `127.0.0.1:18081` (job `tproxy`, host=vps03), но через
|
||
relabel_configs в prometheus.yml лейбл `instance` заменён на **`vps03:8081`**,
|
||
чтобы в Grafana легенды показывали hostname, а не IP туннеля.
|
||
Аналогично relabel сделан для garage (`10.8.0.x:3903` → `vps01|bigbox|vps02:3903`)
|
||
и node (`10.8.0.x:9100` → hostname).
|
||
- Дашборд: 3 панели tproxy (sessions/streams, traffic /sec, backend errors)
|
||
- Алерты: TProxyDown (critical), TProxyBackendErrors (warning)
|
||
|
||
Подробности — в PLAN.md (этап 6) и EXPERIENCE.md.
|
||
|
||
## Node-дашборды (диски/память/сеть/доступность) — этап 7, РЕШЕНО ✅
|
||
|
||
На каждую ноду (vps01, vps02, vps03, bigbox) — **отдельный дашборд**,
|
||
`grafana/dashboards/node-<host>.json` (uid `node-<host>`, title "Node <host>").
|
||
Генерируются скриптом `/tmp/gen_nodes_dash.py` (в git не хранится; при желании
|
||
перенести — в EXPERIENCE.md).
|
||
|
||
Панели (все по `{host="<host>"}`, job=node):
|
||
1. **Availability** — stat-панель `up{job="node",host=...}` (UP/DOWN)
|
||
2. **Disk free (GB)** — `node_filesystem_avail_bytes` (без tmpfs/overlay/squashfs)
|
||
3. **Memory available (GB)** — `node_memory_MemAvailable_bytes`
|
||
4. **Load** — `node_load1/5/15`
|
||
5. **Net <iface> RX/TX (bytes/s)** — `rate(node_network_{receive,transmit}_bytes_total[5m])`
|
||
6. **Net <iface> utilization (%)** — `(rx+tx)*8/speed*100`
|
||
|
||
Физические интерфейсы: vps01=eth0, vps02=enp3s0, vps03=ens1, bigbox=eno1.
|
||
Контейнерные (docker0/veth*/br-*) не включены.
|
||
|
||
Тонкость node-exporter 1.9: на виртуалках vps01/vps02 `node_network_speed_bytes`
|
||
= **-125000** (sysfs speed=-1 → умножается на 125000), поэтому для них скорость
|
||
линка захардкожена **125000000 Б/с (1 Gbit/s)** в формуле утилизации. На физических
|
||
(vps03/bigbox) используется сама метрика `node_network_speed_bytes` (=1.25e+08).
|
||
|
||
## Катастрофоустойчивость
|
||
|
||
Проект хранится в **двух** git-репозиториях — на случай поломки bigbox:
|
||
|
||
| Репозиторий | Роль | Адрес |
|
||
|-------------|------|-------|
|
||
| **gitverse.ru** (облако) | источник истины | `git@gitverse.ru:kpa39l/monitoring.git` |
|
||
| **gitea на bigbox** | pull-mirror (8h) | `https://gitea.nixg.ru/estorozhenko/monitoring` |
|
||
|
||
Порядок работы: правки коммитятся и пушутся в gitverse (источник), gitea
|
||
подтягивает их mirror'ом (каждые 8ч или вручную mirror-sync). Если bigbox
|
||
сломается — репозиторий остаётся в облаке gitverse. |