fix(monitoring): убрать cAdvisor — несовместим с containerd-снапшоттером
На сервере 1gb Docker Engine использует containerd-снапшоттер (driver-type: io.containerd.snapshotter.v1), а не классический overlay2. cAdvisor (проверено на v0.49.2 и свежей v0.52.1, с --docker_only и через --containerd/--containerd-namespace=moby) не может определить read-write layer контейнеров — падает с «failed to identify the read-write layer ID», метрики только по корневому cgroup, без разбивки по контейнерам. Открытая проблема совместимости, флагами не решается. Убран сервис cadvisor, job в prometheus.yml, панели «топ контейнеров» в host.json (Prometheus иначе резолвит cadvisor:8080 в никуда — Grafana показывала бы «No data» вечно). node-exporter метрики хоста (CPU/RAM/ диск/сеть) при этом покрывает полностью, без изменений. Правка конфигурации мониторинга, без изменения пользовательского поведения — версия не бампается.
This commit is contained in:
14
CHANGELOG.md
14
CHANGELOG.md
@@ -5,15 +5,17 @@
|
|||||||
|
|
||||||
## [0.0.9] — 2026-07-28
|
## [0.0.9] — 2026-07-28
|
||||||
|
|
||||||
Метрики CPU/RAM/диска хоста и контейнеров в Grafana; дефолтные подвкладки
|
Метрики CPU/RAM/диска хоста в Grafana; дефолтные подвкладки конференций и
|
||||||
конференций и пользователей в админке.
|
пользователей в админке.
|
||||||
|
|
||||||
### Добавлено
|
### Добавлено
|
||||||
- Мониторинг железа: `node-exporter` (CPU/RAM/диск/сеть/load average хоста)
|
- Мониторинг железа: `node-exporter` (CPU/RAM/диск/сеть/load average хоста)
|
||||||
и `cAdvisor` (метрики по каждому контейнеру) — профиль compose
|
— профиль compose `monitoring`, без публикации портов наружу. Новый
|
||||||
`monitoring`, без публикации портов наружу. Новый дашборд Grafana «Хост и
|
дашборд Grafana «Хост и контейнеры». Три новых алерта Prometheus:
|
||||||
контейнеры». Три новых алерта Prometheus: `HostMemoryLow`, `HostDiskLow`,
|
`HostMemoryLow`, `HostDiskLow`, `HostCpuHigh` (пороги — под сервер `1gb`:
|
||||||
`HostCpuHigh` (пороги — под сервер `1gb`: 8 ГБ RAM, 4 CPU, 50 ГБ диска).
|
8 ГБ RAM, 4 CPU, 50 ГБ диска). `cAdvisor` (разбивка по контейнерам)
|
||||||
|
сознательно не включён — несовместим с containerd-снапшоттером Docker
|
||||||
|
Engine на `1gb`, см. `docs/deploy/monitoring.md`.
|
||||||
|
|
||||||
### Изменено
|
### Изменено
|
||||||
- Админка, вкладка «Конференции»: вкладка «Все» перенесена в конец списка
|
- Админка, вкладка «Конференции»: вкладка «Все» перенесена в конец списка
|
||||||
|
|||||||
@@ -734,42 +734,17 @@ services:
|
|||||||
profiles: ["monitoring"]
|
profiles: ["monitoring"]
|
||||||
logging: *default-logging
|
logging: *default-logging
|
||||||
|
|
||||||
cadvisor:
|
# cAdvisor сознательно НЕ используется: несовместим с Docker Engine на
|
||||||
# Метрики по контейнерам (CPU/память каждого) — отвечает на вопрос
|
# сервере `1gb` (containerd-снапшоттер вместо классического overlay2 —
|
||||||
# «какой из контейнеров ест ресурсы», в отличие от node-exporter
|
# `docker info` показывает `driver-type: io.containerd.snapshotter.v1`).
|
||||||
# (только хост целиком). Дороже node-exporter по CPU/RAM (собственные
|
# cAdvisor (проверено на v0.49.2 и v0.52.1) не может определить
|
||||||
# ~60-120 МБ RSS + периодический обход cgroups) — на сервере 8 ГБ/4 CPU
|
# read-write layer контейнеров через ни docker.sock, ни напрямую через
|
||||||
# с ~13 контейнерами это приемлемо, но не бесплатно; `--docker_only`
|
# `--containerd`/`--containerd-namespace=moby` — падает с
|
||||||
# и `--disable_metrics` ниже отключают часть коллекторов сверх дефолта
|
# «failed to identify the read-write layer ID», отдаёт метрики только по
|
||||||
# cAdvisor (который уже отключает cpu_topology/hugetlb/memory_numa/
|
# корневому cgroup, без разбивки по контейнерам. Открытая проблема
|
||||||
# process/sched/tcp/udp и т.п.) — здесь дополнительно per-core CPU,
|
# совместимости cAdvisor с containerd image store, не чинится флагами —
|
||||||
# perf_event и дисковые метрики (диск и так покрыт node-exporter'ом,
|
# см. `.forcc/JOURNAL.md` за детали и альтернативы. node-exporter
|
||||||
# дублировать через cAdvisor незачем). Список допустимых значений —
|
# (сервис выше) метрики хоста при этом покрывает полностью.
|
||||||
# `cadvisor -help` (в версии образа меняется, не все имена стабильны
|
|
||||||
# между релизами — при апгрейде образа сверяться с `-help`).
|
|
||||||
image: gcr.io/cadvisor/cadvisor:v0.49.2
|
|
||||||
restart: unless-stopped
|
|
||||||
volumes:
|
|
||||||
- /:/rootfs:ro
|
|
||||||
- /var/run:/var/run:ro
|
|
||||||
- /sys:/sys:ro
|
|
||||||
- /var/lib/docker/:/var/lib/docker:ro
|
|
||||||
# Только чтение — cAdvisor не должен иметь возможность управлять
|
|
||||||
# контейнерами, ему нужен только список и статистика.
|
|
||||||
- /var/run/docker.sock:/var/run/docker.sock:ro
|
|
||||||
command:
|
|
||||||
- '--docker_only=true'
|
|
||||||
- '--disable_metrics=percpu,perf_event,diskIO,disk,app'
|
|
||||||
# Без ports вообще — тот же принцип, что и у node-exporter: Prometheus
|
|
||||||
# достаёт метрики по имени сервиса (`cadvisor:8080`) внутри сети compose.
|
|
||||||
healthcheck:
|
|
||||||
test: ["CMD-SHELL", "wget -q -O- http://127.0.0.1:8080/healthz >/dev/null || exit 1"]
|
|
||||||
interval: 10s
|
|
||||||
timeout: 5s
|
|
||||||
retries: 10
|
|
||||||
start_period: 15s
|
|
||||||
profiles: ["monitoring"]
|
|
||||||
logging: *default-logging
|
|
||||||
|
|
||||||
grafana:
|
grafana:
|
||||||
image: grafana/grafana:13.1.0
|
image: grafana/grafana:13.1.0
|
||||||
|
|||||||
@@ -80,8 +80,10 @@ groups:
|
|||||||
summary: "Мало свободной памяти на хосте"
|
summary: "Мало свободной памяти на хосте"
|
||||||
description: >-
|
description: >-
|
||||||
Свободно {{ $value | printf "%.1f" }}% RAM дольше 10 минут
|
Свободно {{ $value | printf "%.1f" }}% RAM дольше 10 минут
|
||||||
(порог 10% ≈ 800 МБ из 8 ГБ). Смотреть, какой контейнер ест
|
(порог 10% ≈ 800 МБ из 8 ГБ). Разбивки по контейнерам в Grafana
|
||||||
память — дашборд «Хост и контейнеры», топ по памяти (cAdvisor).
|
нет (cAdvisor несовместим с containerd-снапшоттером на этом
|
||||||
|
сервере, см. deploy/docker-compose.yml) — смотреть вручную,
|
||||||
|
например `docker stats`.
|
||||||
|
|
||||||
# 50 ГБ диска — 10% ≈ 5 ГБ. `for: 15m` (не мгновенно): диск не растёт
|
# 50 ГБ диска — 10% ≈ 5 ГБ. `for: 15m` (не мгновенно): диск не растёт
|
||||||
# так же резко, как память, ложные срабатывания на всплеск не грозят,
|
# так же резко, как память, ложные срабатывания на всплеск не грозят,
|
||||||
@@ -112,6 +114,6 @@ groups:
|
|||||||
summary: "Устойчиво высокая загрузка CPU хоста"
|
summary: "Устойчиво высокая загрузка CPU хоста"
|
||||||
description: >-
|
description: >-
|
||||||
Загрузка CPU {{ $value | printf "%.1f" }}% дольше 15 минут
|
Загрузка CPU {{ $value | printf "%.1f" }}% дольше 15 минут
|
||||||
подряд (порог 90% из 4 ядер). Смотреть топ контейнеров по CPU
|
подряд (порог 90% из 4 ядер). Разбивки по контейнерам в Grafana
|
||||||
(дашборд «Хост и контейнеры», cAdvisor) и латентность API —
|
нет (см. HostMemoryLow) — смотреть `docker stats` и латентность
|
||||||
возможно, не хватает уровня AI/ресурсов под нагрузку.
|
API — возможно, не хватает уровня AI/ресурсов под нагрузку.
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"title": "Хост и контейнеры",
|
"title": "Хост и контейнеры",
|
||||||
"description": "CPU/RAM/диск/сеть хоста (node-exporter) и разбивка по контейнерам (cAdvisor) — профиль compose monitoring. Пороги на панелях согласованы с deploy/monitoring/alerts.yml (группа vidconf-host).",
|
"description": "CPU/RAM/диск/сеть хоста (node-exporter) — профиль compose monitoring. Пороги на панелях согласованы с deploy/monitoring/alerts.yml (группа vidconf-host). Разбивки по контейнерам нет: cAdvisor несовместим с containerd-снапшоттером Docker Engine на сервере 1gb (см. комментарий у сервиса cadvisor в deploy/docker-compose.yml и .forcc/JOURNAL.md) — вручную смотреть `docker stats`.",
|
||||||
"uid": "vidconf-host",
|
"uid": "vidconf-host",
|
||||||
"editable": false,
|
"editable": false,
|
||||||
"timezone": "browser",
|
"timezone": "browser",
|
||||||
@@ -180,7 +180,7 @@
|
|||||||
"title": "Сетевой трафик",
|
"title": "Сетевой трафик",
|
||||||
"description": "rx/tx по физическим интерфейсам хоста (исключены lo/veth/docker/br — это внутренние интерфейсы контейнеров, а не реальный сетевой трафик сервера).",
|
"description": "rx/tx по физическим интерфейсам хоста (исключены lo/veth/docker/br — это внутренние интерфейсы контейнеров, а не реальный сетевой трафик сервера).",
|
||||||
"type": "timeseries",
|
"type": "timeseries",
|
||||||
"gridPos": { "h": 8, "w": 12, "x": 0, "y": 20 },
|
"gridPos": { "h": 8, "w": 24, "x": 0, "y": 20 },
|
||||||
"datasource": { "type": "prometheus", "uid": "prometheus" },
|
"datasource": { "type": "prometheus", "uid": "prometheus" },
|
||||||
"fieldConfig": {
|
"fieldConfig": {
|
||||||
"defaults": { "unit": "Bps", "custom": { "drawStyle": "line", "fillOpacity": 5 } },
|
"defaults": { "unit": "Bps", "custom": { "drawStyle": "line", "fillOpacity": 5 } },
|
||||||
@@ -200,46 +200,6 @@
|
|||||||
"refId": "B"
|
"refId": "B"
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
},
|
|
||||||
{
|
|
||||||
"id": 10,
|
|
||||||
"title": "Топ контейнеров по CPU",
|
|
||||||
"description": "Источник — cAdvisor (job cadvisor). Отвечает на вопрос «кто из контейнеров грузит CPU» при срабатывании HostCpuHigh.",
|
|
||||||
"type": "timeseries",
|
|
||||||
"gridPos": { "h": 8, "w": 12, "x": 12, "y": 20 },
|
|
||||||
"datasource": { "type": "prometheus", "uid": "prometheus" },
|
|
||||||
"fieldConfig": {
|
|
||||||
"defaults": { "unit": "percentunit", "custom": { "drawStyle": "line", "fillOpacity": 10, "stacking": { "mode": "normal" } } },
|
|
||||||
"overrides": []
|
|
||||||
},
|
|
||||||
"targets": [
|
|
||||||
{
|
|
||||||
"datasource": { "type": "prometheus", "uid": "prometheus" },
|
|
||||||
"expr": "topk(5, sum by (name) (rate(container_cpu_usage_seconds_total{name!=\"\"}[5m])))",
|
|
||||||
"legendFormat": "{{name}}",
|
|
||||||
"refId": "A"
|
|
||||||
}
|
|
||||||
]
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"id": 11,
|
|
||||||
"title": "Топ контейнеров по памяти",
|
|
||||||
"description": "container_memory_working_set_bytes — это то, что реально учитывает cgroup OOM killer (в отличие от RSS), источник — cAdvisor.",
|
|
||||||
"type": "timeseries",
|
|
||||||
"gridPos": { "h": 8, "w": 24, "x": 0, "y": 28 },
|
|
||||||
"datasource": { "type": "prometheus", "uid": "prometheus" },
|
|
||||||
"fieldConfig": {
|
|
||||||
"defaults": { "unit": "decbytes", "custom": { "drawStyle": "line", "fillOpacity": 10, "stacking": { "mode": "normal" } } },
|
|
||||||
"overrides": []
|
|
||||||
},
|
|
||||||
"targets": [
|
|
||||||
{
|
|
||||||
"datasource": { "type": "prometheus", "uid": "prometheus" },
|
|
||||||
"expr": "topk(5, container_memory_working_set_bytes{name!=\"\"})",
|
|
||||||
"legendFormat": "{{name}}",
|
|
||||||
"refId": "A"
|
|
||||||
}
|
|
||||||
]
|
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
# Конфигурация Prometheus (devops) — сбор метрик backend,
|
# Конфигурация Prometheus (devops) — сбор метрик backend,
|
||||||
# PostgreSQL, Redis, железа хоста, контейнеров и локального LLM-сервера.
|
# PostgreSQL, Redis, железа хоста и локального LLM-сервера. Поднимается
|
||||||
# Поднимается compose-профилем `monitoring` (deploy/docker-compose.yml,
|
# compose-профилем `monitoring` (deploy/docker-compose.yml, сервис
|
||||||
# сервис `prometheus`).
|
# `prometheus`).
|
||||||
#
|
#
|
||||||
# Имена метрик backend (`vidconf_http_request_duration_seconds`,
|
# Имена метрик backend (`vidconf_http_request_duration_seconds`,
|
||||||
# `vidconf_pipeline_sessions`, `vidconf_celery_queue_depth`) — КОНТРАКТ с
|
# `vidconf_pipeline_sessions`, `vidconf_celery_queue_depth`) — КОНТРАКТ с
|
||||||
@@ -42,14 +42,6 @@ scrape_configs:
|
|||||||
static_configs:
|
static_configs:
|
||||||
- targets: ["node-exporter:9100"]
|
- targets: ["node-exporter:9100"]
|
||||||
|
|
||||||
# Метрики по каждому контейнеру (CPU/память отдельно у backend, worker,
|
|
||||||
# postgres и т.д. — профиль monitoring, сервис cadvisor). Отвечает на
|
|
||||||
# вопрос «какой из контейнеров ест ресурсы», в отличие от job `node`
|
|
||||||
# (только хост целиком).
|
|
||||||
- job_name: cadvisor
|
|
||||||
static_configs:
|
|
||||||
- targets: ["cadvisor:8080"]
|
|
||||||
|
|
||||||
# Локальный LLM-сервер (llama.cpp, LLAMA_ARG_ENDPOINT_METRICS=1). Адрес
|
# Локальный LLM-сервер (llama.cpp, LLAMA_ARG_ENDPOINT_METRICS=1). Адрес
|
||||||
# `llm:8080` разрешается ОДНИМ из двух compose-сервисов в зависимости от
|
# `llm:8080` разрешается ОДНИМ из двух compose-сервисов в зависимости от
|
||||||
# выбранного при установке пресета — `llm` (CPU, профиль `llm`, уровни
|
# выбранного при установке пресета — `llm` (CPU, профиль `llm`, уровни
|
||||||
|
|||||||
@@ -11,19 +11,25 @@
|
|||||||
| `postgres-exporter` | `quay.io/prometheuscommunity/postgres-exporter:v0.20.1` | — (внутренний) | метрики PostgreSQL |
|
| `postgres-exporter` | `quay.io/prometheuscommunity/postgres-exporter:v0.20.1` | — (внутренний) | метрики PostgreSQL |
|
||||||
| `redis-exporter` | `oliver006/redis_exporter:v1.87.0-alpine` | — (внутренний) | метрики Redis |
|
| `redis-exporter` | `oliver006/redis_exporter:v1.87.0-alpine` | — (внутренний) | метрики Redis |
|
||||||
| `node-exporter` | `prom/node-exporter:v1.8.2` | — (внутренний) | метрики хоста: CPU, память, диск, сеть, load average |
|
| `node-exporter` | `prom/node-exporter:v1.8.2` | — (внутренний) | метрики хоста: CPU, память, диск, сеть, load average |
|
||||||
| `cadvisor` | `gcr.io/cadvisor/cadvisor:v0.49.2` | — (внутренний) | метрики по каждому контейнеру (CPU/память) |
|
|
||||||
| `grafana` | `grafana/grafana:13.1.0` | `3001` (внутри контейнера `3000`) | дашборды «Пайплайны пост-обработки» и «Хост и контейнеры» |
|
| `grafana` | `grafana/grafana:13.1.0` | `3001` (внутри контейнера `3000`) | дашборды «Пайплайны пост-обработки» и «Хост и контейнеры» |
|
||||||
|
|
||||||
`node-exporter`/`cadvisor` не публикуют порт на хост вообще (не только
|
`node-exporter` не публикует порт на хост вообще (не только 127.0.0.1) —
|
||||||
127.0.0.1) — Prometheus ходит к ним по имени сервиса во внутренней сети
|
Prometheus ходит к нему по имени сервиса во внутренней сети compose,
|
||||||
compose, публикация на хост для этого не нужна. `cadvisor` смонтирован
|
публикация на хост для этого не нужна.
|
||||||
к `/var/run/docker.sock` только на чтение (`:ro`) и запущен с
|
|
||||||
`--docker_only` + урезанным набором коллекторов (`--disable_metrics`) —
|
**cAdvisor сознательно не используется** (разбивки метрик по контейнерам
|
||||||
он заметно дороже `node-exporter` по CPU/RAM, урезание снижает накладные
|
в Grafana нет): Docker Engine на сервере `1gb` использует
|
||||||
расходы. Если на конкретном сервере это всё равно избыточно —
|
containerd-снапшоттер (`docker info` → `driver-type:
|
||||||
`cadvisor` можно убрать из `deploy/docker-compose.yml`, оставив только
|
io.containerd.snapshotter.v1`), а не классический overlay2-драйвер, и
|
||||||
`node-exporter` (метрики хоста при этом не пострадают, пропадёт только
|
cAdvisor (проверено на v0.49.2 и v0.52.1, с `--docker_only` и без, через
|
||||||
разбивка по контейнерам).
|
`--containerd`/`--containerd-namespace=moby` и без) не может определить
|
||||||
|
read-write layer контейнеров — падает с «failed to identify the
|
||||||
|
read-write layer ID», метрики есть только по корневому cgroup. Открытая
|
||||||
|
проблема совместимости cAdvisor с containerd image store, флагами не
|
||||||
|
чинится — см. `.forcc/JOURNAL.md`. Если на другом сервере используется
|
||||||
|
классический overlay2, cAdvisor можно добавить обратно по тому же
|
||||||
|
образцу, что и `node-exporter` (job `cadvisor` в `prometheus.yml`,
|
||||||
|
таргет `cadvisor:8080`, без публикации портов).
|
||||||
|
|
||||||
Файлы: `deploy/monitoring/prometheus.yml`, `deploy/monitoring/alerts.yml`,
|
Файлы: `deploy/monitoring/prometheus.yml`, `deploy/monitoring/alerts.yml`,
|
||||||
`deploy/monitoring/grafana/provisioning/` (datasource + провайдер
|
`deploy/monitoring/grafana/provisioning/` (datasource + провайдер
|
||||||
|
|||||||
Reference in New Issue
Block a user