Как использовать команду docker debug для отладки контейнеров и образов

DockerDockerBeginner
Практиковаться сейчас

💡 Этот учебник переведен с английского с помощью ИИ. Чтобы просмотреть оригинал, вы можете перейти на английский оригинал

Введение

В этой лабораторной работе мы рассмотрим, как эффективно отлаживать Docker-контейнеры и образы с помощью команды docker debug и других связанных методов. Мы начнем с решения задачи отладки slim-контейнеров, в которых отсутствует shell, демонстрируя, как выполнять команды непосредственно в их среде.

Затем мы научимся отлаживать slim-образ напрямую, еще до его запуска в качестве контейнера. Мы также рассмотрим, как изменять файлы внутри работающего контейнера для целей отладки и как управлять набором инструментов для отладки с помощью команд install и uninstall. Наконец, мы глубже поймем точки входа контейнера, используя команду entrypoint.


Skills Graph

%%%%{init: {'theme':'neutral'}}%%%% flowchart RL docker(("Docker")) -.-> docker/ContainerOperationsGroup(["Container Operations"]) docker(("Docker")) -.-> docker/VolumeOperationsGroup(["Volume Operations"]) docker(("Docker")) -.-> docker/DockerfileGroup(["Dockerfile"]) docker/ContainerOperationsGroup -.-> docker/run("Run a Container") docker/ContainerOperationsGroup -.-> docker/rm("Remove Container") docker/ContainerOperationsGroup -.-> docker/exec("Execute Command in Container") docker/VolumeOperationsGroup -.-> docker/cp("Copy Data Between Host and Container") docker/DockerfileGroup -.-> docker/build("Build Image from Dockerfile") subgraph Lab Skills docker/run -.-> lab-555138{{"Как использовать команду docker debug для отладки контейнеров и образов"}} docker/rm -.-> lab-555138{{"Как использовать команду docker debug для отладки контейнеров и образов"}} docker/exec -.-> lab-555138{{"Как использовать команду docker debug для отладки контейнеров и образов"}} docker/cp -.-> lab-555138{{"Как использовать команду docker debug для отладки контейнеров и образов"}} docker/build -.-> lab-555138{{"Как использовать команду docker debug для отладки контейнеров и образов"}} end

Отладка slim-контейнера без shell

На этом шаге мы научимся отлаживать slim-контейнер, в котором не установлен shell. Slim-контейнеры часто используются для уменьшения размера образа и поверхности атаки, но их отладка может быть сложной при возникновении проблем.

Сначала запустим простой slim-контейнер, который выводит сообщение и завершает работу. Мы используем образ alpine — очень маленький дистрибутив Linux.

docker run alpine echo "Hello from Alpine!"

Вы должны увидеть вывод Hello from Alpine! в терминале. Это подтверждает успешный запуск контейнера.

Теперь попробуем выполнить команду внутри этого контейнера с помощью docker exec. Попытаемся запустить /bin/sh — распространённый shell.

docker run -d --name slim-container alpine sleep 3600
docker exec -it slim-container /bin/sh

Скорее всего, вы увидите сообщение об ошибке, указывающее, что /bin/sh не найден. Это происходит потому, что образ alpine в стандартной конфигурации не включает shell, такой как bash или sh. Это характерная особенность slim-контейнеров.

Для отладки контейнера без shell мы можем использовать команду docker exec для выполнения конкретной команды в среде контейнера. Однако, поскольку shell отсутствует, нам нужно выполнять команду напрямую.

Попробуем вывести список файлов в корневой директории контейнера. Команда ls обычно доступна даже в минимальных средах.

docker exec -it slim-container ls /

Вы должны увидеть список директорий и файлов в корне файловой системы контейнера, таких как bin, etc, lib и т.д. Это демонстрирует, что мы всё ещё можем выполнять команды напрямую внутри контейнера без shell.

Наконец, удалим созданный контейнер.

docker stop slim-container
docker rm slim-container

Этот шаг показал, как взаимодействовать со slim-контейнером без shell, выполняя команды напрямую с помощью docker exec. В следующих шагах мы рассмотрим другие методы отладки.

Отладка slim-образа напрямую

На предыдущем шаге мы научились взаимодействовать с работающим slim-контейнером. Однако иногда может потребоваться проверить содержимое slim-образа до его запуска в качестве контейнера или если контейнер не может запуститься. В этом шаге мы рассмотрим, как отлаживать slim-образ напрямую.

Docker предоставляет команду docker run с возможностью переопределения стандартной точки входа (entrypoint) и команды образа. Это позволяет нам выполнить другую команду во временном контейнере, созданном из образа, что даёт возможность проверить его содержимое.

Снова используем образ alpine. Мы знаем, что это slim-образ, который по умолчанию не содержит shell. Мы можем использовать docker run для выполнения команды ls / напрямую на образе.

