Docker: как показать различия между двумя изображениями
У меня есть файл Docker с последовательностью инструкций RUN, которые выполняют "apt-get install" s; например, пару строк:
RUN apt-get install -y tree
RUN apt-get install -y git
После выполнения "сборки докеров", если я затем выполняю "изображения докеров -a", я вижу список всех образов base-child-child -...., которые были созданы во время сборки.
Мне бы хотелось увидеть список всех пакетов, которые были установлены, когда была выполнена строка "apt-get install -y git" (включая зависимые пакеты, которые также могут быть установлены, кроме git).
Примечание. Я считаю, что команда "docker diff" показывает разницу между контейнером и изображением, с которого оно было запущено. Вместо этого мне бы хотелось, чтобы разница между двумя изображениями (одного и того же родословного): идентификаторы изображений "дерево" и "git". Возможно ли это?
Спасибо.
Ответы
Ответ 1
Каждая инструкция RUN создает новый контейнер, и вы можете проверить, какой контейнер был изменен с помощью docker diff <container>
.
Итак, после создания файла docker запустите docker ps -a
, чтобы получить список контейнеров, созданных в файле build. Он должен выглядеть примерно так:
CONTAINER ID IMAGE COMMAND CREATED STATUS ...
53d7dadafee7 f71e394eb0fc /bin/sh -c apt-get i 7 minutes ago Exit 0 ...
...
Теперь вы можете сделать docker diff 53d7dadafee7
, чтобы увидеть, что было изменено.
Ответ 2
Я полагаю, что вы можете отправить обе файловые системы изображений в тарболы с помощью docker export CONTAINER_ID
или docker save IMAGE_ID
(обновляется на основе комментариев)
Затем используйте любой инструмент для разбивки файловых систем - Git, Rdiff и т.д.
Ответ 3
Посмотри на:
https://github.com/GoogleCloudPlatform/container-diff
Этот инструмент может различать локальные или удаленные образы докера и может делать это без необходимости установки докера. Он имеет как файл, так и уровень пакета "отличается" (например: apt, npm и pip), чтобы вам было легче видеть различия в пакетах, которые изменились между двумя образами докеров.
Отказ от ответственности: я участник этого проекта
Ответ 4
Если вы знаете идентификатор или имя контейнера (даже остановленный контейнер),
вы можете быстро сбрасывать список файлов на лету.
$ docker export CONTAIN_ID_OR_NAME | tar tv
-rwxr-xr-x 0 0 0 0 2 6 21:22 .dockerenv
-rwxr-xr-x 0 0 0 0 2 6 21:22 .dockerinit
drwxr-xr-x 0 0 0 0 10 21 13:46 bin/
-rwxr-xr-x 0 0 0 1021112 10 8 2014 bin/bash
-rwxr-xr-x 0 0 0 31152 10 21 2013 bin/bunzip2
-rwxr-xr-x 0 0 0 0 10 21 2013 bin/bzcat link to bin/bunzip2
lrwxrwxrwx 0 0 0 0 10 21 2013 bin/bzcmp -> bzdiff
-rwxr-xr-x 0 0 0 2140 10 21 2013 bin/bzdiff
lrwxrwxrwx 0 0 0 0 10 21 2013 bin/bzegrep -> bzgrep
-rwxr-xr-x 0 0 0 4877 10 21 2013 bin/bzexe
......
Затем вы можете сохранить список в файл и сравнить слишком файлы списков.
Если вы настаиваете на использовании идентификатора или имени изображения, вы можете выгрузить список файлов первого уровня на лету:
$ docker save alpine |tar xO '*/layer.tar' | tar tv
drwxr-xr-x 0 0 0 0 12 27 06:32 bin/
lrwxrwxrwx 0 0 0 0 12 27 06:32 bin/ash -> /bin/busybox
lrwxrwxrwx 0 0 0 0 12 27 06:32 bin/base64 -> /bin/busybox
lrwxrwxrwx 0 0 0 0 12 27 06:32 bin/bbconfig -> /bin/busybox
-rwxr-xr-x 0 0 0 821408 10 27 01:15 bin/busybox
В конце концов, я предлагаю вам запустить контейнер, а затем остановить его, тогда вы можете получить список объединенных файлов, как описано в первую очередь.
2017/02/01: Самый быстрый способ показать список файлов контейнеров, вы можете ввести его корневой каталог для чтения файлов.
# PID=$(docker inspect -f '{{.State.Pid}}' CONTAIN_ID_OR_NAME)
# cd /proc/$PID/root && ls -lF
drwxr-xr-x 0 0 0 0 12 27 06:32 bin/
lrwxrwxrwx 0 0 0 0 12 27 06:32 bin/ash -> /bin/busybox
lrwxrwxrwx 0 0 0 0 12 27 06:32 bin/base64 -> /bin/busybox
lrwxrwxrwx 0 0 0 0 12 27 06:32 bin/bbconfig -> /bin/busybox
-rwxr-xr-x 0 0 0 821408 10 27 01:15 bin/busybox
Примечание. Если вы используете докер-машину, вам нужно сначала ввести ее
docker-machine ssh
, затем sudo sh
.
Теперь вы получаете корневую директорию из двух контейнеров, вы можете использовать diff, чтобы сравнивать их напрямую.
Ответ 5
Посмотри на:
https://github.com/moul/docker-diff
В них перечислены инструкции по установке Brew
для Mac, я предполагаю, что это скрипт Bash, поэтому я предполагаю, что он может быть настроен для работы в других * nix средах.
Ответ 6
Этот работал для меня:
docker run -it e5cba87ecd29 bash -c 'find /path/to/files -type f | sort | xargs -I{} sha512sum {}' > /tmp/dockerfiles.e5cba87ecd29.txt
docker run -it b1d19fe1a941 bash -c 'find /path/to/files -type f | sort | xargs -I{} sha512sum {}' > /tmp/dockerfiles.b1d19fe1a941.txt
meld /tmp/dockerfiles*
Где e5cba87ecd29 и b1d19fe1a941 - изображения, которые меня интересуют, а /path/to/files - это каталог, который может быть "/". Он перечисляет все файлы, сортирует его и добавляет к нему хэш на всякий случай. И смесь подчеркивает все различия.
Ответ 7
Сейчас 2019 год, и я только что нашел полезный инструмент, который был выпущен в конце 2017 года. Https://opensource.googleblog.com/2017/11/container-diff-for-comparing-container-images.html
Следующее содержимое со страницы container-diff github:
container-diff diff <img1> <img2> --type=history [History]
container-diff diff <img1> <img2> --type=file [File System]
container-diff diff <img1> <img2> --type=size [Size]
container-diff diff <img1> <img2> --type=rpm [RPM]
container-diff diff <img1> <img2> --type=pip [Pip]
container-diff diff <img1> <img2> --type=apt [Apt]
container-diff diff <img1> <img2> --type=node [Node]
Вы также можете запустить несколько анализаторов одновременно:
container-diff diff <img1> <img2> --type=history --type=apt --type=node