fix(monitoring): убрать cAdvisor — несовместим с containerd-снапшоттером
Some checks failed
CI / backend (push) Has been cancelled
CI / frontend (push) Has been cancelled

На сервере 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:
2026-07-28 00:42:25 +03:00
parent 54fd1a26d7
commit 7f5c88869a
6 changed files with 48 additions and 111 deletions

View File

@@ -734,42 +734,17 @@ services:
profiles: ["monitoring"]
logging: *default-logging
cadvisor:
# Метрики по контейнерам (CPU/память каждого) — отвечает на вопрос
# «какой из контейнеров ест ресурсы», в отличие от node-exporter
# (только хост целиком). Дороже node-exporter по CPU/RAM (собственные
# ~60-120 МБ RSS + периодический обход cgroups) — на сервере 8 ГБ/4 CPU
# с ~13 контейнерами это приемлемо, но не бесплатно; `--docker_only`
# и `--disable_metrics` ниже отключают часть коллекторов сверх дефолта
# cAdvisor (который уже отключает cpu_topology/hugetlb/memory_numa/
# process/sched/tcp/udp и т.п.) — здесь дополнительно per-core CPU,
# perf_event и дисковые метрики (диск и так покрыт 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
# cAdvisor сознательно НЕ используется: несовместим с Docker Engine на
# сервере `1gb` (containerd-снапшоттер вместо классического overlay2 —
# `docker info` показывает `driver-type: io.containerd.snapshotter.v1`).
# cAdvisor (проверено на v0.49.2 и v0.52.1) не может определить
# read-write layer контейнеров через ни docker.sock, ни напрямую через
# `--containerd`/`--containerd-namespace=moby` — падает с
# «failed to identify the read-write layer ID», отдаёт метрики только по
# корневому cgroup, без разбивки по контейнерам. Открытая проблема
# совместимости cAdvisor с containerd image store, не чинится флагами —
# см. `.forcc/JOURNAL.md` за детали и альтернативы. node-exporter
# (сервис выше) метрики хоста при этом покрывает полностью.
grafana:
image: grafana/grafana:13.1.0

View File

@@ -80,8 +80,10 @@ groups:
summary: "Мало свободной памяти на хосте"
description: >-
Свободно {{ $value | printf "%.1f" }}% RAM дольше 10 минут
(порог 10% ≈ 800 МБ из 8 ГБ). Смотреть, какой контейнер ест
память — дашборд «Хост и контейнеры», топ по памяти (cAdvisor).
(порог 10% ≈ 800 МБ из 8 ГБ). Разбивки по контейнерам в Grafana
нет (cAdvisor несовместим с containerd-снапшоттером на этом
сервере, см. deploy/docker-compose.yml) — смотреть вручную,
например `docker stats`.
# 50 ГБ диска — 10% ≈ 5 ГБ. `for: 15m` (не мгновенно): диск не растёт
# так же резко, как память, ложные срабатывания на всплеск не грозят,
@@ -112,6 +114,6 @@ groups:
summary: "Устойчиво высокая загрузка CPU хоста"
description: >-
Загрузка CPU {{ $value | printf "%.1f" }}% дольше 15 минут
подряд (порог 90% из 4 ядер). Смотреть топ контейнеров по CPU
(дашборд «Хост и контейнеры», cAdvisor) и латентность API —
возможно, не хватает уровня AI/ресурсов под нагрузку.
подряд (порог 90% из 4 ядер). Разбивки по контейнерам в Grafana
нет (см. HostMemoryLow) — смотреть `docker stats` и латентность
API — возможно, не хватает уровня AI/ресурсов под нагрузку.

View File

@@ -1,6 +1,6 @@
{
"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",
"editable": false,
"timezone": "browser",
@@ -180,7 +180,7 @@
"title": "Сетевой трафик",
"description": "rx/tx по физическим интерфейсам хоста (исключены lo/veth/docker/br — это внутренние интерфейсы контейнеров, а не реальный сетевой трафик сервера).",
"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" },
"fieldConfig": {
"defaults": { "unit": "Bps", "custom": { "drawStyle": "line", "fillOpacity": 5 } },
@@ -200,46 +200,6 @@
"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"
}
]
}
]
}

View File

@@ -1,7 +1,7 @@
# Конфигурация Prometheus (devops) — сбор метрик backend,
# PostgreSQL, Redis, железа хоста, контейнеров и локального LLM-сервера.
# Поднимается compose-профилем `monitoring` (deploy/docker-compose.yml,
# сервис `prometheus`).
# PostgreSQL, Redis, железа хоста и локального LLM-сервера. Поднимается
# compose-профилем `monitoring` (deploy/docker-compose.yml, сервис
# `prometheus`).
#
# Имена метрик backend (`vidconf_http_request_duration_seconds`,
# `vidconf_pipeline_sessions`, `vidconf_celery_queue_depth`) — КОНТРАКТ с
@@ -42,14 +42,6 @@ scrape_configs:
static_configs:
- 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:8080` разрешается ОДНИМ из двух compose-сервисов в зависимости от
# выбранного при установке пресета — `llm` (CPU, профиль `llm`, уровни