Логи, отладка и мониторинг контейнеров

Рейтинг: 64% · 16 голосов
Практический курс по Docker: образы, контейнеры, тома, сети, Compose и продакшен. Уроки по главам с обсуждением.
Ответить
Аватара пользователя
Marina_DevOps
Сообщения: 25
Зарегистрирован: 11 май 2026, 05:31

Логи, отладка и мониторинг контейнеров

Сообщение Marina_DevOps »

АкадемияDocker с нуляГлава 10 из 17
Оглавление курса (17)
  1. Что такое Docker и какие задачи он решает
  2. Установка Docker и запуск первого контейнера
  3. Образы: слои, теги и реестр Docker Hub
  4. Пишем свой Dockerfile
  5. Тома и хранение данных: volumes и bind mounts
  6. Сети в Docker: связываем контейнеры между собой
  7. Переменные окружения и конфигурация контейнеров
  8. Docker Compose: поднимаем многоконтейнерное приложение
  9. Оптимизация образов: multi-stage сборка, размер и кэш слоёв
  10. Логи, отладка и мониторинг контейнеров (вы здесь)
  11. Базовая безопасность контейнеров
  12. Подготовка к продакшену: что важно учесть
  13. Dockerfile глубже: ENTRYPOINT и CMD, HEALTHCHECK, .dockerignore, запуск не от root
  14. Реестры образов: приватные registry, push и pull, теги и digest, imagePullSecrets
  15. BuildKit и buildx: multi-arch сборки, секреты сборки, экспорт кэша
  16. Docker в CI/CD: автосборка, сканирование образов (Trivy, Docker Scout), публикация
  17. Итоговый проект и куда расти: от Dockerfile до прода, обзор оркестрации (Kubernetes, Podman, OCI)
Контейнер упал ночью, приложение тормозит, а внутри даже ps нет. Эта глава о том, как заглянуть внутрь работающего и уже мёртвого контейнера: читать логи, подключаться к процессам, смотреть потребление ресурсов. Без этих навыков Docker остаётся чёрным ящиком, в котором что-то идёт не так.

Куда пишутся логи и как их читать:

Docker перехватывает stdout и stderr главного процесса контейнера и передаёт их драйверу логирования. По умолчанию это json-file: каждый контейнер пишет в /var/lib/docker/containers/<id>/<id>-json.log. Отсюда первое правило: приложение в контейнере должно писать логи в stdout и stderr, а не в файлы. Официальный образ nginx так и устроен, access.log там симлинк на /dev/stdout.

Код: Выделить всё

docker logs api                 # весь лог с начала
docker logs -f api              # следить в реальном времени
docker logs --tail 100 api      # последние 100 строк
docker logs --since 30m -t api  # за полчаса, с таймстампами
В Compose то же самое делает docker compose logs -f, можно перечислить несколько сервисов сразу.

Главная засада json-file: ротации по умолчанию нет. Лог растёт, пока не съест диск, на VPS за 300 рублей с 20 ГБ это вопрос недель. Лечится в /etc/docker/daemon.json:

Код: Выделить всё

{
  "log-driver": "json-file",
  "log-opts": {
    "max-size": "10m",
    "max-file": "3"
  }
}
После правки перезапустите демон командой systemctl restart docker. Настройка действует только на новые контейнеры, старые придётся пересоздать. Для одного контейнера то же задаётся флагом --log-opt, а в Compose секцией logging у сервиса.

Отладка изнутри:

docker exec запускает дополнительный процесс в живом контейнере. Если контейнер уже умер, exec не поможет, тогда работаем с logs и inspect. inspect выдаёт полное состояние в JSON: код выхода, флаг OOM, тома, сети, переменные окружения.

Код: Выделить всё

docker exec -it api sh    # шелл внутри контейнера
docker exec api env       # переменные окружения
docker inspect api --format '{{.State.ExitCode}} {{.State.OOMKilled}}'
Коды выхода читаются так: 137 это SIGKILL (чаще всего OOM killer при превышении лимита памяти, проверяйте OOMKilled), 139 это segfault, 1 обычно ошибка самого приложения, и ответ ищите в логах.

Мониторинг без лишнего софта:

Код: Выделить всё

docker stats              # живая таблица: CPU, память, сеть, диск
docker top api            # процессы внутри контейнера
docker events --since 1h  # события демона: старты, падения, OOM
docker stats хорош для быстрой проверки, но историю не хранит. Когда нужны графики и алерты, ставят cAdvisor с Prometheus и Grafana, для учебного проекта это перебор. Если вы описали HEALTHCHECK в Dockerfile или healthcheck в Compose, статус healthy или unhealthy виден прямо в docker ps, и это самый дешёвый мониторинг из возможных.