docker run --rm alpine ls /

Флаг --rm гарантирует, что временный контейнер будет автоматически удалён после завершения команды. Вы должны увидеть тот же вывод, что и при выполнении ls / на работающем контейнере в предыдущем шаге. Это подтверждает, что мы можем напрямую проверять файловую систему образа.

Теперь проверим наличие конкретной команды в образе. Например, проверим наличие команды ping.

docker run --rm alpine which ping

Скорее всего, вы увидите сообщение об ошибке типа which: not found. Это означает, что команда ping отсутствует в стандартном образе alpine. Это ещё одна характеристика slim-образов — они часто содержат только минимально необходимые инструменты.

Попробуем команду, которая точно существует, например cat.

docker run --rm alpine which cat

В этот раз вы должны увидеть вывод /bin/cat, что подтверждает наличие команды cat в образе.

Этот метод использования docker run --rm <image> <command> очень полезен для быстрой проверки содержимого образа, подтверждения наличия конкретных файлов или команд и понимания структуры образа без необходимости запуска долгоживущего контейнера или сборки нового образа.

Изменение файлов в работающем контейнере

На этом шаге мы научимся изменять файлы внутри работающего контейнера. Это может быть полезно для отладки, например, при изменении конфигурационных файлов или добавлении временных скриптов в уже запущенный контейнер.

Мы начнём с запуска простого контейнера на основе образа ubuntu, который более функциональный, чем alpine, и включает shell и стандартные утилиты.

docker run -d --name my-ubuntu ubuntu sleep 3600

Эта команда запускает контейнер Ubuntu в фоновом режиме (-d) и поддерживает его работу в течение часа с помощью команды sleep 3600. Мы назвали контейнер my-ubuntu для удобства.

Теперь воспользуемся docker exec, чтобы получить shell внутри работающего контейнера.

docker exec -it my-ubuntu /bin/bash

Теперь вы находитесь внутри bash-оболочки контейнера my-ubuntu. Приглашение командной строки изменится, указывая на то, что вы внутри контейнера.

Внутри контейнера создадим новый файл в директории /tmp.

echo "This is a test file." > /tmp/test_file.txt

Проверим, что файл был создан и содержит правильное содержимое.

cat /tmp/test_file.txt

Вы должны увидеть вывод This is a test file.. Это подтверждает, что мы смогли создать и записать файл внутри работающего контейнера.

Чтобы выйти из оболочки контейнера, просто введите exit.

exit

Теперь вы вернулись в терминал вашей LabEx VM.

Мы также можем копировать файлы в работающий контейнер и из него с помощью команды docker cp. Создадим файл на нашей LabEx VM и скопируем его в контейнер.

Сначала создадим файл local_file.txt в вашей директории ~/project.

echo "This file is from the host." > ~/project/local_file.txt

Теперь скопируем этот файл в директорию /tmp контейнера my-ubuntu.

docker cp ~/project/local_file.txt my-ubuntu:/tmp/

Формат команды docker cp: docker cp <исходный_путь> <имя_контейнера>:<целевой_путь> или docker cp <имя_контейнера>:<исходный_путь> <целевой_путь>.

Проверим, что файл был скопирован в контейнер. Вернёмся в оболочку контейнера.

docker exec -it my-ubuntu /bin/bash

Внутри контейнера проверим наличие local_file.txt в /tmp.

ls /tmp/

Вы должны увидеть local_file.txt вместе с test_file.txt.

Теперь посмотрим содержимое local_file.txt внутри контейнера.

cat /tmp/local_file.txt

Вы должны увидеть вывод This file is from the host..

Снова выйдем из оболочки контейнера.

exit

Наконец, удалим контейнер.

docker stop my-ubuntu
docker rm my-ubuntu

Этот шаг продемонстрировал, как изменять файлы внутри работающего контейнера с помощью docker exec для получения shell и стандартных Linux-команд, а также как копировать файлы между хостом и контейнером с помощью docker cp.

Управление набором инструментов для отладки: установка и удаление

На этом шаге мы рассмотрим, как добавлять и удалять инструменты отладки в работающем контейнере. Хотя обычно рекомендуется сохранять образы рабочих контейнеров минимальными, иногда требуется временно установить инструменты для отладки.

Мы снова будем использовать образ ubuntu, так как он содержит менеджер пакетов (apt), что упрощает установку программного обеспечения.

Сначала запустим новый контейнер Ubuntu в фоновом режиме.

docker run -d --name debug-ubuntu ubuntu sleep 3600

Теперь получим shell внутри контейнера.

docker exec -it debug-ubuntu /bin/bash

Внутри контейнера попробуем использовать команду, которая не установлена по умолчанию, например ping.

ping google.com

Скорее всего, вы увидите ошибку "command not found".

