วิธีคัดลอกอิมเมจ Docker จากโฮสต์หนึ่งไปยังอีกโฮสต์หนึ่งโดยไม่ต้องใช้ที่เก็บ


1374

ฉันจะถ่ายโอนรูปภาพนักเทียบท่าจากเครื่องหนึ่งไปยังอีกเครื่องหนึ่งได้อย่างไรโดยไม่ต้องใช้ที่เก็บข้อมูลไม่ว่าจะเป็นส่วนตัวหรือสาธารณะ

ฉันสร้างภาพของตัวเองใน VirtualBox และเมื่อเสร็จแล้วฉันพยายามปรับใช้กับเครื่องอื่นเพื่อให้มีการใช้งานจริง

เนื่องจากมันขึ้นอยู่กับอิมเมจของฉันเอง (เช่น Red Hat Linux) จึงไม่สามารถสร้างขึ้นใหม่ได้จาก Dockerfile dockerfile ของฉันไม่พกพาได้ง่าย

มีคำสั่งง่ายๆที่ฉันสามารถใช้ได้หรือไม่? หรือวิธีอื่น

คำตอบ:


2307

คุณจะต้องบันทึกอิมเมจ 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

27
นี่คือคำตอบที่ดีกว่าสำหรับภาพ
Andy

26
นอกจากนี้ยังจะดีกว่าที่จะใช้เป็นข้อมูลอ้างอิงภาพมากกว่าrepo:tag image idหากคุณใช้image idรูปภาพที่โหลดจะไม่เก็บแท็ก (และคุณจะต้องทำขั้นตอนอื่นเพื่อติดแท็กรูปภาพ)
wisbucky

1
ฉันใช้รหัสรูปภาพแทนชื่อ: แท็กตอนนี้ฉันนั่งอยู่ที่นี่โหลดรูปภาพและมี <ไม่มี> สำหรับ REPOSITORY และ TAG วิธีที่ถูกต้องในการนำชื่อและแท็กกลับมาเป็นอย่างไร @wisbucky
Ulfhetnar

3
ไปยังแท็กตัวตนแรกรหัสภาพโดยใช้การใช้งานแล้วdocker images docker tag DESIREDIMAGEID mycompany/myreponameหากรหัสรูปภาพของคุณคือ 591de551d6e4 คุณสามารถย่อรหัสรูปภาพได้:docker tag 59 mycompany/myreponame
Junior Mayhé


582

ถ่ายโอนภาพนักเทียบท่าผ่าน SSH โดยบีบอัดเนื้อหาทันที

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

เป็นความคิดที่ดีที่จะวางไว้pvตรงกลางของท่อเพื่อดูว่าการถ่ายโอนเป็นไปอย่างไร:

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

(ข้อมูลเพิ่มเติมเกี่ยวกับpv: หน้าแรก , หน้าคน )


19
เมื่อใช้นักเทียบท่าเครื่องที่คุณสามารถทำได้docker $(docker-machine config mach1) save <image> | docker $(docker-machine config mach2) loadเพื่อคัดลอกภาพระหว่างเครื่องmach1และmach2
matlehmann

5
@manojlds eval $(docker-machine env dev)เป็นสิ่งที่ดีสำหรับการสื่อสารทั่วไปกับโฮสต์docker เดียว แต่ไม่คัดลอกระหว่างเครื่องสองเครื่องเนื่องจากเกี่ยวข้องกับเครื่องโฮสต์ / นักเทียบท่าที่แตกต่างกันสองเครื่อง
matlehmann

14
ทำสิ่งนี้ในสิ่งที่ตรงกันข้าม (ห่างไกลถึงท้องถิ่น):ssh target_server 'docker save image:latest | bzip2' | pv | bunzip2 | docker load
ThorSummoner

2
มีวิธีการทำเช่นนี้เมื่อนักเทียบท่าต้องการ sudo บนเครื่องเป้าหมายหรือไม่? ฉันพยายาม docker save my_img:v1 | ssh -t -t my_user@my_machine sudo docker load(ไม่มีการบีบอัด) หากไม่มีสวิตช์ "-t" sudo จะบ่นsudo: ขออภัยคุณต้องมี tty ในการเรียกใช้ sudo ; ด้วยหนึ่ง "-t" มันเป็นข้อความเดียวกันเพราะ ssh พูดว่าPseudo-terminal จะไม่ถูกจัดสรรเพราะ 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"

