Отладка контейнеров: logs, exec, inspect, stats

↑ Этап 2 · Контейнеры: Docker, docker-compose, Makefile

Обязательно~5 мин чтенияУровень: junior

Зачем это на собесе

«Контейнер падает/не работает — что делаете?» Нужна методичность и знание четырёх базовых команд.

Основные команды

docker ps -a                                  # все контейнеры, статусы, коды выхода
docker logs -f --tail 200 --since 10m api     # логи (stdout/stderr)
docker logs --timestamps api 2>&1 | grep -i error
docker exec -it api sh                        # зайти в запущенный контейнер (bash, если есть)
docker exec api env; docker exec api cat /etc/hosts
docker inspect api                            # полная конфигурация и состояние (JSON)
docker inspect -f '{{.State.ExitCode}} {{.State.OOMKilled}} {{.State.Error}}' api
docker stats --no-stream                      # CPU, память, сеть, I/O в реальном времени
docker top api                                # процессы внутри
docker diff api                               # изменённые файлы в слое записи
docker events --since 1h                      # события демона
docker cp api:/app/logs/app.log ./            # достать файл

Алгоритм диагностики

1. Статус: docker ps -a

СтатусЗначение
Upработает ((healthy)/(unhealthy) при healthcheck)
Restartingпадает и перезапускается (restart policy): смотреть логи и код выхода
Exited (0)завершился штатно (задача выполнена или main-процесс не задаёт долгоживущий процесс)
Exited (1)ошибка приложения
Exited (125/126/127)ошибка docker run / команда не исполняема / команда не найдена
Exited (137)SIGKILL: OOM или docker kill/таймаут остановки
Exited (139)SIGSEGV (падение, segfault)
Exited (143)SIGTERM: корректная остановка

2. Логи: docker logs — причина выхода почти всегда в последних строках. Нет вывода — приложение пишет в файл вместо stdout, либо падает раньше логирования.

3. inspect: State.ExitCode, OOMKilled, Error, Config.Env, Config.Cmd/Entrypoint, Mounts, NetworkSettings, HostConfig.RestartPolicy, Health (последние проверки healthcheck).

4. Воспроизвести интерактивно: запустить тот же образ с переопределённой командой:

docker run --rm -it --entrypoint sh myapp:1.0          # без выполнения приложения
docker run --rm -it --env-file .env --network appnet myapp:1.0 sh
docker compose run --rm --no-deps --entrypoint sh api
docker commit crashed_container debug_img && docker run -it --entrypoint sh debug_img    # для упавшего

5. Сеть: docker exec api nc -zv db 5432, getent hosts db, docker network inspect; образ без утилит — docker run --rm -it --network container:api nicolaka/netshoot.

6. Ресурсы: docker stats (память приближается к лимиту?), docker inspect ... .HostConfig.Memory, dmesg | grep -i oom на хосте.

7. Хост: место (df -h, docker system df), inode, лимиты файлов, версия Docker/ядра, журнал демона journalctl -u docker.

Типичные причины падений

СимптомПричина
Сразу Exited (0)PID 1 завершился: команда не долгоживущая (nginx без daemon off), демонизация в фон
Exited (1) сразунет конфигурации/переменных, не подключился к БД, ошибка миграции, неверный порт
exec format errorархитектура образа (arm64/amd64) или shebang/CRLF в скрипте
permission deniedправа на файлы/тома, USER non-root, read-only ФС
not found у /docker-entrypoint.shCRLF (Windows) в скрипте или нет интерпретатора (alpine без bash)
address already in useпорт занят на хосте/в контейнере
Контейнер «живёт», но не отвечаетслушает 127.0.0.1, неверный порт, healthcheck unhealthy
Перезапуски с 137нехватка памяти (лимит), утечка
Зависает остановка 10 сприложение не обрабатывает SIGTERM (shell-форма, PID 1)
DNS не резолвитсяdefault bridge, не та сеть, search/ndots
Растёт дисклоги json-file без ротации, тома, слой записи

Отладочные контейнеры и инструменты

  • nicolaka/netshoot — набор сетевых инструментов (tcpdump, dig, curl, nmap);
  • docker run --pid=container:api --cap-add SYS_PTRACE ... — доступ к процессам;
  • docker debug (Docker Desktop/Pro) — shell в distroless;
  • docker run --rm -it -v /var/run/docker.sock:/var/run/docker.sock docker sh — осторожно с сокетом;
  • Kubernetes: kubectl debug -it pod/name --image=busybox --target=app, kubectl logs --previous, kubectl describe pod, kubectl get events.

Логи и метрики

  • драйвер логирования: docker info --format '{{.LoggingDriver}}'; docker logs работает с json-file/local/journald;
  • централизованные логи и метрики (cAdvisor, Prometheus, Loki) для истории, когда контейнер удалён;
  • docker compose logs -f service, docker compose ps, docker compose top.

Вопросы с ответами