Как перенести тома, содержащие только данные, с одного хоста на другой?

121

Как описано в документации Docker по работе с томами, существует концепция так называемых контейнеров только для данных , которые предоставляют том, который может быть смонтирован в несколько других контейнеров, независимо от того, работает ли контейнер только для данных на самом деле или нет.

В общем, звучит потрясающе. Но одного я не понимаю.

Эти тома (которые явно не сопоставляются с папкой на хосте по причинам переносимости, как указано в документации) создаются и управляются Docker в некоторой внутренней папке на хосте ( /var/docker/volumes/…).

Предположим, я использую такой том, а затем мне нужно перенести его с одного хоста на другой - как мне перенести том? AFAICS имеет уникальный идентификатор - могу ли я просто скопировать том и соответствующий контейнер только для данных на новый хост? Как узнать, какие файлы копировать? Или в Docker встроена поддержка, которую я еще не обнаружил?

Голо Роден
источник
12
Вы можете экспортировать каталог контейнера данных: docker run --volumes-from <data container> ubuntu tar -cO <volume path> | gzip -c > volume.tgzэто не зависит от деталей реализации томов. И импортируйте данные с tar на вторую машину.
Jiri
1
Ого, классно, спасибо :-)))! Если вы напишете этот комментарий в качестве ответа, я с радостью его приму!
Голо Роден

Ответы:

136

Официальный ответ доступен в разделе «Резервное копирование, восстановление или перенос томов данных» :

РЕЗЕРВНОЕ КОПИРОВАНИЕ:

sudo docker run --rm --volumes-from DATA -v $(pwd):/backup busybox tar cvf /backup/backup.tar /data
  • --rm: удалить контейнер, когда он выходит
  • --volumes-from DATA: прикрепить к томам, совместно используемым контейнером DATA
  • -v $(pwd):/backup: bind смонтировать текущий каталог в контейнер; записать tar-файл в
  • busybox: небольшое более простое изображение - удобное для быстрого обслуживания
  • tar cvf /backup/backup.tar /data: создает несжатый tar-файл всех файлов в каталоге / data

ВОССТАНОВИТЬ:

