fix(ops/metrics): правки конфига Alertmanager молча не доезжали до контейнера #3142

Merged
lekss361 merged 1 commit from fix/3xxx-alertmanager-stale-inode into main 2026-08-27 12:29:55 +00:00
Owner

Пойман на проде 27.08 сразу после мержа #3136 — при проверке, что кнопка «Принял в работу» действительно встала в маршрут.

Симптом

На диске лежал новый конфиг, amtool check-config его одобрил, деплой зелёный. А контейнер продолжал слать алерты напрямую в Telegram:

на диске:       - name: telegram-clients
                  webhook_configs:
                    - url: "http://alert-ack:8080/alertmanager"

в контейнере:   - name: telegram-clients
                  telegram_configs:

Причина

Конфиг подключён бинд-маунтом файла, а рендер в деплое делает rm и создаёт файл заново. Иначе никак: после chown файл принадлежит 65534 с правами 600, а каталог — деплой-пользователю, поэтому пересоздать он может, а перезаписать — нет.

rm + создание даёт новый инод. Открытый дескриптор внутри работающего контейнера продолжает смотреть на прежний, уже удалённый. up -d контейнер при этом не трогает: он сравнивает описание сервиса, а содержимое бинд-маунта в сравнение не входит.

Отказ полностью беззвучный — ни одного красного признака ни в деплое, ни в проверке конфига, ни в состоянии контейнера. Значит и все прежние правки маршрутизации применялись лишь тогда, когда контейнер пересоздавался по какой-то другой причине.

Перезагрузка по SIGHUP/API не лечит: она перечитывает тот же самый открытый инод. Лечит только пересоздание контейнера.

Правка

Флаг ALERTMANAGER_RERENDERED=1 и пересоздание после up -d.

Два свойства, которые я счёл обязательными и закрепил тестами:

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

Флаг выставляется ПОСЛЕ amtool check-config, а не до. При обратном порядке битый конфиг пересоздавал бы живой контейнер и ронял алертинг целиком — вместо того, чтобы оставить работать прежний. Это ровно тот случай, когда «починка» опаснее болезни, поэтому порядок проверяется отдельным тестом.

Прод уже приведён в соответствие

Контейнер пересоздал вручную, проверил после:

- name: telegram-clients
  webhook_configs:
    - url: "http://alert-ack:8080/alertmanager"

gendesign-alert-ackUp, healthy, /healthz отдаёт 200. Маршрут клиентских инцидентов теперь действительно идёт через кнопку. Эта правка нужна, чтобы следующая правка конфига доехала сама.

Проверка

$ uv run python -m pytest tests/ops/ -q
78 passed

$ uv run ruff check tests/ops/test_3xxx_alertmanager_inode.py
All checks passed!

Refs #3078, #3136

