Консультация Oblako.kz

Работа с контейнерами

Контейнер — это изолированная среда, в которой выполняются процессы и запускаются приложения. Одна из ключевых особенностей контейнеров — их переносимость между хостами и предсказуемо стабильная работа, поскольку все необходимые зависимости, пакеты и окружение находятся вместе с приложением внутри контейнера.

Тем не менее нередки ситуации, когда контейнеры после запуска (команда запуска контейнера docker run и ее параметры описаны в отдельной статье «Запуск контейнера») падают или ведут себя не так, как ожидается. В таких случаях нужны инструменты мониторинга и управления контейнерами. Дальше мы приведем основные команды работы с контейнерами.

Получить список запущенных контейнеров

Когда контейнер или контейнеры запускаются на хосте, первое, что хочется сделать, — убедиться в том, что они запустились исправно, работают и не падают. Такую информацию поможет получить команда docker ps. Она выведет в терминал информацию следующего вида:

docker_ps

Из таблицы можно узнать ID и название контейнера, образ, из которого он собран (IMAGE), команду, которая была выполнена автоматически при старте контейнера (COMMAND), сколько времени прошло с момента его запуска (CREATED), статус контейнера (STATUS, например Up 5 minutes, Exited (0) 2 hours ago, Restarting (1) 10 seconds ago) и внутренние и внешние порты контейнера (PORTS).

Если контейнер работает исправно, его статус обычно выглядит как Up 5 minutes (контейнер запущен и отвечает). Если контейнер был собран, запущен, но по какой-то причине основной рабочий процесс внутри него завершился с ошибкой, статус будет Exited (1) или с другим ненулевым кодом выхода. Однако, когда на хосте запущено множество контейнеров, разбираться в стандартном выводе команды docker ps становится неудобно.

Выделить только важное поможет фильтр формата вывода --format, где можно указать только нужные колонки и формат данных. Например, чтобы получить только ID, названия контейнеров и их статусы в табличном виде, достаточно выполнить следующую команду: docker ps --format "table {{.ID}}\t{{.Names}}\t{{.Status}}":

docker_format

Для включения других колонок в отчет их нужно добавить в команду docker ps --format "table {{.ID}}\t{{.Names}}\t{{.Status}}" в следующем виде:

  • {{.Created}} — человекочитаемое время создания контейнера (столбец CREATED).

  • {{.Image}} — имя и тег образа, из которого создан контейнер (столбец IMAGE).

  • {{.Ports}} — проброшенные порты контейнера (столбец PORTS).

  • {{.Command}} — команда, с которой был запущен контейнер (столбец COMMAND).

Просмотр логов контейнера

Заглянуть внутрь контейнера и понять, что происходит с процессом, помогает команда docker logs container_name. Команда возвращает лог работы процесса, указанного в ENTRYPOINT или в CMD. Вывод зависит от конкретного процесса, например, вот лог сервиса Caddy (HTTPS reverse proxy):

docker_logs

В выводе видны ошибки обработки URL, но сервис работает исправно. Проблема команды docker logs в том, что она по умолчанию выводит всю историю лога, и это часто бывает излишне. Получить лог только по последним событиям можно с помощью флага --tail, который ограничивает количество выводимых строк. Например, команда docker logs --tail 1 caddy-container выведет только последнюю строку лога:

docker_logs_tail

Так вывод лога Caddy становится короче, при этом мы видим только последние события. Если нужно «подписаться» на новые записи и одновременно видеть только последние строки, можно добавить флаг -f: docker logs --tail 1 -f caddy-container.

Мониторинг и сбор статистики контейнера

Быстро понять, сколько ресурсов потребляет конкретный контейнер или все контейнеры вместе, помогает команда docker stats (или docker stats container_name для одного контейнера). Она возвращает таблицу со следующей информацией:

  • CONTAINER ID / NAME — идентификатор и имя контейнера.
  • CPU % — доля CPU, которую сейчас потребляет контейнер.
  • MEM USAGE / LIMIT — объем памяти, который использует контейнер, и установленный лимит.
  • MEM % — процент использования памяти от лимита.
  • NET I/O — объем сетевого трафика (входящего/исходящего) для контейнера.
  • BLOCK I/O — чтение/запись на диске, связанные с контейнером.
  • PIDS — количество процессов, запущенных внутри контейнера.

