Выкурить надоедливые проблемы с контейнерами с минимальным безумием
Иногда контейнеры Docker могут быть черным ящиком. Независимо от того, создали ли вы базовый образ или используете общедоступный, колеблющийся контейнер разочаровывает. Выяснение того, что происходит, может быть затруднено из-за того, как выполняются контейнеры и как они обрабатывают ведение журнала.
В этой статье мы рассмотрим несколько основных команд и параметров, которые вы можете использовать для устранения неполадок особенно суетливых контейнеров. Если контейнер не запускается, периодически взрывается или вы просто хотите больше узнать о деталях изображения, эти простые варианты действительно изменят правила игры.
1. Лучшее ведение журнала и временные метки
Первый и самый простой пример — использовать инструменты ведения журнала, которые уже предоставляет Docker. Большинство людей уже знают, как смотреть логи внутри контейнера:
docker logs <container_id>
Но что, если этот конкретный контейнер работает уже давно и имеет журнал размером с Техас? В таких случаях вы можете просто добавить дополнительный параметр --tail
:
docker logs --tail 10 <container_id>
Используя опцию --tail
, вы можете увидеть только последние n
строки журнала. Передача количества строк, которые вы хотите видеть, позволяет вам перейти прямо к самой актуальной и последней информации.
Если ваш вывод журнала из контейнера по умолчанию не содержит временных меток, вы также можете добавить их. Docker позволяет вам передать флаг -t
в log
, который будет добавлять к каждой строке отметку времени:
docker logs -t <container_id>
Эти параметры также можно комбинировать для создания точного инструмента устранения неполадок. Теперь вы сможете точно сказать, когда что-то произошло, без необходимости что-либо менять внутри контейнера.
2. Выполнение команд от root
Если вы используете образ, который запускается от имени пользователя root по умолчанию, это не проблема. Когда вы работаете не от имени пользователя root, а вместо этого используете непривилегированного пользователя, это отличный инструмент для устранения неполадок.
Если вы запустите:
docker exec -it <container_id> /bin/sh
Это всегда будет работать как пользователь, определенный в базовом образе. Если у этого пользователя нет привилегий суперпользователя, то может быть сложно попытаться выполнить запуск в работающем контейнере для устранения неполадок (особенно если вам нужно что-то установить).
Если вы хотите перейти в контейнер как пользователь root, все, что вам нужно сделать, это вместо этого передать следующее:
docker exec -u 0 -it <container_id> /bin/sh
Это укажет Docker использовать пользователя с идентификатором 0
. Это корень. Теперь, когда вы войдете в контейнер, вы будете готовы к отладке с полными привилегиями.
3. Фиксация контейнера как образа
Это часто упускаемая из виду функция Docker. Фактически вы можете создать новый образ из существующего контейнера. Это означает, что если вы возились с контейнером и внесли несколько изменений, чтобы исправить некоторые ошибки, вы можете сразу же запустить из него новые контейнеры. Вам даже не нужно перестраивать Dockerfile.
Следующая команда зафиксирует новый образ из существующего контейнера:
docker commit <container_name> <new_image>
Это создаст новый образ с любым именем, которое вы укажете, и вы сможете сразу же использовать его для запуска новых контейнеров.
Еще одно дополнительное преимущество команды commit
заключается в том, что вы можете передать ей синтаксис Dockerfile во время процесса фиксации. Если вы хотите зафиксировать существующий контейнер, но изменить в нем одну из переменных среды, вы можете использовать флаг --change
, чтобы передать это:
docker commit --change="ENV foo=bar" <container_name> <new_image>
Вы можете передать несколько разных changes
в команду commit
, чтобы упростить создание впечатляюще детализированного образа в командной строке.
4. Сопоставление хэшей изображений
Если вы устраняете неполадки в контейнере, который существует некоторое время, вы можете не знать, с какой конкретной версией образа он был создан. Если вы используете реестр контейнеров, такой как Docker Hub или Elastic Container Registry, вы можете легко получить хэш образа, чтобы сравнить его с вашим контейнером.
Быстрый способ получить все метаданные о контейнере — использовать команду inspect
. Это хорошо, но дает вам тонну информации. Если все, что вам нужно, это хэш изображения, вы можете получить его, используя небольшое волшебство форматирования, например:
docker inspect --format "{{ .Image }}" <container_id>
Это должно вывести хэш sha256 изображения, на котором запущен контейнер. Хэш можно сравнить с хешем в вашем реестре, чтобы определить, когда он был создан.
Теперь вы можете быть абсолютно уверены, какая версия и где работает.
5. Пропуск кеша сборки
Если вы действительно изо всех сил пытаетесь понять, почему сборка дает сбой, содержит ошибки или просто не включает некоторые сделанные вами изменения, возможно, пришло время удалить кеш. Хотя Docker должен распознавать изменения в слоях и перестраивать их по мере необходимости, иногда вам нужно спокойствие, чтобы начать с нуля.
Если вы хотите создать образ без использования существующего кэша сборки, вы можете запустить следующую команду:
docker build --tag <tag> --no-cache .
Это проигнорирует любые ранее созданные элементы в кеше и заставит все построить с нуля. Удобно, если вы работаете с несколькими итерациями изображения и хотите убедиться, что вы внесли очень тонкие изменения в некоторые слои.
Спасибо за чтение! Какие ваши любимые советы по Docker? Посмотрите несколько других моих постов о Docker: