Комментарий пользователя
Привет! В проде Python‑под в Kubernetes периодически перезапускается с OOMKilled. В логах не видно явных утечек, нагрузка примерно такая же, как в тестах. С чем это чаще всего связано и как это исправить?
Ответ специалиста
Добрый день, Таня! OOMKilled — это сигнал от ядра Linux, что контейнер вышел за границы выделенной памяти. В Kubernetes это почти всегда происходит, когда реальное потребление памяти Python‑процесса превышает limits.memory контейнера. Сам Python при этом может не выдавать ошибки, т. к. наблюдение за cgroups и лимитами ведет сама платформа.
Чтобы разобраться, сначала смотрите на фактическое использование памяти под нагрузкой: kubectl top pod и kubectl top pod –containers.
Если потребление постоянно упирается в лимит, значит, приложению либо не хватает места, либо в коде что-то копится.
OOMKilled появляется из‑за того, что приложение неправильно расходует память в пике: например, считывает большой файл целиком, накапливает объекты в кэше, держит лишние пулы соединений или фантомные list и dict в globals.
На практике обычно помогает такой порядок действий:
- проверить реальное потребление памяти под нагрузкой;
- если видно, что приложение стабильно упирается в limits, спокойно увеличить limits.memory до более комфортного значения;
- если память продолжает ползти вверх, а не стабилизируется, уже искать объекты, которые держат ссылки лишнее время, и уменьшать их объем или время жизни;
- в Kubernetes выставить requests чуть ниже пика потребления, а limits — выше пика, чтобы контейнер не умирал при обычных всплесках, но не съедал все время лишнюю память.
В большинстве случаев OOMKilled в Python‑контейнере не связан с внутренней ошибкой Python, а именно с тем, как контейнер настроен в Kubernetes. Если у вас уже есть мониторинг, удобно добавить алерт по событиям OOMKilled и по container_memory_usage_bytes — это дает сигнал, когда нужно либо пересмотреть лимиты, либо смотреть на код.
На сегодня все. Еще больше ответов на сложные вопросы ищите в Академии Selectel.