Урок 02 · CLI

Жизненный цикл и диагностика

Получите намеренно упавший container и восстановите причину сбоя по status, exit code, logs и runtime-конфигурации.

Время: 20 минутРезультат: диагноз exit 17Интервью: порядок triage

Из памяти

Контейнер отсутствует в выводе docker ps. Назовите минимум три разные причины.

Состояния, которые нельзя смешивать

created означает, что runtime-объект создан, но основной process ещё не стартовал. running — process работает. exited — process завершился, но container и его метаданные сохранились. removed — runtime-объекта больше нет.

Не удаляйте уликуПосле rm исчезнут logs, exit code и runtime config контейнера. Сначала собрать факты, потом очищать.

Практика: job с ошибкой

docker run --name failing-job alpine:3.21 \
  sh -c 'echo "starting checks"; exit 17'

docker ps --filter name=failing-job
docker ps --all --filter name=failing-job

В первом списке строки нет: process уже завершился. Во втором container существует со status Exited (17).

docker inspect --format \
  'status={{.State.Status}} exit={{.State.ExitCode}} error={{.State.Error}}' \
  failing-job

docker logs --timestamps failing-job
НаблюдениеКакой вопрос закрывает
ps --allСуществует ли container и в каком он состоянии?
inspect .StateКак process завершился: exit code, OOM, runtime error?
logsЧто process записал в stdout/stderr до завершения?
inspect .ConfigКакой image, command, env и user действительно использовались?

docker start --attach failing-job запускает тот же container с той же командой. Результат снова будет 17: restart не исправляет детерминированную причину.

exec не заменяет основной process

docker run --detach --name diagnostic-web nginx:alpine
docker exec diagnostic-web nginx -t
docker exec diagnostic-web cat /etc/nginx/conf.d/default.conf
docker top diagnostic-web
docker stats --no-stream diagnostic-web

exec запускает дополнительный process в уже running container. Если основной process завершён, выполнить exec нельзя. Изменения через интерактивный shell полезны для исследования, но не являются воспроизводимым исправлением: fix должен попасть в Dockerfile или конфигурацию.

docker rm failing-job
docker rm --force diagnostic-web

Порядок triage для CI

  1. Найти container, включая stopped: docker ps --all.
  2. Зафиксировать status, exit code, OOMKilled и error через inspect.
  3. Собрать stdout/stderr через logs.
  4. Сверить фактические image, command, env, mounts и network.
  5. Только после сбора артефактов повторять запуск или очищать окружение.

«Я начинаю не с restart, а с состояния контейнера: ps -a, затем inspect для exit code/OOM и logs для stdout/stderr. После этого сверяю фактический image, command, env, mounts и network с ожидаемой конфигурацией. Так я сохраняю причину сбоя и отделяю проблему приложения от инфраструктуры».

Проверка понимания

1. Что показывает docker ps?

2. Container завершился с ошибкой. Первый ход?

3. Что делает docker exec?

Первичные источники

Если вывод отличается, сохраните команды и фактический результат и разберите их с преподавателем.