# create a new data container
$ sudo docker create -v /data --name DATA2 busybox true
# untar the backup files into the new container᾿s data volume
$ sudo docker run --rm --volumes-from DATA2 -v $(pwd):/backup busybox tar xvf /backup/backup.tar
data/
data/sven.txt
# compare to the original container
$ sudo docker run --rm --volumes-from DATA -v `pwd`:/backup busybox ls /data
sven.txt
tommasop
источник
3
На данный момент лучше использовать docker createдля контейнеров только с данными, чтобы они не запускались. Пример в офф. документация: docs.docker.com/userguide/dockervolumes/…
FelikZ
1
Итак ... Если я пытаюсь сделать резервную копию базы данных Postgres, что бы я заменить /dataс /var/lib/postgresql/data, правильно?
425nesp
6
Раздел «Резервное копирование, восстановление или перенос томов данных», похоже, был удален из документации Docker :-(
SteveC
2
@Datz - это просто команда, вызываемая для создания контейнера данных, это может быть любая команда, которая на самом деле ничего не делает. Контейнер запускается и немедленно закрывается, но он используется для сохранения данных.
tommasop
1
@rszalski Если по какой-то причине вам нужно, чтобы контейнер продолжал работать (скажем, вы хотите docker execв него войти), тогда простая команда tail -f /dev/nullникогда не завершится, но использует минимальные ресурсы. Когда он вам больше не нужен, он docker stop data-containerсделает это за вас. Объемы остаются для других контейнеров.
Джесси Чизхолм
16

Вы можете экспортировать том в tar и перенести на другую машину. И импортируйте данные с tar на вторую машину. Это не зависит от деталей реализации томов.

# you can list shared directories of the data container
docker inspect <data container> | grep "/vfs/dir/"

# you can export data container directory to tgz
docker run --cidfile=id.tmp --volumes-from <data container> ubuntu tar -cO <volume path> | gzip -c > volume.tgz

# clean up: remove exited container used for export and temporary file
docker rm `cat id.tmp` && rm -f id.tmp
Иржи
источник
спасибо за Ваш ответ. Как перенести контейнер данных с одного хоста на другой?
Джунг Нгуен
1
@nXqd Контейнер данных создается docker run -v /data-volume -name datacointainer busybox true- вы можете запустить его где угодно. После создания контейнера данных вы можете импортировать tar-архив, как описано в ответе.
Jiri
Спасибо за Ваш ответ. Но я столкнулся с другой проблемой: нам нужно удалить контейнер зомби, который впоследствии используется для резервного копирования. Поскольку это не возвращает id. У вас есть хороший способ: D
Джунг Нгуен
@nXqd Конечно - вы должны использовать в --cidfile=id.txtкачестве параметра запуска. Идентификатор контейнера будет сохранен в файле id.txt. Я обновил ответ.
Иржи
9
Вы можете просто использовать docker run --rmвместо docker run --cidfile ... ; docker rm.
Felix Rabe
16

Расширение официального ответа из документов Docker и главный ответ здесь , вы можете иметь следующие псевдонимы в своих .bashrc или .zshrc

# backup files from a docker volume into /tmp/backup.tar.gz
function docker-volume-backup-compressed() {
  docker run --rm -v /tmp:/backup --volumes-from "$1" debian:jessie tar -czvf /backup/backup.tar.gz "${@:2}"
}
# restore files from /tmp/backup.tar.gz into a docker volume
function docker-volume-restore-compressed() {
  docker run --rm -v /tmp:/backup --volumes-from "$1" debian:jessie tar -xzvf /backup/backup.tar.gz "${@:2}"
  echo "Double checking files..."
  docker run --rm -v /tmp:/backup --volumes-from "$1" debian:jessie ls -lh "${@:2}"
}
# backup files from a docker volume into /tmp/backup.tar
function docker-volume-backup() {
  docker run --rm -v /tmp:/backup --volumes-from "$1" busybox tar -cvf /backup/backup.tar "${@:2}"
}
# restore files from /tmp/backup.tar into a docker volume
function docker-volume-restore() {
  docker run --rm -v /tmp:/backup --volumes-from "$1" busybox tar -xvf /backup/backup.tar "${@:2}"
  echo "Double checking files..."
  docker run --rm -v /tmp:/backup --volumes-from "$1" busybox ls -lh "${@:2}"
}

Обратите внимание, что резервная копия сохраняется в /tmp, поэтому вы можете перемещать сохраненный файл резервной копии между хостами докеров.

Также есть две пары псевдонимов резервного копирования / восстановления. Один использует сжатие и debian: jessie, а другой - без сжатия, но с busybox. Используйте сжатие, если файлы для резервного копирования большие.

Луис Бьянчин
источник
3

Я добавлю сюда еще один недавний инструмент от IBM, который на самом деле предназначен для переноса томов с одного контейнера на другой. Это текущий проект. Так что в будущем вы можете найти другую версию с дополнительными функциями.

Cargo был разработан для миграции контейнеров с одного хоста на другой вместе с их данными с минимальным временем простоя. Cargo использует возможности объединения данных файловой системы union для создания единого представления данных (в основном корневой файловой системы) на исходном и целевом хостах. Это позволяет Cargo запускать контейнер почти сразу (в течение миллисекунд) на целевом хосте, поскольку данные из исходной корневой файловой системы копируются на целевые хосты либо по требованию (с использованием раздела копирования при записи (COW) ), либо лениво. в фоновом режиме (с помощью rsync) .

Важные моменты: - centralizedсервер обрабатывает процесс миграции

Ссылка на проект здесь:

https://github.com/nadgowdas/cargo
Ариф А.
источник
3

Если ваши машины находятся в разных VPC или вы хотите скопировать с / на локальную машину (как в моем случае), вы можете использовать созданный мной dvsync . По сути, это ngrok в сочетании с rsyncSSH, упакованный в два небольших (~ 25 МБ) образа. Сначала вы запускаете dvsync-serverна машине, с которой хотите скопировать данные (вам понадобится та, NGROK_AUTHTOKENкоторую можно получить с панели инструментов ngrok ):

$ docker run --rm -e NGROK_AUTHTOKEN="$NGROK_AUTHTOKEN" \
  --mount source=MY_VOLUME,target=/data,readonly \
  quay.io/suda/dvsync-server

Затем вы можете запустить dvsync-clientна машине, на которую хотите скопировать файлы, передавая DVSYNC_TOKENпоказанный сервером:

docker run -e DVSYNC_TOKEN="$DVSYNC_TOKEN" \
  --mount source=MY_TARGET_VOLUME,target=/data \
  quay.io/suda/dvsync-client 

Как только копирование будет выполнено, клиент выйдет. Это также работает с Docker CLI, Compose, Swarm и Kubernetes.

Suda
источник