บันทึกภาพด้วย id:

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

11
สำหรับการโหลด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เพื่อหลีกเลี่ยงสิ่งนี้!
Andreas Forslöw

docker save [image] -o file.tarดูเหมือนว่าจะเร็วขึ้นอย่างดุเดือด
ti7

19

สำหรับการเอ็กซ์พอร์ตระบบไฟล์ของคอนเทนเนอร์แบบแบนให้ใช้;

docker export CONTAINER_ID > my_container.tar

ใช้cat my_container.tar | docker import -เพื่อนำเข้าภาพดังกล่าว


9
มันจะเป็นcat my_container.tar | docker import - my_container:newถ้านำเข้าในท้องถิ่นตามคำสั่งช่วยเหลือ
Larry Cai

7
สิ่งนี้มีมากขึ้นสำหรับการสำรองข้อมูลคอนเทนเนอร์ที่ใช้งานมากกว่าสำหรับการปรับใช้ภาพ
Kousha

15

เมื่อใช้เครื่องเทียบท่าคุณสามารถคัดลอกภาพระหว่างเครื่องmach1และmach2ด้วย:

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

และแน่นอนคุณสามารถติดpvตรงกลางเพื่อรับตัวบ่งชี้ progess:

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ไปยังโฮสต์นักเทียบท่าปัจจุบัน


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

บันทึกอิมเมจไฟล์เก็บถาวรชื่อเป็นไฟล์ tar ฉันจะใช้/media/sf_docker_vm/เพื่อบันทึกภาพ

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

คัดลอกแฟ้ม archiveName.tar อินสแตนซ์หางใหม่ของคุณโดยใช้วิธีการใด ๆ ก็ตามการทำงานในสภาพแวดล้อมของคุณตัวอย่างเช่น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

กรุณาค้นหาโพสต์รายละเอียดนี้



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

ข้อแม้ที่ใหญ่ที่สุดคือคุณต้องเพิ่ม localhost ลงใน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 ได้ที่ไหน


1
ฉันได้แก้ไขคำตอบของคุณเพื่อให้ชัดเจนว่าคุณได้สร้างโปรแกรมอรรถประโยชน์ที่คุณแนะนำ ดูหน้านี้โดยเฉพาะ: "โพสต์คำตอบที่ดีมีความเกี่ยวข้องและถ้ามีบางคน (แต่ไม่ทั้งหมด) เกี่ยวกับผลิตภัณฑ์หรือเว็บไซต์ของคุณไม่เป็นไรอย่างไรก็ตามคุณต้องเปิดเผยความร่วมมือในคำตอบของคุณ"
Louis

8

คำตอบอื่น ๆ ทั้งหมดมีประโยชน์มาก docker machine scpฉันเพียงแค่เดินผ่านปัญหาเดียวกันและคิดออกเป็นวิธีที่ง่ายกับ

ตั้งแต่ Docker Machine v0.3.0 จึงมีการนำ scp ไปใช้เพื่อคัดลอกไฟล์จากเครื่อง Docker เครื่องหนึ่งไปยังอีกเครื่องหนึ่ง วิธีนี้จะสะดวกมากถ้าคุณต้องการคัดลอกไฟล์จากเครื่องคอมพิวเตอร์ของคุณไปยังเครื่อง Docker ระยะไกลเช่น AWS EC2 หรือ Digital Ocean เพราะ Docker Machine ดูแลข้อมูลประจำตัวของ SSH ให้คุณ

  1. บันทึกภาพโดยใช้docker savelike:

    docker save -o docker-images.tar app-web
    
  2. คัดลอกรูปภาพโดยใช้scp-docker-machine

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

สมมติเครื่องเทียบท่าระยะไกลของคุณเป็นremote-machineและไดเรกทอรีที่คุณต้องการไฟล์ tar /home/ubuntuที่จะเป็น

  1. โหลดอิมเมจ Docker

    docker-machine ssh remote-machine sudo docker load -i docker-images.tar
    

5
ทำไมไม่ใช่แค่ 'scp <source> <remote>'
Tamas Kalman

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วางเนื้อหาบน stdin ซึ่งสามารถคว้าdocker loadได้



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"

โหลดนักเทียบท่า:

#!/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
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.