fix(observability): контейнерные метрики терялись целиком + два хвоста стека #3108
No reviewers
Labels
No labels
Fable 5 ревью
GG-форсайт
admin
analytics
auth
automation
bug
business
chore
ci
compliance
data
data-moat
docs
duplicate
dx
enhancement
feedback/max
generative
needs-discussion
needs-human
observability
pause-bots
performance
priority/p0
priority/p1
priority/p2
priority/p3
scope/backend
scope/db
scope/devops
scope/frontend
scope/qa
scrapers
security
site-finder
stage/1
stage/2
status/blocked
status/done
status/needs-analysis
status/needs-fix
status/qa
status/ready
status/review
status/wip
tech-debt
tradein
ux
week ревью 1
wontfix
ИРД
вторичка
No milestone
No project
No assignees
1 participant
Notifications
Due date
No due date set.
Dependencies
No dependencies set.
Reference: lekss361/gendesign#3108
Loading…
Add table
Reference in a new issue
No description provided.
Delete branch "fix/metrics-cadvisor-drop"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Три независимых дефекта, найденных на живом проде после того, как стек метрик поднялся (#3106). Симптом, с которого начали, — «в метриках нодата».
1. cAdvisor-метрики не доезжали ВООБЩЕ (главное)
Замер на живом Prometheus: ноль имён
container_*при 2034 именах метрик всего.При этом всё звено выглядело здоровым:
container_*health = up,last_scrape10 мс назадprometheus.scrape.cadvisor/prometheus.relabel.cadvisor_trimhealthynode/postgresидут через него же и доезжают__name__Методом исключения остаётся второе правило в
cadvisor_trim:Замысел был выкинуть безымянные cgroup-ряды (
id="/"). Ноregexв Alloy документированно дефолтится в(.*), а пустая строка неотличима от незаданного значения — такойdropрискует выкидывать вообще всё, что и наблюдается.Заменено на однозначное
keep regex=".+"— тот же замысел, но результат не зависит от того, как трактуется пустой regex.Честно: сам механизм (пустой regex →
(.*)) я не доказал — в доках Alloy этот случай прямо не описан. Правка выбрана так, чтобы быть верной при любой из трактовок.2. healthcheck alloy не мог пройти никогда
test: wget -q --spider …, а в образеgrafana/alloyнет ниwget, ниcurl, ниnc— провереноcommand -vна живом контейнере. Итог: контейнер вечноunhealthyпри полностью исправном alloy (все 10 компонентовhealthy). Ложная тревога, которая маскирует настоящие сбои.Заменено на сырой HTTP через
bash /dev/tcp— без внешних утилит.3. Prometheus раз в минуту ругался на отсутствующий alertmanager
lookup alertmanager: no such host+up{job="alertmanager"}=0.Alertmanager намеренно за профилем
alertsдо решения #3078 по каналу доставки — профиль не трогаю, это не дефект. Дефект в том, чтоprometheus.ymlссылался на сервис безусловно.Оба места (
alerting.alertmanagersиjob_name: alertmanager) переведены наfile_sd_configsс файлом целей, по умолчанию пустым ([]): целей нет — ошибок разрешения имени тоже нет. Prometheus перечитывает file_sd на лету, поэтому включение профиля сведётся к наполнению файла — без рестарта и без правки этого конфига.Файл целей смонтирован в сервис
prometheusявным volume — с учётом того, что ровно забытый монт сегодня уже положил Caddy (#3103).Проверка — на живом хосте, не на глаз
Механизм нового healthcheck выполнен внутри работающего
gendesign-alloy:Наличие
bash/head/grep/printfв образе подтвержденоcommand -v— чтобы не повторить ровно ту ошибку, которую чиним пунктом 2.После мёрджа
Проверить, что
count(container_last_seen)перестал быть пустым иgendesign-alloyушёл изunhealthy.Три независимых дефекта, найденных на живом проде после подъёма стека метрик. 1. cAdvisor-метрики не доезжали ВООБЩЕ. В Prometheus ноль имён container_* при 2034 именах всего, хотя cAdvisor отдаёт 880 рядов, scrape-таргет в alloy health=up с последним скрейпом 10 мс назад, а remote_write рабочий (node/postgres идут через него же и доезжают). Методом исключения — потери в prometheus.relabel.cadvisor_trim, во втором правиле: rule { source_labels = ["name"], regex = "", action = "drop" } Замысел был выкинуть безымянные cgroup-ряды (id="/"). Но regex в Alloy документированно дефолтится в (.*), и пустая строка неотличима от незаданного значения — такой drop рискует выкидывать вообще всё, что и наблюдалось. Заменено на однозначное keep regex=".+" — тот же замысел, без зависимости от того, как трактуется пустой regex. 2. healthcheck alloy не мог пройти никогда: дёргал wget, которого в образе grafana/alloy нет (как и curl, и nc). Контейнер вечно unhealthy при полностью исправном alloy — ложная тревога, маскирующая настоящие сбои. Заменено на сырой HTTP через bash /dev/tcp, без внешних утилит. 3. Prometheus раз в минуту писал "lookup alertmanager: no such host" и держал up{job="alertmanager"}=0. Alertmanager намеренно за профилем alerts до решения #3078 — дефект не в профиле, а в безусловной ссылке на сервис. Оба места (alerting.alertmanagers и job_name: alertmanager) переведены на file_sd_configs с файлом целей, по умолчанию пустым: целей нет — ошибок тоже нет. Prometheus перечитывает file_sd на лету, поэтому включение профиля сведётся к наполнению файла, без рестарта и правки конфига. Файл целей смонтирован в сервис prometheus явным volume. Проверено на живом хосте, не на глаз: - alloy fmt обоих .alloy в одноразовом контейнере grafana/alloy:v1.6.1 - exit 0 - promtool check config в prom/prometheus:v3.1.0 - valid, 16 rules found - механизм нового healthcheck выполнен внутри работающего gendesign-alloy: первая строка ответа "HTTP/1.0 200 OK", grep матчится, RESULT=HEALTHY - наличие bash/head/grep/printf в образе alloy подтверждено command -v