commit 7a41e7f32c34348660cda2c80bf91226a2ebcfcb Author: kpa39l Date: Sun Aug 30 13:38:29 2026 +0000 first_commit diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..24da4ac --- /dev/null +++ b/.gitignore @@ -0,0 +1,14 @@ +# Данные и кэши — не в git +prometheus-data/ +grafana-data/ +loki-data/ +promtail-data/ + +# env с паролями +.env +.env.* + +# временное +*.tmp +*.log +.DS_Store \ No newline at end of file diff --git a/EXPERIENCE.md b/EXPERIENCE.md new file mode 100644 index 0000000..542c3f6 --- /dev/null +++ b/EXPERIENCE.md @@ -0,0 +1,103 @@ +# Опыт эксплуатации: мониторинг Garage v2.1 через Prometheus + +> Дата: 2026-08-30 +> Ситуация: кластер Garage v2.1 (RF=3) на vps01 + bigbox + vps02, WireGuard 10.8.0.0/24. +> Задача: вывести статус кластера в браузер (Grafana + Prometheus + Loki). + +## Ключевые находки / грабли + +### 1. Admin API Garage v2.1 слушает ОТДЕЛЬНЫЙ порт (`[admin] api_bind_addr`) + +Самое важное. Если `api_bind_addr` НЕ задан в `[admin]`, Garage слушает admin +(включая `/metrics`) на **том же порту, что S3 API** (3900). В этом случае +`Authorization: Bearer ` к `/metrics` на 3900 отвечает +`400 Bad request: Unsupported authorization method` — авторизация S3 не понимает +Bearer, а admin-роутер не подключён. + +**Решение:** добавить в `[admin]` отдельный адрес: + +```toml +[admin] +api_bind_addr = "10.8.0.2:3903" # свой WG-IP на каждой ноде +metrics_token = "..." +admin_token = "..." +``` + +После рестарта ноды `/metrics` и `/health` доступны на `:3903`. + +### 2. `metrics_token` НЕ обязателен + +Если `metrics_token` не задан — `/metrics` доступен **без авторизации**. +Если задан — используется как обычный Bearer token: +``` +curl -H "Authorization: Bearer " http://node:3903/metrics +``` +(совпадает с синтаксисом admin_token; для метрик достаточно metrics_token). + +### 3. Docker-образ `dxflrs/garage:v2.1.0` — scratch без shell + +- Нет `/bin/sh`, нет `ls`, `docker exec garage ls` — не работает. +- CLI-бинарь лежит по пути `/garage` внутри образа, а НЕ в PATH. +- Поэтому проверка статуса через docker run: +``` +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 +``` +(без монтирования `meta` будет ошибка "Unable to read node key"). + +### 4. Перезапуск нод кластера — безопасно, но по очереди + +`docker compose restart garage` на всех трёх нодах прошёл **без потери кворума** +и без пересборки layout — кластер остался HEALTHY (layout version 1 сохранился). +Порядок: внешние (vps02, vps01) → bigbox. Пауза ~8с между рестартами. + +### 5. UFW на vps01 режет новые порты + +Порт 3903 на vps01 был закрыт UFW (в отличие от 3901, открытого для Anywhere). +Пришлось: +``` +sudo ufw allow from 10.8.0.0/24 to any port 3903 proto tcp comment "garage admin metrics" +``` +На vps02 файрвол — nftables с policy ACCEPT, порт не блокировался. + +### 6. Конфиг garage.toml на vps01/vps02 принадлежит root + +Правка через SSH требует sudo (python не может писать напрямую): +``` +ssh vps01 'sudo sed -i "s|^\[admin\]$|[admin]\napi_bind_addr = \"10.8.0.1:3903\"|" /opt/garage/garage.toml' +``` + +### 7. Авторизация в веб-поиске не работает напрямую с bigbox + +SearXNG (127.0.0.1:11436) возвращает пустые результаты из-за блокировок +движков (brave rate-limit, duckduckgo CAPTCHA, startpage timeout). +Документация Garage достаётся напрямую с git.deuxfleurs.fr: +``` +https://git.deuxfleurs.fr/Deuxfleurs/garage/raw/branch/main-v1/doc/book/reference-manual/configuration.md +https://git.deuxfleurs.fr/Deuxfleurs/garage/raw/branch/main-v1/doc/book/reference-manual/admin-api.md +``` +Ветка по умолчанию для v2.x — `main-v1` (не `main`). + +## Проверка результата + +``` +# все три ноды отдают метрики: +curl -s -H "Authorization: Bearer " http://10.8.0.1:3903/metrics | head +curl -s -H "Authorization: Bearer " http://10.8.0.2:3903/metrics | head +curl -s -H "Authorization: Bearer " http://10.8.0.4:3903/metrics | head +# → HTTP 200, ~90-110 КБ текста в Prometheus-формате + +# кластер HEALTHY: +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 +``` + +## Что осталось сделать / TODO + +- [ ] Поднять `docker compose up -d` в /opt/monitoring (после первого коммита) +- [ ] Node-exporter на всех 3 хостах (10.8.0.x:9100) +- [ ] Дашборд Garage в Grafana (provisioning уже настроен, нужен JSON) +- [ ] Проверить `up{job="garage"}` в Prometheus и открыть Grafana :3001 +- [ ] Логи garage через promtail → Loki → Grafana +- [ ] Сделать разные admin_token / metrics_token (сейчас совпадают) \ No newline at end of file diff --git a/PLAN.md b/PLAN.md new file mode 100644 index 0000000..4620342 --- /dev/null +++ b/PLAN.md @@ -0,0 +1,61 @@ +# План работ: мониторинг Garage-кластера + +## Цель +Вывести статус кластера Garage (vps01, bigbox, vps02) в браузер через Grafana, +с Prometheus-метриками и сбором логов (Loki). Без трейсов (до них «не доросли»). + +## Этап 1. Метрики Garage (выполнено ✅) + +1. Понять, как Garage v2.1 отдаёт метрики. + → Найдено: admin API на отдельном порту `[admin] api_bind_addr`; `/metrics` в + Prometheus-формате; `metrics_token` опционален. +2. Добавить в `/opt/garage/garage.toml` на **трёх** нодах: + ```toml + [admin] + api_bind_addr = ":3903" + metrics_token = "" + ``` + - bigbox: 10.8.0.2:3903 (файл — estorozhenko) + - vps01: 10.8.0.1:3903 (файл — root, sudo) + - vps02: 10.8.0.4:3903 (файл — root, sudo) +3. Открыть порт 3903 для WG-подсети на vps01 (ufw); на vps02/bigbox не требуется. +4. Перезапустить ноды по очереди: vps02 → vps01 → bigbox (пауза ~8с). +5. Проверить: `curl -H "Authorization: Bearer " http://:3903/metrics` → 200. + +**Результат:** все 3 ноды отдают метрики, кластер HEALTHY. + +## Этап 2. Стек мониторинга на bigbox (в работе 🔄) + +- [x] Создать `/opt/monitoring/` с docker-compose.yml, prometheus.yml, alerts.yml +- [x] Prometheus: таргеты garage x3 (:3903), health x3, node-exporters, self +- [ ] Node-exporter на 3 хостах (10.8.0.x:9100) +- [ ] Запустить `docker compose up -d` +- [ ] Проверить Prometheus :9090 (`up{job="garage"}`, targets) +- [ ] Grafana :3001: datasource Prometheus, дашборд Garage, alerts + +## Этап 3. Логи (после метрик 🔄) + +- [ ] Promtail (docker.sock) → Loki :3100 → Grafana +- [ ] Логи garage со всех нод (сейчас promtail только на bigbox) + +## Этап 4. Git + катастрофоустойчивость (в работе 🔄) + +- [x] MD-файлы: README.md, EXPERIENCE.md, PLAN.md +- [ ] git init в /opt/monitoring, первый коммит +- [ ] remote: git@gitverse.ru:kpa39l/monitoring.git (master) +- [ ] `git push -u origin master` +- [ ] В gitea: pull mirror репозитория из gitverse +- [ ] В gitea: добавить estorozhenko с полными правами (на случай поломки bigbox) + +## Этап 5. Полировка (TODO) + +- [ ] Разные admin_token / metrics_token (`openssl rand -base64 32`) +- [ ] Дашборд: статус нод, занятость диска, блоки, репликация +- [ ] Уведомления алертов (например, в Telegram/почту) + +## Риски / заметки + +- Перезапуск нод кластера безопасен, но делать по очереди. +- Scratch-образ garage → для CLI-команд нужен `--entrypoint /garage` + монтирование meta. +- Интернет с bigbox частично ограничен; документация — через git.deuxfleurs.fr (ветка main-v1). +- Port 3000 занят gitea → Grafana на 3001. \ No newline at end of file diff --git a/README.md b/README.md new file mode 100644 index 0000000..23b7217 --- /dev/null +++ b/README.md @@ -0,0 +1,93 @@ +# Monitoring stack — Garage cluster (vps01 + bigbox + vps02) + +Стек мониторинга для S3-кластера Garage (репликация RF=3, WireGuard 10.8.0.0/24). +Расположен на **bigbox** в `/opt/monitoring`. + +## Архитектура + +``` + bigbox (10.8.0.2) + ┌─────────────────────────────────────────────────┐ + │ prometheus :9090 ── scrape ──► garage x3 :3903 │ + │ │ (WG admin API) │ + │ ├──► node-exporter :9100 (bigbox) │ + │ └──► 10.8.0.1:3903 (vps01) │ + │ 10.8.0.4:3903 (vps02) │ + │ │ + │ grafana :3001 (dashboards, alerts) │ + │ loki :3100 (logs) │ + │ promtail ── docker.sock ──► docker logs garage │ + └─────────────────────────────────────────────────┘ + │ + ▼ WireGuard 10.8.0.0/24 + vps01 (10.8.0.1) vps02 (10.8.0.4) +``` + +## Сервисы и порты + +| Сервис | Порт | Доступ | Примечание | +|-----------|-----------|--------------------|--------------------------------| +| Prometheus| 9090 | локально/WG | retention 30d (TSDB) | +| Grafana | 3001 | браузер bigbox | 3000 занят gitea → 3001 | +| Loki | 3100 | локально | сбор логов | +| Promtail | — | docker.sock | docker logs garage | +| node-exp | 9100 | WG | на каждой ноде (системные метрики) | + +## Garage admin API (метрики) + +В Garage v2.1 admin API (включая `/metrics` в Prometheus-формате) слушает +**отдельный порт** `[admin] api_bind_addr`. На всех трёх нодах прописано: + +```toml +[admin] +api_bind_addr = ":3903" # bigbox 10.8.0.2, vps01 10.8.0.1, vps02 10.8.0.4 +admin_token = "c213de..." +metrics_token = "c213de..." +``` + +Проверка метрик: +``` +curl -H "Authorization: Bearer c213de..." http://10.8.0.2:3903/metrics +``` +`/health` возвращает 200 при кворуме (≥2 нод), 503 иначе. + +Порты 3903 открыты только для WG-подсети: +- vps01: `ufw allow from 10.8.0.0/24 to any port 3903` +- vps02/bigbox: файрвол не блокирует (policy ACCEPT) + +## Запуск + +``` +cd /opt/monitoring +docker compose up -d +``` + +Пароль Grafana — переменная `GRAFANA_ADMIN_PASSWORD` в `.env` (по умолчанию `admin`). + +## Полезные команды + +``` +# статус кластера +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 " http://10.8.0.2:3903/metrics | head + +# health +curl -s -o /dev/null -w "%{http_code}" http://10.8.0.2:3903/health +``` + +## Алерты (prometheus/alerts.yml) + +| Алерт | Условие | Severity | +|--------------------|--------------------------------|----------| +| GarageNodeDown | `up{job="garage"} == 0` (2м) | critical | +| GarageNoQuorum | `<2` нод up (2м) | critical | +| GarageResyncErrors | `garage_block_resync_error_count > 0` (10м) | warning | +| GarageNodeUnstable | RPC health down (5м) | warning | + +## Катастрофоустойчивость + +Проект хранится в **двух** git-репозиториях (см. ниже) — на случай поломки bigbox. \ No newline at end of file diff --git a/alerts.yml b/alerts.yml new file mode 100644 index 0000000..977df0a --- /dev/null +++ b/alerts.yml @@ -0,0 +1,34 @@ +groups: + - name: garage + rules: + - alert: GarageNodeDown + expr: up{job="garage"} == 0 + for: 2m + labels: + severity: critical + annotations: + summary: "Garage node {{ $labels.instance }} is down" + + - alert: GarageNoQuorum + expr: (count(up{job="garage"} == 1) < 2) + for: 2m + labels: + severity: critical + annotations: + summary: "Garage cluster lost quorum (<2 nodes up)" + + - alert: GarageResyncErrors + expr: garage_block_resync_error_count > 0 + for: 10m + labels: + severity: warning + annotations: + summary: "Garage resync errors on {{ $labels.instance }}" + + - alert: GarageNodeUnstable + expr: garage_rpc_node_health_is_up == 0 + for: 5m + labels: + severity: warning + annotations: + summary: "Garage RPC health of some node is down" \ No newline at end of file diff --git a/docker-compose.yml b/docker-compose.yml new file mode 100644 index 0000000..d46c961 --- /dev/null +++ b/docker-compose.yml @@ -0,0 +1,70 @@ +# Monitoring stack: Prometheus + Grafana + Loki + Promtail +# Garage cluster (vps01, bigbox, vps02) metrics via WG admin API :3903 +# Logs: docker logs of garage containers via promtail (docker driver) + +services: + prometheus: + image: prom/prometheus:v2.53.0 + container_name: prometheus + restart: unless-stopped + volumes: + - ./prometheus.yml:/etc/prometheus/prometheus.yml:ro + - ./prometheus-data:/prometheus + command: + - '--config.file=/etc/prometheus/prometheus.yml' + - '--storage.tsdb.retention.time=30d' + - '--storage.tsdb.path=/prometheus' + ports: + - "9090:9090" + networks: + - monitoring + + grafana: + image: grafana/grafana:11.1.0 + container_name: grafana + restart: unless-stopped + environment: + - GF_SECURITY_ADMIN_USER=admin + - GF_SECURITY_ADMIN_PASSWORD=${GRAFANA_ADMIN_PASSWORD:-admin} + - GF_USERS_ALLOW_SIGN_UP=false + - GF_SERVER_ROOT_URL=http://localhost:3001 + volumes: + - ./grafana-data:/var/lib/grafana + - ./grafana/provisioning:/etc/grafana/provisioning:ro + - ./grafana/dashboards:/var/lib/grafana/dashboards:ro + ports: + - "3001:3000" + depends_on: + - prometheus + networks: + - monitoring + + loki: + image: grafana/loki:3.1.0 + container_name: loki + restart: unless-stopped + command: -config.file=/etc/loki/local-config.yaml + volumes: + - ./loki-config.yaml:/etc/loki/local-config.yaml:ro + - ./loki-data:/loki + ports: + - "3100:3100" + networks: + - monitoring + + promtail: + image: grafana/promtail:3.1.0 + container_name: promtail + restart: unless-stopped + volumes: + - ./promtail-config.yaml:/etc/promtail/config.yaml:ro + - /var/run/docker.sock:/var/run/docker.sock + command: -config.file=/etc/promtail/config.yaml + depends_on: + - loki + networks: + - monitoring + +networks: + monitoring: + driver: bridge \ No newline at end of file diff --git a/grafana/dashboards/garage-cluster.json b/grafana/dashboards/garage-cluster.json new file mode 100644 index 0000000..0de5352 --- /dev/null +++ b/grafana/dashboards/garage-cluster.json @@ -0,0 +1,144 @@ +{ + "annotations": { + "list": [] + }, + "editable": true, + "fiscalYearStartMonth": 0, + "graphTooltip": 1, + "id": null, + "links": [], + "panels": [ + { + "datasource": { "type": "prometheus", "uid": "Prometheus" }, + "fieldConfig": { + "defaults": { + "color": { "mode": "thresholds" }, + "mappings": [ + { "options": { "0": { "color": "red", "text": "DOWN" }, "1": { "color": "green", "text": "UP" } }, "type": "value" } + ], + "thresholds": { "mode": "absolute", "steps": [ { "color": "red", "value": null }, { "color": "green", "value": 1 } ] } + }, + "overrides": [] + }, + "gridPos": { "h": 8, "w": 6, "x": 0, "y": 0 }, + "id": 1, + "options": { + "colorMode": "background", + "graphMode": "none", + "justifyMode": "auto", + "orientation": "auto", + "reduceOptions": { "calcs": [ "lastNotNull" ], "fields": "", "values": false }, + "textMode": "auto" + }, + "pluginVersion": "11.1.0", + "targets": [ + { "datasource": { "type": "prometheus", "uid": "Prometheus" }, "expr": "up{job=\"garage\"}", "legendFormat": "{{ instance }}", "refId": "A" } + ], + "title": "Garage nodes up", + "type": "stat" + }, + { + "datasource": { "type": "prometheus", "uid": "Prometheus" }, + "fieldConfig": { + "defaults": { + "color": { "mode": "palette-classic" }, + "custom": { "axisCenteredZero": false, "axisColorMode": "text", "axisLabel": "", "axisPlacement": "auto", "drawStyle": "line", "fillOpacity": 10, "gradientMode": "none", "hideFrom": { "legend": false, "tooltip": false, "viz": false }, "lineInterpolation": "linear", "lineWidth": 1, "pointSize": 5, "scaleDistribution": { "type": "linear" }, "showPoints": "never", "spanNulls": false, "stacking": { "group": "A", "mode": "none" }, "thresholdsStyle": { "mode": "off" } }, + "mappings": [], + "thresholds": { "mode": "absolute", "steps": [ { "color": "green", "value": null } ] } + }, + "overrides": [] + }, + "gridPos": { "h": 8, "w": 6, "x": 6, "y": 0 }, + "id": 2, + "options": { + "legend": { "calcs": [], "displayMode": "list", "placement": "bottom", "showLegend": true }, + "tooltip": { "mode": "multi", "sort": "none" } + }, + "targets": [ + { "datasource": { "type": "prometheus", "uid": "Prometheus" }, "expr": "node_filesystem_avail_bytes{fstype!~\"tmpfs|overlay|squashfs\"} / 1024 / 1024 / 1024", "legendFormat": "{{ instance }}", "refId": "A" } + ], + "title": "Node disk free (GB)", + "type": "timeseries" + }, + { + "datasource": { "type": "prometheus", "uid": "Prometheus" }, + "fieldConfig": { + "defaults": { + "color": { "mode": "palette-classic" }, + "custom": { "axisCenteredZero": false, "axisColorMode": "text", "axisLabel": "", "axisPlacement": "auto", "drawStyle": "line", "fillOpacity": 10, "gradientMode": "none", "hideFrom": { "legend": false, "tooltip": false, "viz": false }, "lineInterpolation": "linear", "lineWidth": 1, "pointSize": 5, "scaleDistribution": { "type": "linear" }, "showPoints": "never", "spanNulls": false, "stacking": { "group": "A", "mode": "none" }, "thresholdsStyle": { "mode": "off" } }, + "mappings": [], + "thresholds": { "mode": "absolute", "steps": [ { "color": "green", "value": null } ] } + }, + "overrides": [] + }, + "gridPos": { "h": 8, "w": 12, "x": 12, "y": 0 }, + "id": 3, + "options": { + "legend": { "calcs": [], "displayMode": "list", "placement": "bottom", "showLegend": true }, + "tooltip": { "mode": "multi", "sort": "none" } + }, + "targets": [ + { "datasource": { "type": "prometheus", "uid": "Prometheus" }, "expr": "garage_block_count", "legendFormat": "blocks {{ instance }}", "refId": "A" }, + { "datasource": { "type": "prometheus", "uid": "Prometheus" }, "expr": "garage_block_resync_queue_length", "legendFormat": "resync queue {{ instance }}", "refId": "B" } + ], + "title": "Garage blocks", + "type": "timeseries" + }, + { + "datasource": { "type": "prometheus", "uid": "Prometheus" }, + "fieldConfig": { + "defaults": { + "color": { "mode": "thresholds" }, + "mappings": [], + "thresholds": { "mode": "absolute", "steps": [ { "color": "green", "value": null }, { "color": "red", "value": 1 } ] } + }, + "overrides": [] + }, + "gridPos": { "h": 8, "w": 12, "x": 0, "y": 8 }, + "id": 4, + "options": { + "legend": { "calcs": [], "displayMode": "list", "placement": "bottom", "showLegend": true }, + "tooltip": { "mode": "multi", "sort": "none" } + }, + "targets": [ + { "datasource": { "type": "prometheus", "uid": "Prometheus" }, "expr": "garage_rpc_node_health_is_up", "legendFormat": "{{ instance }}", "refId": "A" } + ], + "title": "Garage RPC node health", + "type": "timeseries" + }, + { + "datasource": { "type": "prometheus", "uid": "Prometheus" }, + "fieldConfig": { + "defaults": { + "color": { "mode": "palette-classic" }, + "custom": { "axisCenteredZero": false, "axisColorMode": "text", "axisLabel": "", "axisPlacement": "auto", "drawStyle": "line", "fillOpacity": 10, "gradientMode": "none", "hideFrom": { "legend": false, "tooltip": false, "viz": false }, "lineInterpolation": "linear", "lineWidth": 1, "pointSize": 5, "scaleDistribution": { "type": "linear" }, "showPoints": "never", "spanNulls": false, "stacking": { "group": "A", "mode": "none" }, "thresholdsStyle": { "mode": "off" } }, + "mappings": [], + "thresholds": { "mode": "absolute", "steps": [ { "color": "green", "value": null } ] } + }, + "overrides": [] + }, + "gridPos": { "h": 8, "w": 12, "x": 12, "y": 8 }, + "id": 5, + "options": { + "legend": { "calcs": [], "displayMode": "list", "placement": "bottom", "showLegend": true }, + "tooltip": { "mode": "multi", "sort": "none" } + }, + "targets": [ + { "datasource": { "type": "prometheus", "uid": "Prometheus" }, "expr": "rate(garage_api_s3_request_counter[5m])", "legendFormat": "{{ instance }} {{ api_endpoint }}", "refId": "A" } + ], + "title": "S3 requests /sec", + "type": "timeseries" + } + ], + "refresh": "30s", + "schemaVersion": 39, + "tags": [ "garage" ], + "templating": { "list": [] }, + "time": { "from": "now-6h", "to": "now" }, + "timepicker": {}, + "timezone": "browser", + "title": "Garage Cluster", + "uid": "garage-cluster", + "version": 1, + "weekStart": "" +} \ No newline at end of file diff --git a/grafana/provisioning/dashboards/dashboards.yml b/grafana/provisioning/dashboards/dashboards.yml new file mode 100644 index 0000000..d0fbd2a --- /dev/null +++ b/grafana/provisioning/dashboards/dashboards.yml @@ -0,0 +1,11 @@ +apiVersion: 1 + +providers: + - name: 'garage-dashboards' + orgId: 1 + folder: 'Garage' + type: file + disableDeletion: false + updateIntervalSeconds: 30 + options: + path: /var/lib/grafana/dashboards \ No newline at end of file diff --git a/grafana/provisioning/datasources/datasources.yml b/grafana/provisioning/datasources/datasources.yml new file mode 100644 index 0000000..54f1c69 --- /dev/null +++ b/grafana/provisioning/datasources/datasources.yml @@ -0,0 +1,16 @@ +apiVersion: 1 + +datasources: + - name: Prometheus + type: prometheus + access: proxy + url: http://prometheus:9090 + isDefault: true + editable: true + + - name: Loki + type: loki + access: proxy + url: http://loki:3100 + isDefault: false + editable: true \ No newline at end of file diff --git a/prometheus.yml b/prometheus.yml new file mode 100644 index 0000000..fb16546 --- /dev/null +++ b/prometheus.yml @@ -0,0 +1,48 @@ +global: + scrape_interval: 15s + evaluation_interval: 15s + external_labels: + monitor: 'garage-cluster' + +rule_files: + - /etc/prometheus/alerts.yml + +scrape_configs: + # Garage node metrics (admin API on WG) + - job_name: 'garage' + metrics_path: /metrics + scheme: http + authorization: + type: Bearer + credentials: c213debe864061cefe501f7791d557b6dba701710b41791b4a4a0fb036690d1d + static_configs: + - targets: ['10.8.0.1:3903', '10.8.0.2:3903', '10.8.0.4:3903'] + labels: + cluster: garage + + # Health check for each node (returns 200 if quorum OK) + - job_name: 'garage_health' + metrics_path: /health + scheme: http + static_configs: + - targets: ['10.8.0.1:3903', '10.8.0.2:3903', '10.8.0.4:3903'] + labels: + cluster: garage + + # Node exporter on each host (system metrics) + - job_name: 'node' + static_configs: + - targets: ['10.8.0.2:9100'] + labels: + host: bigbox + - targets: ['10.8.0.1:9100'] + labels: + host: vps01 + - targets: ['10.8.0.4:9100'] + labels: + host: vps02 + + # Prometheus self + - job_name: 'prometheus' + static_configs: + - targets: ['localhost:9090'] \ No newline at end of file