Витягнути файл із зображення докера?


24

Я хотів би витягнути файл із зображення Докера, не запускаючи зображення.

Цей docker saveпараметр для мене не є життєздатним варіантом, оскільки він дозволяє економити занадто величезний файл лише для того, щоб скасувати націлювання на певний файл.


Який дистрибутив ви використовуєте?
ryekayo

@ryekayo: Ubuntu 14, докер 1.12.4 (api 1.24)
BlakBat

Відповіді:


21

Ви можете витягти файли із зображення за допомогою таких команд:

docker create $image  # returns container ID
docker cp $container_id:$source_path $destination_path
docker rm $container_id

Згідно з docker create документацією , цей контейнер не запускає:

docker createКоманда створює записується шар поверх контейнер зазначеного зображення і готує його для виконання зазначеної команди. Потім ідентифікатор контейнера друкується в STDOUT. Це аналогічно docker run -dтому, що контейнер ніколи не запускається. Потім можна використовувати docker start <container_id>команду для запуску контейнера в будь-якій точці.


Для довідки (моя попередня відповідь) менш ефективним способом вилучення файлу із зображення є наступний:

docker run some_image cat $file_path > $output_path

3
Можливо, ви захочете перевищити точку входу. docker run --entrypoint /bin/sh my_image -c /bin/cat some_file
Ендрю

1
Це запускає зображення, яке саме я не хотів робити, як зазначено в моєму запитанні.
BlakBat

Ах, це хороший момент. Я згоден, то моя нинішня відповідь не задовольняє тоді.
bbc

1
@BlakBat Чи працює ця оновлена ​​відповідь? Я думаю, я мав би створити нову відповідь, але це зроблено зараз.
bbc

1
@bbc Ця оновлена ​​відповідь насправді не запускає контейнер (суть питання) і не потребує root.
BlakBat

2

Ніщо з перерахованого вище не працювало для мене. Повна робоча команда:

docker run --rm --entrypoint /bin/sh image_name -c "cat /path/filename" > output_filename

Без лапок catпередається без імені файлу, тому він не знає, що показати. Також корисно видалити контейнер після завершення команди.


Команда, на яку ви посилаєтесь, працюватиме лише залежно від докера та того, як правильно було встановлено ENTRYPOINT / CMD у Dockerfile; це не має нічого спільного з цитуванням. Ви також скажете видалити контейнер, але ви вказали - rm. Нарешті, коли я опублікував своє запитання, я вказав "без необхідності запускати зображення", і відповіді не були рішенням, що враховувало це.
BlakBat

1
Незалежно від того, які CMD та ENTRYPOINT були встановлені в Dockerfile, я перекриваю обидва, так що це буде працювати завжди (звичайно на Linux). Що ви маєте на увазі під "залежно від докера"? Налаштування, версія, env, що? Ви ставите запитання невірно, оскільки зображення неможливо виконати, лише контейнери. Я думаю, що правильної відповіді немає, вам доведеться мати багато файлів або створити тимчасовий контейнер. - rm видаляє тимчасовий контейнер, відповіді інших залишають небагато сміття на вашому диску.
Секрет

1

Якщо я не помиляюся, я вважаю, що контейнери докера зберігають кешовані файли, створені в наступному каталозі для Ubuntu:

/var/lib/docker/aufs/diff/<container_id>

Звідти ви маєте змогу отримати доступ до файлової системи та отримати свої файли (файли).


Ні. Цей каталог містить лише layersizeі jsonне є читабельним для користувачів (навіть якщо користувач перебуває в групі докерів). /var/lib/docker/aufs/diffміститиме файл, який я шукаю (але класифікується не за ідентифікатором контейнера), а також не читабельний.
BlakBat

Дайте мені декілька, і я погляну. Я знаю, що існує спосіб відновити файли, не входячи в контейнер і не запускаючи його.
ryekayo

Як не читається, як це відображається? Я знайшов приклад, коли можна витягувати текстові файли з контейнерів, перейшовши до каталогу / var / lib / docker / aufs / diff / *
ryekayo

Моя помилка. Користувач може отримати доступ /var/lib/docker/aufs(але не до всіх інших каталогів /var/lib/docker/)
BlakBat

Чи можете ви отримати доступ до root?
ryekayo

0

Якщо зберігання повного виводу docker saveне є варіантом, ви можете використовувати конвеєри, щоб витягти з нього лише потрібний файл.

На жаль, оскільки вихід є «дьогтю тар», це може бути трохи ітераційним процесом.

Що я робив тоді, коли мені потрібно було витягти файл, було:

1) Визначте, для якої версії зображення останнім часом змінився файл, який вас цікавить (як це зробити, ймовірно, залежить від вашого зображення), і дата його створення / збереження

2) Отримайте повну таблицю вмісту з виводу docker saveкоманди за допомогою:

docker save IMAGE_NAME | tar -tvf -

3) Визначте layer.tarфайли (файли) у висновку цієї команди, які відповідають даті зображення, визначеному на кроці 1. (ви можете додати, | grep layer.tarщоб просто показати ці файли)

4) Витягніть цей layer.tarфайл до стандартного та отримайте його зміст:

docker save IMAGE_NAME | tar -xf - -O CHECKSUM_FROM_LIST/layer.tar | tar -tvf -

5) Перевірте, чи потрібний файл є в списку, і витягніть його, як тільки знайдете ім'я:

docker save IMAGE_NAME | tar -xf - -O CHECKSUM_FROM_LIST/layer.tar | tar -xf - PATH/TO/YOUR/FILE

Якщо layer.tarна кроці 2/3 є кілька файлів, які відповідають даті, яку ви шукаєте, можливо, вам доведеться повторити крок 4 для кожного з них, поки не знайдете потрібний

Замініть текст великими літерами в командах вище на правильні назви зображень, контрольні суми та назви файлів для вашої справи.

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.