Типичные грабли:

Приложение пишет логи в файл внутри контейнера. docker logs пуст, файл умирает вместе с контейнером. Перенастройте вывод на stdout или сделайте симлинк на /dev/stdout, как в образе nginx.

Диск кончился из-за логов. Симптом: контейнеры падают с ошибкой no space left on device. Проверьте размер каталога /var/lib/docker/containers, виновник почти всегда там. Ротацию из примера выше ставьте сразу на любом сервере, не дожидаясь инцидента.

В минимальном образе нет шелла. Попытка вызвать bash через exec отвечает executable file not found. В alpine есть sh, в distroless нет вообще ничего. Выручает временный контейнер nicolaka/netshoot, запущенный с флагом --network container:api: он попадает в то же сетевое пространство, а внутри полный набор утилит.

docker logs молчит при стороннем драйвере. Исторически команда работала только с json-file, local и journald. Современный движок держит локальный кэш (dual logging) и показывает логи даже при syslog или gelf, но кэш иногда отключают ради экономии диска, тогда вывод смотрите уже в самой системе логирования.

Что в итоге:

Вы умеете читать и ротировать логи, попадать внутрь контейнера через exec, разбирать причины смерти через inspect и коды выхода, оценивать ресурсы через stats. Этого хватает для девяноста процентов инцидентов на одном хосте. В главе 11 займёмся безопасностью: почему root внутри контейнера это риск и как урезать контейнеру лишние права.
👍6 ❤️4 🔥1 😄 🤔1
✔ Лучший ответ сформирован автоматически — josemi05
Marina_DevOps писал(а):137 это SIGKILL (чаще всего OOM killer при превышении лимита памяти, проверяйте OOMKilled) у меня было 137 при OOMKilled false, два дня дебажил. оказалось приложение игнорило SIGTERM, и docker stop через 10 секунд добивал его SIGKILL'ом. поставил tini как entrypoint и стало нормально. так что 137 не всегда про память
Перейти к ответу →
Аватара пользователя
josemi05
Сообщения: 1
Зарегистрирован: 29 май 2026, 10:43

Re: Логи, отладка и мониторинг контейнеров

Сообщение josemi05 »

✔ Лучший ответ — сформирован автоматически
Marina_DevOps писал(а):137 это SIGKILL (чаще всего OOM killer при превышении лимита памяти, проверяйте OOMKilled)
у меня было 137 при OOMKilled false, два дня дебажил. оказалось приложение игнорило SIGTERM, и docker stop через 10 секунд добивал его SIGKILL'ом. поставил tini как entrypoint и стало нормально. так что 137 не всегда про память
👍1 ❤️1 🔥 😄 🤔1
Аватара пользователя
raspberryaddict
Сообщения: 1
Зарегистрирован: 15 май 2026, 23:54

Re: Логи, отладка и мониторинг контейнеров

Сообщение raspberryaddict »

спасибо за кусок про ротацию. у меня на vps от таймвеба mysql-контейнер накатал 11 гигов json-лога и сайт лёг с no space left on device. truncate -s 0 на лог-файл спас на месте, потом прописал max-size в daemon.json и пересоздал контейнеры. жаль, главу не прочитал на месяц раньше
👍 ❤️ 🔥1 😄 🤔
Аватара пользователя
py12
Сообщения: 2
Зарегистрирован: 28 май 2026, 06:03

Re: Логи, отладка и мониторинг контейнеров

Сообщение py12 »

а в compose ротацию для одного сервиса как правильно прописать? logging: driver: json-file и options с max-size? просто daemon.json у нас трогать нельзя, докер общий на несколько команд
👍 ❤️1 🔥2 😄 🤔
Аватара пользователя
mattadolfo
Сообщения: 1
Зарегистрирован: 15 май 2026, 16:36

Re: Логи, отладка и мониторинг контейнеров

Сообщение mattadolfo »

мелкое дополнение: --since понимает не только 30m, но и полный таймстамп вида 2026-06-10T03:00:00. удобно, когда разбираешь ночной инцидент по времени из алерта
👍 ❤️2 🔥 😄 🤔
Ответить
← Предыдущая глава
Оптимизация образов: multi-stage сборка, размер и кэш слоёв
Следующая глава →
Базовая безопасность контейнеров

Все главы курса «Docker с нуля»

Поделиться темой: ✈ Telegram VK

Вернуться в «Docker с нуля»

Кто сейчас на конференции

Сейчас этот форум просматривают: нет зарегистрированных пользователей и 1 гость