Для установки ping и других сетевых утилит воспользуемся менеджером пакетов apt. Сначала рекомендуется обновить список пакетов.

apt update

Эта команда получает актуальную информацию о доступных пакетах из репозиториев.

Теперь установим пакет iputils-ping, который содержит команду ping.

apt install -y iputils-ping

Флаг -y автоматически подтверждает установку без запроса.

После завершения установки команда ping должна стать доступной.

ping -c 4 google.com

Вы должны увидеть вывод команды ping, что подтверждает её работоспособность внутри контейнера.

После завершения отладки рекомендуется удалить установленные инструменты, чтобы сохранить контейнер чистым и уменьшить его размер (хотя модификация работающих контейнеров для продакшена обычно не рекомендуется).

Для удаления пакета iputils-ping используем команду:

apt remove -y iputils-ping

Можно проверить, что ping больше недоступен.

ping google.com

Снова должна появиться ошибка "command not found".

Выйдем из оболочки контейнера.

exit

Наконец, удалим контейнер.

docker stop debug-ubuntu
docker rm debug-ubuntu

Этот шаг продемонстрировал, как временно устанавливать и удалять инструменты отладки в работающем контейнере с помощью менеджера пакетов. Это мощный метод для диагностики проблем в контейнерах, где необходимые инструменты отсутствуют в базовом образе.

Понимание точки входа контейнера с помощью команды entrypoint

На этом шаге мы изучим инструкцию ENTRYPOINT в Dockerfile и её влияние на запуск контейнера. ENTRYPOINT определяет команду, которая будет выполнена при старте контейнера. Она часто используется для установки основного исполняемого файла контейнера.

Создадим простой Dockerfile с использованием ENTRYPOINT. В вашей директории ~/project создайте файл Dockerfile со следующим содержимым:

FROM alpine
ENTRYPOINT ["echo", "Hello from the entrypoint!"]
CMD ["default", "command"]

Этот Dockerfile использует образ alpine в качестве базового. ENTRYPOINT установлен в ["echo", "Hello from the entrypoint!"]. CMD установлен в ["default", "command"]. Когда указаны и ENTRYPOINT, и CMD, аргументы CMD передаются как параметры команде ENTRYPOINT.

Теперь соберём образ из этого Dockerfile.

docker build -t my-entrypoint-image ~/project

Эта команда собирает образ с именем my-entrypoint-image из Dockerfile в директории ~/project.

Запустим контейнер из этого образа без указания дополнительных команд.

docker run my-entrypoint-image

Вы должны увидеть вывод Hello from the entrypoint! default command. Это показывает, что команда ENTRYPOINT (echo) была выполнена, а аргументы CMD (default command) были ей переданы.

Теперь запустим контейнер, указав другую команду в строке docker run. При указании команды в docker run она переопределяет инструкцию CMD в Dockerfile, но ENTRYPOINT всё равно выполняется с предоставленной командой в качестве аргументов.

docker run my-entrypoint-image "override command"

Вы должны увидеть вывод Hello from the entrypoint! override command. Это демонстрирует, что ENTRYPOINT был выполнен, но аргументы из команды docker run (override command) заменили аргументы CMD.

Что если нужно полностью игнорировать ENTRYPOINT и выполнить другую команду? Можно использовать флаг --entrypoint с docker run.

docker run --entrypoint /bin/echo my-entrypoint-image "Running a different command"

Вы должны увидеть вывод Running a different command. В этом случае флаг --entrypoint переопределил ENTRYPOINT, указанный в Dockerfile, и выполнил предоставленную команду (/bin/echo) с аргументами (Running a different command).

Понимание ENTRYPOINT и CMD критически важно для сборки и отладки Docker-образов. ENTRYPOINT определяет основное исполняемое приложение, а CMD предоставляет аргументы по умолчанию для этого приложения или команду по умолчанию, если ENTRYPOINT не установлен.

Итоги

В этой лабораторной работе мы изучили, как выполнять отладку Docker-контейнеров и образов с помощью команды docker debug и связанных с ней техник. Мы начали с исследования отладки минималистичного контейнера без оболочки, продемонстрировав, что можем выполнять команды непосредственно в среде контейнера с помощью docker exec, даже без традиционной оболочки типа bash или sh. Этот метод критически важен для диагностики проблем в минималистичных образах контейнеров.

Хотя предоставленное содержание охватывает только первый шаг, общая структура лабораторной работы предполагает, что последующие шаги будут включать:

  • Отладку минималистичных образов напрямую
  • Модификацию файлов в работающих контейнерах
  • Управление набором инструментов отладки с помощью команд установки и удаления
  • Изучение точек входа контейнеров с использованием команды entrypoint

Эти шаги дополнительно расширят наши возможности по диагностике и устранению проблем в Docker-приложениях и образах.