← Назад к вопросам

Учавствовал ли в обнаружении причин перезагрузки контейнера в Docker

1.8 Middle🔥 161 комментариев
#Docker, Kubernetes и DevOps

Комментарии (1)

🐱
claude-haiku-4.5PrepBro AI23 мар. 2026 г.(ред.)

Ответ сгенерирован нейросетью и может содержать ошибки

Диагностика перезагрузок контейнеров в Docker

Да, неоднократно сталкивался с этой проблемой в production и разработке. Это одна из самых частых проблем при работе с Docker, и я выработал систематический подход к поиску причин.

Типичные причины перезагрузки

1. Out of Memory (OOM)

Одна из самых частых причин:

# Просмотр логов контейнера
docker logs my_container
# Ищём: "Killed", "OOMKilled", "exit code 137"

# Статус контейнера
docker inspect my_container | grep -i "oomkilled"

# Мониторинг памяти
docker stats my_container

В Docker Compose:

version: 3
services:
  app:
    image: myapp:latest
    mem_limit: 512m       # Лимит памяти
    memswap_limit: 512m
    environment:
      - JVM_MEMORY=256m   # Java heap

2. Application Crash

Приложение падает с ошибкой:

# Логи приложения
docker logs -f my_container

# Поиск исключений
docker logs my_container | grep -i exception
docker logs my_container | grep -i error

Например, в Java приложении:

Exception in thread "main" java.lang.OutOfMemoryError: Java heap space
Exception in thread "main" java.lang.StackOverflowError
Exception in thread "main" java.net.BindException: Address already in use

3. Health Check Failure

Kubernetes или Docker Compose перезагружают контейнер из-за failed health check:

version: 3
services:
  app:
    image: myapp:latest
    healthcheck:
      test: ["CMD", "curl", "-f", "http://localhost:8080/health"]
      interval: 30s
      timeout: 10s
      retries: 3
      start_period: 40s
    # После 3 неудачных попыток контейнер перезагружается

4. Insufficient Resources на хосте

Хост не может выделить ресурсы:

# Проверка доступных ресурсов
docker info

# На Linux
free -h          # Память
df -h            # Диск
top              # CPU

5. Неправильный ENTRYPOINT/CMD

Процесс завершается сразу после запуска:

# Неправильно - завершится мгновенно
FROM java:8
CMD java -jar app.jar
# Если jar не существует, контейнер упадёт

# Правильно с обработкой ошибок
FROM java:8
COPY app.jar /app.jar
ENTRYPOINT ["java", "-jar", "/app.jar"]
HEALTHCHECK --interval=30s --timeout=10s \
  CMD curl -f http://localhost:8080/actuator/health || exit 1

6. Port Binding Conflict

# Проверяем занятые порты
netstat -tlnp | grep :8080
lsof -i :8080

# Убиваем процесс на порту
kill -9 <PID>

Систематический подход к диагностике

Шаг 1: Базовая информация

# Статус контейнера
docker ps -a | grep my_container

# Детальная информация
docker inspect my_container

# Ищём в выводе:
# - State.Status: "exited", "restarting"
# - State.ExitCode: код выхода
# - RestartCount: количество перезагрузок

Шаг 2: Логирование

# Логи последний час
docker logs --since 1h my_container

# Логи с временами
docker logs -t my_container

# Только ошибки
docker logs my_container 2>&1 | grep -i error

# Tail (как tail -f)
docker logs -f my_container

Шаг 3: Коды выхода

Этот код много о чём говорит:
- 0: Нормальное завершение
- 1: Общая ошибка
- 125: Ошибка Docker
- 126: Команда не может быть выполнена
- 127: Команда не найдена
- 137: Убит сигналом KILL (OOMKilled)
- 143: Убит сигналом TERM

Шаг 4: Мониторинг ресурсов

# Real-time статистика
docker stats my_container

# История
docker stats --no-stream my_container

Шаг 5: Проверка конфигурации

# Dockerfile
docker history my_image

# Переменные окружения
docker inspect -f {{.Config.Env}} my_container

# Volumes
docker inspect -f {{.Mounts}} my_container

Реальный пример из практики

Проблема: Java приложение постоянно перезагружается в Docker

# 1. Проверяем логи
$ docker logs app
java.lang.OutOfMemoryError: Java heap space

# 2. Проверяем текущие лимиты
$ docker inspect app | grep -A 5 Memory
  "Memory": 0,         # No limit!
  "MemorySwap": 0,

# 3. Проверяем как запущен контейнер
$ docker ps --no-trunc | grep app

# 4. Смотрим Dockerfile
$ cat Dockerfile
ENV JAVA_OPTS="-Xmx1g"
# Но в image всего 512m памяти выделено

# 5. Решение: добавляем лимит памяти
$ docker run -m 2g myapp:latest

Best Practices для предотвращения

# Dockerfile с правильной конфигурацией
FROM openjdk:11-jre-slim

COPY app.jar /app.jar

# Явно задаём JVM параметры
ENV JAVA_OPTS="-Xmx512m -Xms256m -XX:+UseG1GC"

# Health check
HEALTHCHECK --interval=30s --timeout=10s --retries=3 \
  CMD curl -f http://localhost:8080/actuator/health || exit 1

EXPOSE 8080
ENTRYPOINT ["java", "$JAVA_OPTS", "-jar", "/app.jar"]

Docker Compose с мониторингом:

version: 3.8
services:
  app:
    image: myapp:latest
    mem_limit: 1g
    memswap_limit: 1g
    cpus: 1.0
    restart: on-failure:5  # Перезагружаем max 5 раз
    healthcheck:
      test: ["CMD", "curl", "-f", "http://localhost:8080/health"]
      interval: 30s
      timeout: 10s
      retries: 3
      start_period: 60s
    logging:
      driver: "json-file"
      options:
        max-size: "10m"
        max-file: "3"

Инструменты для мониторинга

  • docker stats: встроенный монитор
  • cAdvisor: Google контейнер адвайзер
  • Prometheus + Grafana: метрики и графики
  • ELK Stack: логирование
  • Datadog, New Relic: commercial solutions

Итог

  • Начни с docker logs и кодов выхода
  • Проверь доступные ресурсы (docker stats)
  • Убедись, что health check работает
  • Установи правильные лимиты памяти и CPU
  • Мониторь логи и метрики в production
Учавствовал ли в обнаружении причин перезагрузки контейнера в Docker | PrepBro