← Все статьи

Смержено, засинкано, смонтировано — и всё равно не алертит: vmalert без hot reload

Новые правила для Kafka прошли через Git и Argo CD в ConfigMap, но vmalert их так и не начал оценивать. GitOps-конвейер оборвался на последнем шаге.

В Gambchamp правила алертов для всей платформы живут в Git-репозитории. Мерж через Argo CD с auto-sync попадает в ConfigMap, а vmalert — часть центрального observability-хаба на VictoriaMetrics — их оценивает. Однажды я смержил набор новых правил для Kafka: упавшие брокеры, under-replicated партиции, лаг консьюмеров и шторм ребалансов.

Argo CD засинкал. ConfigMap в кластере содержал новые правила. И ничего не произошло.

Доказательство, что правила не работают

Важна не проверка «правило есть в Git», а «движок его оценивает». Метрика ALERTS, которую vmalert пишет для каждого pending и firing алерта, по alertname=~"Kafka.*" давала ноль рядов. При этом сырое выражение правила, выполненное руками, возвращало 18 подходящих consumer group. Условие было истинным, просто правило не было загружено.

Причина

У этого vmalert, развёрнутого из стандартного чарта, не было sidecar’а config-reloader и флага -rule.configCheckInterval. ConfigMap с правилами смонтирован как volume. Kubelet обновляет файлы в этом volume, когда ConfigMap меняется, но vmalert читает файлы правил только при старте процесса. Без reloader или интервала проверки никто не сообщает ему, что файлы изменились.

Конвейер «мерж, синк, ConfigMap» отработал безупречно и остановился за шаг до финиша. Новые правила лежали на диске пода и до движка не доходили.

Немедленное исправление

Я перезапустил Deployment vmalert. При старте он прочитал все файлы правил, включая новые группы. 18 алертов про шторм ребалансов сразу ушли в pending, а после окна for: 15m — в firing, и панель алертов на дашборде сразу их показала.

У рестарта есть цена, которую стоит знать: он сбрасывает таймеры for: у всех правил флота, а не только у новых. Позже я нашёл способ мягче. vmalert принимает явный POST /-/reload, который перечитывает файлы правил без перезапуска процесса. Перечитываются только изменённые группы; нетронутые сохраняют своё состояние, и уже горящие алерты продолжают гореть. Для правки правил это правильный инструмент.

Долгосрочное исправление

Любое из двух изменений делает так, что GitOps-алерты активируются сами:

  • добавить -rule.configCheckInterval=30s, чтобы vmalert периодически перечитывал свои файлы, или
  • поставить sidecar config-reloader, который дёргает reload при каждом изменении ConfigMap.

Пока ни того, ни другого нет, каждый мерж в репозиторий алертов требует ручного reload.

Что вынести

  • «Правило смержено» — это не «правило работает». Подтверждай через ALERTS{alertname="X"}, что движок его видит — в pending или firing.
  • ConfigMap, смонтированный как volume, обновляет файлы, а не процесс. Проверь, следит ли потребитель за ними.
  • Для правки правил предпочитай явный reload рестарту: рестарт сбрасывает все таймеры for:.
  • Калибруй пороги для алертов на счётчиках по живым данным до мержа, чтобы новое правило не было ни мёртвым, ни шумным.