Как скопировать образы Docker с одного хоста на другой без использования репозитория

1376

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

Я создаю свой собственный образ в VirtualBox, и когда он заканчивается, я пытаюсь развернуть его на других машинах для реального использования.

Поскольку он основан на моем собственном образе (например, Red Hat Linux), он не может быть воссоздан из Dockerfile. Мой докер-файл не легко переносим.

Есть ли простые команды, которые я могу использовать? Или другое решение?

Ларри Кай
источник

Ответы:

2312

Вам нужно сохранить образ Docker в виде файла tar:

docker save -o <path for generated tar file> <image name>

Затем скопируйте файл на новую систему с обычными инструментами передачи файлов , такими как cp, scpили rsync(предпочтительнее для больших файлов). После этого вам нужно будет загрузить изображение в Docker:

docker load -i <path to image tar file>

PS: Вам могут понадобиться sudoвсе команды.

РЕДАКТИРОВАТЬ: Вы должны добавить имя файла (не просто каталог) с -o, например:

docker save -o c:/myfile.tar centos:16
Daiwei
источник
27
Это лучший ответ для изображений .
Энди
26
Кроме того, лучше использовать repo:tagв качестве ссылки на изображение, чем image id. Если вы используете image id, загруженное изображение не сохранит тег (и вам придется сделать еще один шаг, чтобы пометить изображение).
Висбуки
1
Я использовал идентификатор изображения вместо тега name: Теперь я сижу здесь, загружаю изображение и имею <none> для репозитория и тега. Как правильно вернуть имя и метку? @wisbucky
Ульфетнар
3
Чтобы пометить, сначала идентифицируйте ID ИЗОБРАЖЕНИЯ, используя docker images, затем используйте docker tag DESIREDIMAGEID mycompany/myreponame. Если ваш идентификатор изображения 591de551d6e4, вы можете сократить идентификатор изображения:docker tag 59 mycompany/myreponame
Младший Mayhé
@AndiJay Посмотрите, как копировать образы
duct_tape_coder
582

Передача образа Docker через SSH, архивирование содержимого на лету:

docker save <image> | bzip2 | \
     ssh user@host 'bunzip2 | docker load'

Это также хорошая идея, чтобы поставить pvв середине трубы, чтобы увидеть, как происходит передача:

docker save <image> | bzip2 | pv | \
     ssh user@host 'bunzip2 | docker load'

(Подробнее о pv: домашней странице , странице руководства ).

kolypto
источник
19
При использовании docker-machine вы можете docker $(docker-machine config mach1) save <image> | docker $(docker-machine config mach2) loadкопировать изображения между машинами mach1 и mach2 .
matlehmann
5
@manojlds eval $(docker-machine env dev)хорош для общего взаимодействия с одним хостом докера, но не для копирования между двумя компьютерами, поскольку в нем задействованы два разных хоста докера.
matlehmann
14
сделать это в обратном порядке (удаленно к локальному):ssh target_server 'docker save image:latest | bzip2' | pv | bunzip2 | docker load
ThorSummoner
2
Есть ли способ сделать это, когда Docker требует sudo на целевой машине? Я пытался (без сжатия) docker save my_img:v1 | ssh -t -t my_user@my_machine sudo docker load. Без ключа "-t" sudo жалуется на sudo: извините, у вас должен быть tty для запуска sudo ; с одним "-t" это то же самое сообщение, потому что ssh говорит, что псевдо-терминал не будет выделен, потому что stdin не является терминалом. и, наконец, с двумя "-t" я получаю содержимое файла tar (т.е. изображение) на моем терминале. Любые идеи?
голод
1
@JosefStark Мне нужно было добавить «По умолчанию: <имя пользователя цели!! Requiretty» при редактировании файла sudoers, чтобы остановить сообщение «Извините» от sudo. Я не знаю, какая разница, но я также помещаю все после user @ host в кавычки (поэтому "[...] | ssh user @ host 'bunzip2 | sudo docker load'").
VirtualWolf
99

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

Получить идентификатор изображения, выполнив:

sudo docker images

Скажем, у вас есть изображение с идентификатором «matrix-data».

Сохраните изображение с идентификатором:

sudo docker save -o /home/matrix/matrix-data.tar matrix-data

Скопируйте изображение с пути на любой хост. Теперь импортируйте в локальную установку Docker, используя:

sudo docker load -i <path to copied image file>
Сохан
источник
34

Сначала сохраните образ Docker в zip-файл:

docker save <docker image name> | gzip > <docker image name>.tar.gz

Затем загрузите экспортированный образ в Docker с помощью следующей команды:

