Подтвердить что ты не робот

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". Возможно ли это?

Спасибо.

4b9b3361

Ответ 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