Как определить причину перезагрузки контейнера Docker?

«Как определить причину перезагрузки контейнера Docker?» — вопрос из категории DevOps, который задают на 10% собеседований Java Разработчик. Ниже — развёрнутый ответ с разбором ключевых моментов.

Ответ

Для диагностики перезапуска контейнера Docker используется комбинация анализа логов, метрик и системных событий.

Основные методы и инструменты:

  1. Анализ логов Docker и приложения:

    • docker logs <container_id> — просмотр stdout/stderr контейнера.
    • journalctl -u docker.service — логи службы Docker.
    • В Java-приложении можно добавить Shutdown Hook для логирования факта остановки:
      Runtime.getRuntime().addShutdownHook(new Thread(() -> {
      log.info("Application is shutting down. Container restart imminent.");
      }));
  2. Проверка событий Docker:

    docker events --since '2h' --filter 'event=die'

    Эта команда покажет, когда контейнеры завершались, и их exit-коды.

  3. Диагностика OOM Killer (Out-Of-Memory):

    • Проверить системные логи: dmesg -T | grep -i kill.
    • В логах Docker искать сообщение "Killed".
    • Анализировать потребление памяти через docker stats.
  4. Health Checks и мониторинг:

    • Docker Healthcheck в Dockerfile:
      HEALTHCHECK --interval=30s --timeout=3s --start-period=5s --retries=3 
      CMD curl -f http://localhost:8080/actuator/health || exit 1
    • Метрики приложения (Prometheus + Grafana): В Spring Boot приложении:
      // Использование Micrometer для экспорта метрик
      implementation 'io.micrometer:micrometer-registry-prometheus'

      Метрики доступны на /actuator/prometheus и помогают отслеживать состояние до падения.

Типичные причины и индикаторы:

  • Exit Code 137: Сигнал SIGKILL, часто из-за OOM Killer.
  • Exit Code 1/143: Ошибка в приложении (SIGHUP) или graceful shutdown.
  • Периодические рестарты: Проблема с Health Check или утечка ресурсов.