zcat <docker image name>.tar.gz | docker load
Дамодаран
источник
12
Для загрузки docker load < my-image.tar.gzдостаточно. Изображение автоматически распаковывается для gzip, bzip2 и xz.
Поток
32

Запустить

docker images

чтобы увидеть список изображений на хосте. Допустим, у вас есть изображение под названием awesomesauce . В вашем терминале, cdв каталог, куда вы хотите экспортировать изображение. Теперь запустите:

docker save awesomesauce:latest > awesomesauce.tar

Скопируйте файл tar на флэш-диск или что-то еще, а затем скопируйте его на новый хост-компьютер.

Теперь с нового хоста делаем:

docker load < awesomesauce.tar

А теперь иди выпить кофе и почитать Hacker News ...

Нил Джирарди
источник
4
Стоит отметить, что это будет работать только в том случае, если сохранение и загрузка выполняются в одной и той же ОС. Используйте docker save [image] -o file.tarи docker load -i file.tarчтобы избежать этого!
Андреас Форслоу
docker save [image] -o file.tarКроме того, как представляется, дико быстрее
ti7
19

Для упрощенного экспорта файловой системы контейнера используйте;

docker export CONTAINER_ID > my_container.tar

Используйте cat my_container.tar | docker import -для импорта указанного изображения.

Panagiotis Moustafellos
источник
9
это будет, cat my_container.tar | docker import - my_container:newесли импортировать локально в соответствии с cmd help
Ларри Кай
7
Это больше для резервного копирования работающего контейнера, чем для развертывания образа.
Kousha
15

При использовании docker-machine вы можете копировать изображения между компьютерами mach1и mach2с помощью:

docker $(docker-machine config <mach1>) save <image> | docker $(docker-machine config <mach2>) load

И, конечно, вы также можете pvвставлять посередине, чтобы получить индикатор прогестирования:

docker $(docker-machine config <mach1>) save <image> | pv | docker $(docker-machine config <mach2>) load

Вы также можете опустить одну из docker-machine configвложенных оболочек, чтобы использовать свой текущий докер-хост по умолчанию.

docker save <image> | docker $(docker-machine config <mach>) load

скопировать изображение с текущего докер-хоста на mach

или

docker $(docker-machine config <mach>) save <image> | docker load

скопировать с machтекущего докера-хоста.

matlehmann
источник
10

Я предполагаю, что вам нужно сохранить couchdb-cartridgeс идентификатором изображения 7ebc8510bc2c:

stratos@Dev-PC:~$ docker images
REPOSITORY                             TAG                 IMAGE ID            CREATED             VIRTUAL SIZE
couchdb-cartridge                      latest              7ebc8510bc2c        17 hours ago        1.102 GB
192.168.57.30:5042/couchdb-cartridge   latest              7ebc8510bc2c        17 hours ago        1.102 GB
ubuntu                                 14.04               53bf7a53e890        3 days ago          221.3 MB

Сохраните изображение archiveName в файл tar. Я буду использовать, /media/sf_docker_vm/чтобы сохранить изображение.

stratos@Dev-PC:~$ docker save imageID > /media/sf_docker_vm/archiveName.tar

Скопируйте файл archiveName.tar в новый экземпляр Docker, используя любой метод, который работает в вашей среде, например FTP, SCPи т. Д.

Запустите docker loadкоманду на вашем новом экземпляре Docker и укажите местоположение файла tar изображения.

stratos@Dev-PC:~$ docker load < /media/sf_docker_vm/archiveName.tar

Наконец, выполните docker imagesкоманду, чтобы убедиться, что изображение теперь доступно.

stratos@Dev-PC:~$ docker images
REPOSITORY                             TAG        IMAGE ID         CREATED             VIRTUAL SIZE
couchdb-cartridge                      latest     7ebc8510bc2c     17 hours ago        1.102 GB
192.168.57.30:5042/couchdb-cartridge   latest     bc8510bc2c       17 hours ago        1.102 GB
ubuntu                                 14.04      4d2eab1c0b9a     3 days ago          221.3 MB

Пожалуйста, найдите этот подробный пост .

tk_
источник
10

Чтобы перенести образы из локальной установки Docker на виртуальную машину minikube:

docker save <image> | (eval $(minikube docker-env) && docker load)
Брайан Ларсен
источник
10

docker-push-ssh утилита командной строки, которую я создал только для этого сценария

Он устанавливает временный частный реестр Docker на сервере, устанавливает SSH-туннель с вашего локального хоста, отправляет ваш образ, а затем очищает себя.

Преимущество этого подхода перед docker save(на момент написания большинства ответов использует этот метод) состоит в том, что только новые слои передаются на сервер, что приводит к НАМНОГО более быстрой загрузке.

