Как проверить изменения в файловой системе контейнера Docker
Контейнеры Docker наследуют файловую систему своего образа при первоначальном создании. Файловая система контейнера может отличаться от содержимого образа после создания, если в доступный для записи слой контейнера вносятся изменения.
Возможность проверки изменений в файловой системе может помочь вам отладить проблемы и исследовать отсутствующие данные. Файлы, записанные в файловую систему контейнера, будут потеряны при перезапуске или уничтожении этого контейнера. В некоторых случаях вы можете непреднамеренно выполнять записи, которые вместо этого должны быть направлены на постоянный том.
В этой статье мы поделимся некоторыми методами определения изменений, внесенных в файловые системы контейнеров. Вы можете использовать эту информацию для отслеживания активности контейнера и исследования расхождений между различными средами.
Использование Docker Diff
Для этого в Docker CLI есть встроенная команда. Запуск docker diff
перечислит все изменения, внесенные в файлы и каталоги в конкретном контейнере. Он принимает идентификатор или имя контейнера, который вы хотите проверить.
Запустите простой контейнер для демонстрационных целей:
$ docker run -it --name alpine alpine:latest sh
Это запустит новый контейнер с изображением Alpine. Окно вашего терминала будет прикреплено к контейнеру. Держите это окно открытым.
Теперь запустите docker diff
во втором сеансе терминала:
$ docker diff alpine
Вывод не производится, поскольку свежий контейнер по-прежнему точно соответствует файловой системе образа Alpine.
Вернитесь к своему первому терминалу, который все еще подключен к контейнеру. Запустите несколько команд, которые добавляют, удаляют или изменяют файлы:
/ # touch demo / # touch example
Вернитесь к первому окну оболочки. Повторите команду docker diff
, чтобы увидеть внесенные изменения:
$ docker diff alpine A /example C /root C /root/.ash_history A /demo
Теперь два новых файла видны в выводе команды. Запуск touch
также добавил записи в историю оболочки контейнера. Также сообщается об изменении /root/.ash_history
, а также о последующем изменении каталога /root
.
Интерпретация вывода Docker Diff
Каждая строка вывода, создаваемая docker diff
, имеет префикс A
, C
или D
в зависимости от типа произошло изменение:
A
— файл или каталог добавлен в файловую систему контейнера. Его нет на исходном изображении.C
— содержимое файла или каталога отличается от версии на изображении.D
– путь, присутствующий в изображении, удален из контейнера.
Эта информация позволяет быстро найти расхождения, которые могут объяснить отсутствующие данные или неожиданное поведение.
Любые изменения файловой системы, которые не отображаются в выходных данных, повлияют на пути, сопоставленные с томом Docker. Эти файлы хранятся вне контейнера, независимо от его файловой системы, поэтому они не отображаются с помощью docker diff
.
Просмотр содержимого в исходном изображении
Может быть полезно сравнить версию файла, которая включена в исходное изображение. Вы можете сделать это, создав новый контейнер, а затем скопировав файл. Используйте docker create
вместо docker run
, чтобы контейнер был создан, но не запущен. Это гарантирует, что изменения, вызванные сценарием точки входа изображения, не повлияют на результат.
$ docker create --name temp-container my-image:latest $ docker cp temp-container:/path/to/file copied-file $ docker rm temp-container
Альтернативный способ — запустить контейнер с настраиваемой точкой входа, которая передает содержимое файла в стандартный поток вывода. Включите флаг --rm
, чтобы контейнер автоматически удалялся после завершения команды:
$ docker run --rm --entrypoint cat alpine:latest /path/to/file > copied-file
Сравнение различий между двумя контейнерами
Иногда вам может понадобиться сравнить различия между двумя разными контейнерами, на которых работает один и тот же образ. Сначала используйте docker diff
, чтобы получить отдельные списки изменений:
$ docker diff first-container > first $ docker diff second-container > second
Теперь вы можете использовать стандартные инструменты Unix, такие как команда diff
, чтобы найти различия в двух списках изменений:
diff first second 3c3 < A /a-new-file --- > A /demo
Разница показывает, что /a-new-file
был удален во втором контейнере, а /demo
был добавлен.
Другой способ сравнить контейнеры — использовать docker export
и команду tar для доступа к полному списку файлов:
$ docker export demo-container | tar tv -rwxr-xr-x 0/0 0 2022-06-21 14:21 .dockerenv drwxr-xr-x 0/0 0 2022-05-23 17:51 bin/ lrwxrwxrwx 0/0 0 2022-05-23 17:51 bin/arch -> /bin/busybox lrwxrwxrwx 0/0 0 2022-05-23 17:51 bin/ash -> /bin/busybox lrwxrwxrwx 0/0 0 2022-05-23 17:51 bin/base64 -> /bin/busybox lrwxrwxrwx 0/0 0 2022-05-23 17:51 bin/bbconfig -> /bin/busybox ...
Повторите эту команду для обоих контейнеров. Затем вы можете использовать diff
для сравнения двух списков. Расширенный вывод tar может помочь вам отследить, когда файлы были изменены, поскольку отображаются время модификации и разрешения.
Краткое содержание
Файловые системы контейнеров Docker должны очень напоминать образ, из которого они были созданы. Расхождения могут возникать, когда программное обеспечение внутри контейнера записывает содержимое непосредственно в файловую систему. Пользователи могут быть еще одним источником различий, когда такие механизмы, как docker exec
, используются для запуска команд в работающем контейнере.
Утилита docker diff
предоставляет удобный способ просмотра этих изменений. Хотя вы не можете видеть, почему файл был добавлен или удален, возможность получить список модификаций может оказаться бесценной для понимания того, почему наблюдается конкретное поведение.
В этой статье мы сосредоточились на изучении изменений, внесенных в работающие контейнеры. Вы можете использовать различные инструменты, такие как docker history
и Dive, для проверки изменений, внесенных в слои в образе Docker. Эти два подхода можно использовать в тандеме, что позволяет определить точную точку, в которой файл был добавлен или изменен в стеке слоев контейнера.