Если нужно понять, какие именно процессы запущены в контейнере, поможет команда docker top container_name. Она выводит список процессов внутри контейнера в формате, похожем на классическую команду ps в Linux: PID, пользователя, время работы и команду запуска.

Работа внутри контейнера

Есть разные причины, зачем может потребоваться войти в контейнер. Например, сервис в одном контейнере по какой-то причине не может передать данные в сервис в другом контейнере. Для отладки можно зайти в контейнер с помощью команды docker exec -it container_name /bin/sh (или /bin/bash, если он установлен в образе) и выполнить, например, команду curl http://service-b:80/health для проверки сетевого соединения. Кроме проверки сети, вход в контейнер полезен и для других задач администрирования и отладки:

  • Проверка зависимостей и окружения: python --version, node --version, printenv для просмотра переменных окружения.
  • Диагностика файловой системы: ls -la /app, du -sh /var/log для проверки структуры каталогов и занятого места.
  • Просмотр локальных логов приложения внутри контейнера, если оно пишет в файлы: tail -n 50 /var/log/app.log.
  • Запуск разовых диагностических команд: ping service-b, nslookup service-b, telnet service-b 80 (если нужные утилиты установлены в образе).
  • Ручной запуск приложения с дополнительными флагами отладки, чтобы воспроизвести проблему прямо в контейнере.

Вход в контейнер можно рассматривать как инструмент точечной диагностики и отладки. Кстати, многие перечисленные выше действия можно выполнить, не заходя в контейнер, с помощью docker exec. В этом случае команда будет выполнена в контейнере, но интерактивная сессия не откроется и терминал не будет заблокирован. Например, вот так можно вызвать утилиту curl в контейнере без входа в него: docker exec container_name curl http://service-b:80/health.

Запуск, остановка, перезапуск и приостановка контейнера

Первый запуск контейнера обычно выполняется командой docker run -d image_name, при этом Docker создает новый контейнер из указанного образа и сразу же его запускает. Если контейнер уже был создан и затем остановлен командой docker stop container_name, повторно создавать его не нужно — достаточно запустить его командой docker start container_name. В отличие от run, команда start не создает новый контейнер, а поднимает существующий с его состоянием (томами, именем, переменными окружения).

Корректно остановить работающий контейнер помогает команда docker stop container_name. Она отправляет основному процессу внутри контейнера сигнал SIGTERM и дает ему время на завершение (по умолчанию 10 секунд), а затем, при необходимости, принудительно посылает SIGKILL.

Иногда контейнер нужно не останавливать полностью, а временно приостановить. Команда docker pause container_name приостанавливает все процессы внутри контейнера (сигнал SIGSTOP на уровне cgroups): они перестают потреблять CPU, но память и состояние остаются в том же виде. Это удобно, когда нужно временно «заморозить» контейнер, не завершая работу приложения.

Команда docker unpause container_name возобновляет работу приостановленного контейнера — процессы продолжают выполняться с того же места, где были остановлены.

Бывает, что контейнер не отвечает на команды stop и pause. В такой ситуации можно принудительно завершить работу процесса командой docker kill container_name. Она сразу отправляет сигнал SIGKILL (или другой указанный сигнал), не давая приложению времени на корректное завершение. Такая остановка может привести к потере несохраненных данных или повреждению файлов, с которыми работал процесс, поэтому использовать docker kill стоит только в крайних случаях.

Удаление контейнеров

Команда docker ps показывает список активных контейнеров, а с ключом -a — список всех контейнеров, в том числе остановленных и неактивных. Такие неактивные контейнеры занимают место, и от них время от времени нужно избавляться. Поддерживать контейнерную гигиену помогают несколько команд:

  • docker rm container_name — удалить остановленный контейнер.
  • docker rm -f container_name — остановить запущенный контейнер и сразу удалить его.
  • docker container prune — удалить все остановленные контейнеры.
Последнее обновление: 04.02.2026