Часто использование промежуточного реестра, такого как dockerhub, нежелательно и обременительно.

https://github.com/brthor/docker-push-ssh

Установка:

pip install docker-push-ssh

Пример:

docker-push-ssh -i ~/my_ssh_key username@myserver.com my-docker-image

Самым большим предупреждением является то, что вы должны вручную добавить свой локальный хост в insecure_registriesконфигурацию Docker . Запустите инструмент один раз, и он выдаст вам информативную ошибку:

Error Pushing Image: Ensure localhost:5000 is added to your insecure registries.
More Details (OS X): /programming/32808215/where-to-set-the-insecure-registry-flag-on-mac-os

Где мне установить флаг «--insecure-registry» в Mac OS?

brthornbury
источник
1
Я отредактировал ваш ответ, чтобы было ясно, что рекомендуемая вами утилита была создана вами. См. Эту страницу , в частности: «Публикуйте хорошие, релевантные ответы, и если некоторые (но не все) касаются вашего продукта или веб-сайта, это нормально. Тем не менее, вы должны раскрывать свою принадлежность в своих ответах».
Луи
8

Все остальные ответы очень полезны. Я только что прошел ту же проблему и выяснил легкий путь docker machine scp.

Начиная с версии Docker Machine v0.3.0, scp был представлен для копирования файлов с одной машины Docker на другую. Это очень удобно, если вы хотите скопировать файл с локального компьютера на удаленный Docker-компьютер, такой как AWS EC2 или Digital Ocean, поскольку Docker Machine позаботится о ваших учетных данных SSH.

  1. Сохранить ваши изображения, используя docker saveкак:

    docker save -o docker-images.tar app-web
    
  2. Копирование изображений с использованием docker-machine scp

    docker-machine scp ./docker-images.tar remote-machine:/home/ubuntu
    

Предположим, что ваш удаленный Docker-компьютер remote-machineи каталог, в котором вы хотите разместить tar-файл /home/ubuntu.

  1. Загрузите образ Docker

    docker-machine ssh remote-machine sudo docker load -i docker-images.tar
    
Peng
источник
5
почему бы просто не 'scp <source> <remote>'?
Тамас Кальман
3

Я хочу переместить все изображения с тегами.

```
OUT=$(docker images --format '{{.Repository}}:{{.Tag}}')
OUTPUT=($OUT)
docker save $(echo "${OUTPUT[*]}") -o /dir/images.tar
``` 

Объяснение:

Сначала OUTполучает все теги, но разделяются новыми строками. Второй OUTPUTполучает все теги в массиве. Третий $(echo "${OUTPUT[*]}")помещает все теги для одной docker saveкоманды, так что все изображения находятся в одном tar.

Кроме того, это может быть заархивировано с помощью gzip. На цель, запустите:

tar xvf images.tar.gz -O | docker load

-Oопция tarпомещает содержимое на стандартный ввод, который может быть захвачен docker load.

Викрам
источник
2

Вы можете использовать sshfs:

$ sshfs user@ip:/<remote-path> <local-mount-path>
$ docker save <image-id> > <local-mount-path>/myImage.tar
Чу
источник
1

Скрипт для выполнения функции сохранения и загрузки Docker (опробовано и протестировано):

Докер Сохранить:

#!/bin/bash

#files will be saved in the dir 'Docker_images'
mkdir Docker_images
cd Docker_images
directory=`pwd`
c=0
#save the image names in 'list.txt'
doc= docker images | awk '{print $1}' > list.txt
printf "START \n"
input="$directory/list.txt"
#Check and create the image tar for the docker images
while IFS= read -r line
do
     one=`echo $line | awk '{print $1}'`
     two=`echo $line | awk '{print $1}' | cut -c 1-3`
     if [ "$one" != "<none>" ]; then
             c=$((c+1))
             printf "\n $one \n $two \n"
             docker save -o $two$c'.tar' $one
             printf "Docker image number $c successfully converted:   $two$c \n \n"
     fi
done < "$input"

Загрузка Docker:

#!/bin/bash

cd Docker_images/
directory=`pwd`
ls | grep tar > files.txt
c=0
printf "START \n"
input="$directory/files.txt"
while IFS= read -r line
do
     c=$((c+1))
     printf "$c) $line \n"
     docker load -i $line
     printf "$c) Successfully created the Docker image $line  \n \n"
done < "$input"
Сайед Фараз Умар
источник
0

Вы можете использовать одну строку с DOCKER_HOSTпеременной:

docker save app:1.0 | gzip | DOCKER_HOST=ssh://user@remotehost docker load
vitalets
источник