Как получить файл, который был добавлен, а затем удален в образе Docker?

Чтобы заменить первую строку ожидаемой меткой времени, просто используйте

sed "1c TS: $(date '+%F %T')"

1 в начале означает первая строка, c означает «заменить строку следующей строкой». $ (...) вставляет вывод данной команды, см. man date для получения подробной информации.

0
10.02.2019, 01:53
1 ответ

Is there a way (or several ways) to retrieve from the image, the contents of file.txt that was added then removed in an intermediate layer?

Да!

Does the answer depend on the choice of the WORKDIR?

Нет. WORKDIRне делает ничего, кроме изменения текущего рабочего каталога.


Когда вы создаете образ из Dockerfile, каждая директива в Dockerfile создает новый слой. «Образ» — это просто набор слоев, которые объединяются для формирования файловой системы контейнера при запуске контейнера. Каждый из этих слоев можно найти отдельно на вашем диске в /var/lib/docker. Например, предположим, что я создаю образ, используя этот Dockerfile:

FROM debian:9
COPY file.txt /root/file.txt
RUN rm -f /root/file.txt

В этом каталоге у меня есть файл с именем file.txt, который содержит текст:

hello world

Если я побегу docker build -t erikmd., я увижу:

Sending build context to Docker daemon  3.072kB
Step 1/3 : FROM debian:9
 ---> d508d16c64cd
Step 2/3 : COPY file.txt /root/file.txt
 ---> Using cache
 ---> 6f06029c1cca
Step 3/3 : RUN rm -f /root/file.txt
 ---> Using cache
 ---> a2dc62c823c9
Successfully built a2dc62c823c9
Successfully tagged erikmd:latest

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

$ docker run --rm 6f06029c1cca cat /root/file.txt

И посмотреть содержимое файла:

hello world

Но что, если я не просто построил образ? В этом случае я бы начал с использования команды docker image inspectдля просмотра списка слоев, составляющих изображение :

.
$ docker image inspect erikmd | jq '.[0].RootFS.Layers'
[
  "sha256:13d5529fd232cacdd8cd561148560e0bf5d65dbc1149faf0c68240985607c303",
  "sha256:41494b03ef195ce6db527bd68b89cbebdace66210b4c142e95f8553fcb0bf51e",
  "sha256:1948a4bd00b6f1712667bb2c68d1fe6eb60fbbcdf8bad62653208c23bf2602a5"
]

В приведенном выше примере jq— это просто инструмент для запроса данных JSON. Вы можете просто визуально проверить вывод docker image inspectдля получения той же информации, если у вас нет под рукой jq.

Предполагая, что конфигурация Docker по умолчанию использует драйвер хранилища overlay2, вы найдете эти идентификаторы в /var/lib/docker/image/overlay2/layerdb/sha256/*/diff. Так, например:

# grep -l 13d5529fd232cacdd8cd561148560e0bf5d65dbc1149faf0c68240985607c303 \
  /var/lib/docker/image/overlay2/layerdb/sha256/*/diff
/var/lib/docker/image/overlay2/layerdb/sha256/13d5529fd232cacdd8cd561148560e0bf5d65dbc1149faf0c68240985607c303/diff

Этот первый слой является изображением debian:9. Мы можем подтвердить это, запустив:

$ docker image inspect debian:9 | jq '.[0].RootFS.Layers'
[
  "sha256:13d5529fd232cacdd8cd561148560e0bf5d65dbc1149faf0c68240985607c303"
]

...так что проигнорируем. Найдем второй слой:

# grep -l 41494b03ef195ce6db527bd68b89cbebdace66210b4c142e95f8553fcb0bf51e \
  /var/lib/docker/image/overlay2/layerdb/sha256/*/diff
/var/lib/docker/image/overlay2/layerdb/sha256/14347a192896a59fdf5c1a9ffcac2f93025433c66136d3531d7bbb3aec53efc7/diff

Внутри того же каталога, что и этот файл diff, мы найдем файл с именемcache-id:

# cat image/overlay2/layerdb/sha256/14347a192896a59fdf5c1a9ffcac2f93025433c66136d3531d7bbb3aec53efc7/cache-id
118b1e4a401873e1db8849c0821d0280b4cf9ef621ccb70cf14fe672dc74ef75

Что cache-idидентифицирует каталог, в который был извлечен слой; мы можем найти его под/var/lib/docker/overlay2/<id>:

# ls /var/lib/docker/overlay2/118b1e4a401873e1db8849c0821d0280b4cf9ef621ccb70cf14fe672dc74ef75
diff/ link lower work/

Нас интересует содержимое каталога diff/:

# find /var/lib/docker/overlay2/118b1e4a401873e1db8849c0821d0280b4cf9ef6
21ccb70cf14fe672dc74ef75/diff/
/var/lib/docker/overlay2/118b1e4a401873e1db8849c0821d0280b4cf9ef621ccb70cf14fe672dc74ef75/diff/
/var/lib/docker/overlay2/118b1e4a401873e1db8849c0821d0280b4cf9ef621ccb70cf14fe672dc74ef75/diff/root
/var/lib/docker/overlay2/118b1e4a401873e1db8849c0821d0280b4cf9ef621ccb70cf14fe672dc74ef75/diff/root/file.txt

Вот оно!


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

5
28.01.2020, 02:23

Теги

Похожие вопросы