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

98

Я не могу найти способ переместить контейнеры с запущенным докером с одного хоста на другой.

Можно ли каким-то образом отправить свои контейнеры в репозитории, как мы делаем это для изображений? В настоящее время я не использую тома данных для хранения данных, связанных с приложениями, работающими внутри контейнеров. Таким образом, некоторые данные находятся внутри контейнеров, и я хочу сохранить их перед изменением конфигурации.

Динеш Редди
источник
Взгляните на flocker github.com/ClusterHQ/flocker
Адриан Муат,
Обратите внимание, что вы можете захотеть использовать сохранение / загрузку вместо экспорта / импорта, поскольку при сохранении сохраняются метаданные и история.
Burstaholic
Должен ли это быть комментарий к ответу @aholt?
Мартин Томпсон
docker saveпредназначен для сохранения изображений, а не контейнеров. docs.docker.com/engine/reference/commandline/save
stmllr 09

Ответы:

57

Вы не можете переместить работающий док-контейнер с одного хоста на другой.

Вы можете зафиксировать изменения в вашем контейнере в образе с помощью docker commit, переместить изображение на новый хост, а затем запустить новый контейнер с помощью docker run. Это сохранит все данные, которые ваше приложение создало внутри контейнера.

Nb: он не сохраняет данные, которые хранятся внутри томов; вам необходимо вручную переместить тома данных на новый хост.

ларски
источник
@larsks Разве сначала не нужно остановить контейнер, а затем выполнить фиксацию?
valentt 06
@valentt Оба варианта возможны, чтобы зафиксировать работающий и остановленный контейнер
crollywood
2
Этот ответ на самом деле не объясняет, какие именно команды вам нужно использовать, что затрудняет работу такого новичка, как я,
Пол Крюгер
docker-checkpoint может позволить вам перемещать «работающий» контейнер между хостами, если они оба поддерживают CRIU.
dGRAMOP
2
1. остановите контейнер docker stop x; 2. зафиксировать изменения ur docker commit -p x x; 3. сохранить контейнер в образ docker save -o x x; 4. переместите файл x на новый хост и на новом хосте загрузите новый образ dokcer load -i x(если вы запустили контейнер с -vопцией, вам также придется переместить эти файлы на новый хост); 5. запустите это изображение с помощьюdocker run (-v is required to mount these files if needed)
Lau Real
95

В качестве альтернативы, если вы не хотите отправлять данные в репозиторий:

  1. Экспорт контейнера в архив

    docker export <CONTAINER ID> > /home/export.tar
    
  2. Переместите ваш tarball на новую машину

  3. Импортировать обратно

    cat /home/export.tar | docker import - some-name:latest
    
Ахольт
источник
8
Также не сохраняет данные, которые хранятся внутри томов.
stmllr 09
1
Как это должно работать? После импорта я получаю новое изображение, и что дальше? Просто выполните новую команду запуска?
valentt 03
2
На самом деле это действительно плохое предложение, особенно для контейнеров с базой данных. Я попробовал это предложение, но оно не сработало. Может ли он сначала сработать с остановкой контейнера?
valentt 06
2
Это предложение действительно было только альтернативой. Это может сработать в вашей ситуации, а может и нет. Что касается меня, в то время я настраивал докер-контейнеры для репликации базы данных, а для экспорта / импорта не заботился о сохранении данных, так как я регулярно выполнял резервные копии данных базы данных в другой архив. Для этого это сработало отлично.
Aholt 06
32

Что в конечном итоге сработало для меня, после множества запутанных руководств и запутанных руководств, поскольку Docker, очевидно, на момент написания моей статьи был на грани завышенных ожиданий , так это:

  1. Сохраните образ докера в архив:
    docker save image_name > image_name.tar
  2. скопировать на другую машину
  3. на этой другой машине-докере запустите загрузку докера следующим образом:
    cat image_name.tar | docker load

Экспорт и импорт, как предлагается в других ответах, не экспортируют порты и переменные, которые могут потребоваться для запуска вашего контейнера. И вы можете получить что-то вроде «Команда не указана» и т. Д. Когда вы пытаетесь загрузить ее на другой компьютер.