Пойман на проде 27.08 сразу после мержа #3136 — при проверке, что кнопка «Принял в работу» действительно встала в маршрут. ## Симптом На диске лежал новый конфиг, `amtool check-config` его одобрил, деплой зелёный. А контейнер продолжал слать алерты напрямую в Telegram: ``` на диске: - name: telegram-clients webhook_configs: - url: "http://alert-ack:8080/alertmanager" в контейнере: - name: telegram-clients telegram_configs: ``` ## Причина Конфиг подключён бинд-маунтом **файла**, а рендер в деплое делает `rm` и создаёт файл заново. Иначе никак: после `chown` файл принадлежит `65534` с правами `600`, а каталог — деплой-пользователю, поэтому пересоздать он может, а перезаписать — нет. `rm` + создание даёт **новый инод**. Открытый дескриптор внутри работающего контейнера продолжает смотреть на прежний, уже удалённый. `up -d` контейнер при этом не трогает: он сравнивает описание сервиса, а содержимое бинд-маунта в сравнение не входит. Отказ полностью беззвучный — ни одного красного признака ни в деплое, ни в проверке конфига, ни в состоянии контейнера. **Значит и все прежние правки маршрутизации применялись лишь тогда, когда контейнер пересоздавался по какой-то другой причине.** Перезагрузка по SIGHUP/API не лечит: она перечитывает тот же самый открытый инод. Лечит только пересоздание контейнера. ## Правка Флаг `ALERTMANAGER_RERENDERED=1` и пересоздание после `up -d`. Два свойства, которые я счёл обязательными и закрепил тестами: **Пересоздание закрыто проверкой флага.** Безусловное рвало бы доставку алертов на каждом деплое метрик, включая те, где конфиг не менялся. **Флаг выставляется ПОСЛЕ `amtool check-config`, а не до.** При обратном порядке битый конфиг пересоздавал бы живой контейнер и ронял алертинг целиком — вместо того, чтобы оставить работать прежний. Это ровно тот случай, когда «починка» опаснее болезни, поэтому порядок проверяется отдельным тестом. ## Прод уже приведён в соответствие Контейнер пересоздал вручную, проверил после: ``` - name: telegram-clients webhook_configs: - url: "http://alert-ack:8080/alertmanager" ``` `gendesign-alert-ack` — `Up, healthy`, `/healthz` отдаёт 200. Маршрут клиентских инцидентов теперь действительно идёт через кнопку. Эта правка нужна, чтобы **следующая** правка конфига доехала сама. ## Проверка ``` $ uv run python -m pytest tests/ops/ -q 78 passed $ uv run ruff check tests/ops/test_3xxx_alertmanager_inode.py All checks passed! ``` Refs #3078, #3136
lekss361 added 1 commit 2026-08-27 12:10:48 +00:00
fix(ops/metrics): правки конфига Alertmanager молча не доезжали до контейнера
All checks were successful
CI Trade-In / changes (pull_request) Successful in 9s
CI Trade-In / backend-tests (pull_request) Has been skipped
CI / changes (pull_request) Successful in 11s
CI Trade-In / browser-tests (pull_request) Has been skipped
CI Trade-In / frontend-checks (pull_request) Has been skipped
CI / frontend-tests (pull_request) Has been skipped
CI / openapi-codegen-check (pull_request) Successful in 2m0s
CI / backend-tests (pull_request) Successful in 17m28s
5ea05cffa6
Пойман на проде 27.08 сразу после мержа #3136. На диске лежал новый конфиг —
`webhook_configs` на сервис кнопки подтверждения, — `amtool check-config` его
одобрил, деплой зелёный. А контейнер продолжал слать алерты напрямую:

    на диске:     webhook_configs: url http://alert-ack:8080/alertmanager
    в контейнере: telegram_configs:

Конфиг подключён бинд-маунтом ФАЙЛА, а рендер делает `rm` и создаёт файл
заново — иначе не перезаписать: после chown он принадлежит 65534 с правами
600, а каталог принадлежит деплой-пользователю. `rm` + создание даёт НОВЫЙ
инод, тогда как открытый дескриптор внутри работающего контейнера продолжает
смотреть на прежний, уже удалённый. `up -d` контейнер не трогает: он
сравнивает описание сервиса, а содержимое бинд-маунта в сравнение не входит.

Отказ беззвучный — ни одного красного признака нигде. Значит и все прежние
правки маршрутизации применялись лишь тогда, когда контейнер пересоздавался
по совпадению.

Перезагрузка по SIGHUP/API не лечит: она перечитывает тот же открытый инод.
Лечит только пересоздание контейнера — его и добавляю, под флагом, который
выставляется ПОСЛЕ успешной проверки конфига. Порядок важен: при обратном
битый конфиг убивал бы работающий Alertmanager вместо того, чтобы оставить
прежний работать.

Прод уже приведён в соответствие вручную — контейнер пересоздан, маршрут
клиентских инцидентов теперь идёт через кнопку. Эта правка нужна, чтобы
следующая правка конфига доехала сама.

Три теста: пересоздание есть, оно закрыто проверкой флага (безусловное рвало
бы доставку на каждом деплое метрик), флаг выставляется после проверки.
Прогон: 78 ops-тестов зелёные, ruff чист.
lekss361 merged commit 9e37262ea0 into main 2026-08-27 12:29:55 +00:00
lekss361 deleted branch fix/3xxx-alertmanager-stale-inode 2026-08-27 12:29:56 +00:00
Sign in to join this conversation.
No reviewers
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference: lekss361/gendesign#3142
No description provided.