Копирование файлов между Docker контейнером и хостом
Docker — программная платформа, позволяющая быстро создавать, тестировать и разворачивать приложения с помощью контейнеров.
В Docker часто возникает необходимость копирования файлов между хостом и контейнерами. Это удобно для файлов конфигурации, скриптов или любых других данных, которые должны быть доступны в среде контейнера. Например:
- Отладка проблем с контейнерами
- Резервное копирование и восстановление данных
- Изменение файлов конфигурации
В этой статье мы рассмотрим два метода копирования файлов или папок в контейнеры Docker и из них.
Метод 1: Использование команды docker cp
Обычно для копирования файлов или папок между контейнером и хостом, независимо от того, запущен контейнер или остановлен, используется команда docker cp
.
Копирование файлов из контейнера Docker
Использование: docker cp [OPTIONS] container:src_path dest_path
container
— имя или идентификатор контейнера, из которого требуется скопировать.src_path
— путь внутри контейнера к файлу или папке, которую требуется скопировать.dest_path
— путь на хосте к файлу или папке, в которую требуется скопировать. Используйте-
для указания стандартного вывода.
Например, скопируем файл /etc/ssh/sshd_config
на хост (f5732ee3d33c
— идентификатор контейнера):
docker cp f5732ee3d33c:/etc/ssh/sshd_config /root/ssh-changes
Successfully copied 5.12kB to /root/ssh-changes
Скопируем папку /var/log
на хост:
docker cp f5732ee3d33c:/var/log /root/ssh-changes
Successfully copied 768kB to /root/ssh-changes
Скопируем файл /etc/ssh/sshd_config
в STDOUT
. Это просто как печать содержимого файла:
docker cp f5732ee3d33c:/etc/ssh/sshd_config -
sshd_config0000644000000000000000000000624714606114611011466 0ustar0000000000000000
# This is the sshd server system-wide configuration file. See
# sshd_config(5) for more information.
# This sshd was compiled with PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games
# The strategy used for options in the default sshd_config shipped with
# OpenSSH is to specify options with their default value where
# possible, but leave them commented. Uncommented options override the
# default value.
Include /etc/ssh/sshd_config.d/*.conf
#Port 22
....
Копирование файлов в контейнер Docker
Использование: docker cp [OPTIONS] src_path container:dest_path
container
— имя или идентификатор контейнера, в который требуется скопировать.src_path
— путь к файлу или папке на хосте, которую требуется скопировать. Используйте-
для обозначения стандартного ввода.dest_path
— путь внутри контейнера к файлу или папке, в которую требуется скопировать.
Например, скопируем файл /root/ssh-changes/sshd_config
в файл в контейнере /etc/ssh/sshd_config
(f5732ee3d33c
— идентификатор контейнера):
docker cp /root/ssh-changes/sshd_config f5732ee3d33c:/etc/ssh/sshd_config
Successfully copied 5.12kB to f5732ee3d33c:/etc/ssh/sshd_config
Скопируем папку /root/ssh-changes/log
в папку контейнера /tmp
(f5732ee3d33c
— идентификатор контейнера):
docker cp /root/ssh-changes/log f5732ee3d33c:/tmp
Successfully copied 768kB to f5732ee3d33c:/tmp
Извлечём tar из хоста в контейнер (f5732ee3d33c
— идентификатор контейнера):
docker cp - f5732ee3d33c:/tmp < /root/ssh-changes/apps.tar
Successfully copied 0B to f5732ee3d33c:/tmp
docker exec f5732ee3d33c ls -d /tmp/apps
/tmp/apps
Опции
Опция: -a
, --archive
С помощью этой опции команда docker cp
может сохранять исходные разрешения, права, специальные атрибуты и временные метки копируемых файлов. Если копируется каталог, то всё содержимое каталога будет скопировано рекурсивно.
Опция: -L
, --follow-link
С помощью опции команда docker cp
может следовать символическим ссылкам (symlinks) во время процесса копирования. При копировании каталога, содержащего символические ссылки, будет скопирован фактический файл или каталог, на который указывает символическая ссылка, а не сама символическая ссылка.
Опция: -q
, --quiet
С помощью этой опции команда docker cp может автоматически подавлять вывод прогресса при копировании с подключением терминала. Вывод прогресса автоматически подавляется без подключения терминала. Это может быть удобно в сценарии или если вы не хотите видеть вывод прогресса.
Метод 2: Копирование с «хоста»на «хост»
Он обычно используется для копирования файлов или папок между контейнером и хостом. Но этот метод копирует только на хосте, например из одной папки хоста в другую папку.
На самом деле, файловая система контейнера также находится на хосте. Таким образом, мы можем получить доступ к файловой системе контейнера непосредственно с хоста. Но где находится файловая система контейнера на хосте?
Прежде чем начать, давайте посмотрим драйвер хранилища Docker, выполнив следующие команды:
docker info | grep Storage
Storage Driver: overlay2
OverlayFS — файловая система, используемая по умолчанию драйвером overlay2
Docker для управления файловыми системами контейнеров.
Теперь запустим контейнер «hello».
docker run -dit --name hello ubuntu:latest
Выполним команду docker inspect
:
# docker container inspect hello | jq '.[0].GraphDriver'
{
"Data": {
"LowerDir": "/var/lib/docker/overlay2/1e04348e54577157f8945bfd16543b18910c6c9551e14ea2f3fd91cc29f200f6-init/diff:/ci_runner/dockerHome/overlay2/595b425d150311a9c2637426cdc200d9f7509a7f26653ee203b35c171e379e89/diff",
"MergedDir": "/var/lib/docker/overlay2/1e04348e54577157f8945bfd16543b18910c6c9551e14ea2f3fd91cc29f200f6/merged",
"UpperDir": "/var/lib/docker/overlay2/1e04348e54577157f8945bfd16543b18910c6c9551e14ea2f3fd91cc29f200f6/diff",
"WorkDir": "/var/lib/docker/overlay2/1e04348e54577157f8945bfd16543b18910c6c9551e14ea2f3fd91cc29f200f6/work"
},
"Name": "overlay2"
}
Мы можем увидеть 4 вида слоёв данных:
LowerDir
: слои образа, доступные только для чтения, содержат оригинальное содержимое файловой системы, включая слоиbootfs
иrootfs
. Эти слои образов могут быть собраны в стек. Слой LowerDir обеспечивает базовую структуру файловой системы контейнера.UpperDir
: расположен над слоем LowerDir, доступен для чтения и записи. При запуске контейнера слой UpperDir автоматически создаётся поверх финального слоя образа. Все изменения данных контейнера происходят в этом слое, и он имеет собственное состояние данных, не влияя на базовый образ.MergedDir
: объединяет LowerDir и UpperDir в единую структуру каталогов, обеспечивая единое представление контейнера. Изменения файлов в LowerDir или новые файлы, добавленные в UpperDir, будут перезаписаны или добавлены в MergedDir.WorkDir
: определяет рабочий каталог по умолчанию в контейнере. Он может быть задан с помощью инструкцииWORKDIR
вDockerfile
. Определение рабочей директории может быть полезно для организации файлов внутри контейнера.
Эти 4 слоя в совокупности обеспечивают полную структуру файловой системы и рабочую среду для контейнеров. Обратим внимание на MergedDir, где мы можем увидеть все файлы внутри контейнера.
Перейдя в /var/lib/docker/overlay2/1e04348e54577157f8945bfd16543b18910c6c9551e14ea2f3fd91cc29f200f6/merged
, можно увидеть все файлы в контейнере.
cd /var/lib/docker/overlay2/1e04348e54577157f8945bfd16543b18910c6c9551e14ea2f3fd91cc29f200f6/merged
ls
bin dev home lib32 libx32 mnt proc run srv tmp var
boot etc lib lib64 media opt root sbin sys usr
Таким образом, копирование файла или папки аналогично операции копирования на хосте с помощью команд Linux cp
, rync
и так далее.
Копирование файлов из контейнера Docker
Например: скопируем файл /var/log/last
из контейнера на хост в /tmp
:
cd /var/lib/docker/overlay2/1e04348e54577157f8945bfd16543b18910c6c9551e14ea2f3fd91cc29f200f6/merged
cp ./var/log/lastlog /tmp/
ls -l /tmp/lastlog
-rw-r--r-- 1 root root 29492 Apr 21 21:38 /tmp/lastlog
Копирование файлов в контейнер Docker
Например: скопируем файл из хоста в каталог /root
контейнера:
echo "hello!" > /tmp/hello.test
cd /var/lib/docker/overlay2/1e04348e54577157f8945bfd16543b18910c6c9551e14ea2f3fd91cc29f200f6/merged
cp /tmp/hello.test ./root/
Давайте проверим это, выполнив команду:
docker exec -it hello cat /root/hello.test
hello!
Мне нравится этот метод копирования файлов или папок между хостом и контейнерами. Я всегда пишу несколько скриптов для мониторинга конфигурационных файлов в контейнере. А также для резервного копирования или восстановления некоторых из них. В моих скриптах нет ни одной команды Docker. Я могу работать с tar
, rync
, ssh
… поскольку контейнер прозрачен. Но контейнер должен быть запущен и не может быть остановлен.