Итак, разница между сохранением и экспортом заключается в том, что команда сохранения сохраняет все изображение с историей и метаданными, а команда экспорта экспортирует только структуру файлов (без истории или метаданных).

Излишне говорить, что, если у вас уже есть эти порты, задействованные в гипервизоре докеров, который вы импортируете, каким-либо другим контейнером докеров, вы столкнетесь с конфликтом, и вам придется перенастроить открытые порты.

Александар Павич
источник
1
Очень полезно. Сообщение «Не указана команда» сводило меня с ума.
Rintoul
Сообщение «Не указана команда» тоже сводило меня с ума. Я использую docker commit <container-id> stackstorm-local: 2.9 и docker pull stackstorm-local: 2.9 с другого хоста.
Хуа Чжан
18

Из документации Docker:

docker exportне экспортирует содержимое томов, связанных с контейнером. Если том смонтирован поверх существующего каталога в контейнере, docker exportэкспортируется содержимое базового каталога, а не содержимое тома. См резервного копирования, восстановления или переноса объемов данных в руководстве пользователя для примера на экспорт данных в объеме.

Антонио де Маринис
источник
завершение работы кластера ... и, кстати, для переноса контейнера контейнер должен работать на ZFS / любом поддерживаемом lun хранилища
asvignesh
6

Используйте этот скрипт: https://github.com/ricardobranco777/docker-volumes.sh

Это делает сохранение данных в объемах.

Пример использования:

# Stop the container   
docker stop $CONTAINER

# Create a new image   
docker commit $CONTAINER $CONTAINER

# Save image
docker save -o $CONTAINER.tar $CONTAINER

# Save the volumes (use ".tar.gz" if you want compression)
docker-volumes.sh $CONTAINER save $CONTAINER-volumes.tar

# Copy image and volumes to another host
scp $CONTAINER.tar $CONTAINER-volumes.tar $USER@$HOST:

# On the other host:
docker load -i $CONTAINER.tar
docker create --name $CONTAINER [<PREVIOUS CONTAINER OPTIONS>] $CONTAINER

# Load the volumes
docker-volumes.sh $CONTAINER load $CONTAINER-volumes.tar

# Start container
docker start $CONTAINER
Рикардо Бранко
источник
1
У меня не работало на AWS Linux (Centos). В конце концов, я использовал низкотехнологичный подход, используя docker inspect, чтобы найти каталог тома, а затем вручную скопировал его.
JasonPlutext
@JasonPlutext Может быть, что-то связано с SELinux? У вас включен SELinux?
Рикардо Бранко
Получил: tar: Удаление
начального символа
@hjahan Это типичное сообщение tar. Не ошибка и даже не предупреждение.
Рикардо Бранко,
1

Я пробовал много решений для этого, и это то, что у меня сработало:

1. зафиксировать / сохранить контейнер в новый образ:

  1. ++ зафиксировать контейнер:
    # docker stop
    # docker commit CONTAINER_NAME
    # docker save --output IMAGE_NAME.tar IMAGE_NAME: TAG


ps: "В нашем контейнере CONTAINER_NAME есть смонтированный том в '/ var / home'" (вы должны проверить свой контейнер, чтобы указать путь к его тому: # docker inspect CONTAINER_NAME)

  1. ++ сохраните его объем: мы будем использовать образ Ubuntu, чтобы сделать это.
    # mkdir backup
    # docker run --rm --volumes-from CONTAINER_NAME -v $ {pwd} / backup: / backup ubuntu bash -c «cd / var / home && tar cvf /backup/volume_backup.tar.»

Теперь, когда вы посмотрите на $ {pwd} / backup, вы найдете наш том в формате tar.
До сих пор у нас есть изображение нашего контейнера 'IMAGE_NAME.tar' и его том volume_backup.tar.

Теперь вы можете воссоздать тот же старый контейнер на новом хосте.

Хусам Эззух
источник