Что произойдет с контейнером, если будет превышен лимит по памяти

«Что произойдет с контейнером, если будет превышен лимит по памяти» — вопрос из категории Docker, который задают на 23% собеседований Devops Инженер. Ниже — развёрнутый ответ с разбором ключевых моментов.

Ответ

Контейнер будет принудительно завершен (killed) ядром операционной системы с событием OOM (Out Of Memory).

Механизм в Docker: При запуске контейнера с флагом -m или --memory Docker создает cgroup с заданным лимитом памяти. Если процесс в контейнере пытается выделить больше памяти, чем разрешено, ядро Linux активирует OOM killer, который завершает процесс-нарушитель.

Пример запуска с лимитом:

docker run -d --name my-app --memory="100m" --memory-swap="100m" my-application:latest
  • --memory="100m" — лимит оперативной памяти (RAM).
  • --memory-swap="100m" — общий лимит памяти (RAM + swap). Значение, равное --memory, отключает использование swap для контейнера.

Как это выглядит на практике:

  1. Проверим статус контейнера после OOM:
    docker ps -a | grep my-app
    # Вывод: ... Exited (137) ...

    Код выхода 137 (128 + SIGKILL(9)) указывает на принудительное завершение.

  2. Посмотрим логи контейнера:
    docker logs my-app
    # Может содержать сообщение об ошибке OOM от приложения или просто обрыв логов.
  3. Детальная информация из docker inspect:
    docker inspect my-app --format='{{.State.OOMKilled}}'
    # Вывод: true

Последствия и мониторинг в DevOps:

  • В standalone Docker: Контейнер просто остановится. Необходимо настроить политику перезапуска (--restart unless-stopped) или использовать оркестратор.
  • В Kubernetes: Pod перейдет в статус CrashLoopBackOff с причиной OOMKilled и будет постоянно перезапускаться, пока не будет увеличен лимит памяти или не исправлена утечка в приложении.
  • Мониторинг: Критически важно настраивать алерты на события OOM и отслеживать потребление памяти контейнеров через системы вроде Prometheus/Grafana (с использованием экспортера cAdvisor или node-exporter).