วิธีที่ถูกต้องในการเพิ่มข้อมูลไปยังไดรฟ์ข้อมูลที่มีชื่อที่มีอยู่ใน Docker คืออะไร?


91

ฉันใช้ Docker แบบเก่าโดยมี Volume Container:

docker run -d --name jenkins-data jenkins:tag echo "data-only container for Jenkins"

แต่ตอนนี้ฉันเปลี่ยนเป็นวิธีใหม่โดยสร้างไดรฟ์ข้อมูลที่มีชื่อ:

 docker volume create --name my-jenkins-volume 

ฉันผูกโวลุ่มใหม่นี้กับคอนเทนเนอร์เจนกินส์ใหม่ สิ่งเดียวที่ฉันทิ้งไว้คือโฟลเดอร์ที่ฉันมี/var/jenkins_homeคอนเทนเนอร์ของเจนกินส์ก่อนหน้านี้ (โดยใช้docker cp) ตอนนี้ฉันต้องการเติมไดรฟ์ข้อมูลที่มีชื่อใหม่ของฉันด้วยเนื้อหาของโฟลเดอร์นั้น

ฉันสามารถคัดลอกเนื้อหาของโฟลเดอร์นั้นไปที่/var/lib/jenkins/volume/my-jenkins-volume/_data?

คำตอบ:


141

คุณสามารถคัดลอกข้อมูลได้โดยตรง/var/lib/docker/volumes/my-jenkins-volume/_dataแต่การทำเช่นนี้คุณจะ:

  • อาศัยการเข้าถึงทางกายภาพไปยังโฮสต์นักเทียบท่า เทคนิคนี้จะใช้ไม่ได้หากคุณกำลังโต้ตอบกับ api นักเทียบท่าระยะไกล

  • การอาศัยลักษณะเฉพาะของการใช้งานไดรฟ์ข้อมูลอาจเปลี่ยนแปลงได้ในอนาคตทำลายกระบวนการใด ๆ ที่คุณต้องพึ่งพา

ฉันคิดว่าคุณควรพึ่งพาสิ่งต่าง ๆ ที่คุณสามารถทำได้โดยใช้ docker api ผ่านไคลเอนต์บรรทัดคำสั่งดีกว่า วิธีแก้ปัญหาที่ง่ายที่สุดน่าจะเป็นเพียงการใช้ภาชนะผู้ช่วยเช่น:

docker run -v my-jenkins-volume:/data --name helper busybox true
docker cp . helper:/data
docker rm helper

3
เกี่ยวกับสัญลักษณ์แสดงหัวข้อย่อยที่สองของคุณคุณสามารถเรียกใช้docker volume inspect my-jenkins-volume --format '{{.Mountpoint}}'เพื่อรับตำแหน่งทางกายภาพโดยทางโปรแกรมได้ ยังไม่รู้สึกว่าเป็นความคิดที่ดีแม้ว่า
c24w

9
คอนเทนเนอร์ตัวช่วยนี้ไม่จำเป็นต้องทำงานจริง มันจะเพียงพอที่จะสร้างมันขึ้นมาจากนั้นเรียกใช้docker cpและลบออก
Alex

คุณไม่สามารถดำเนินการในคอนเทนเนอร์นั้นเพื่อดูผลลัพธ์หรือแก้ไขไฟล์ด้วยตนเอง
CodeOrElse

3
ทราบว่ารายชื่อ/var/lib/docker/volumes/my-jenkins-volume/_dataเมื่อใช้หางสำหรับ Macไม่ได้เพราะไฟล์ที่เก็บไว้ภายในเครื่องเสมือน xhyve ดูforums.docker.com/t/var-lib-docker-does-not-exist-on-host/18314
Ortomala Lokni

1
True อธิบายไว้ที่นี่stackoverflow.com/questions/29762231/…
Zuabi

32

คุณสามารถลดคำตอบที่ยอมรับให้เหลือหนึ่งบรรทัดได้โดยใช้เช่น

docker run --rm -v `pwd`:/src -v my-jenkins-volume:/data busybox cp -r /src /data

1
ฉันสงสัยว่าลักษณะชั่วคราวของ / tmp อาจทำให้เกิดความเสี่ยงที่คอนเทนเนอร์อาจลบข้อมูลของคุณก่อนที่ cp จะเสร็จสมบูรณ์หรือไม่? pathname.com/fhs/pub/fhs-2.3.html#TMPTEMPORARYFILES
thurt

1
ลิงก์ไม่ได้อธิบายอายุการใช้งานของไฟล์ใน / tmp ฉันระบุว่า: "โปรแกรมต้องไม่คิดว่าไฟล์หรือไดเร็กทอรีใด ๆ ใน / tmp จะถูกเก็บรักษาไว้ระหว่างการเรียกใช้โปรแกรม" ซึ่งหมายความว่าไฟล์จะอยู่รอดได้ แต่นั่นเป็นการรับประกัน อ็อพชัน -v สำหรับนักเทียบท่าจะสร้างไดเร็กทอรีในคอนเทนเนอร์หากไม่มีอยู่ดังนั้นการเปลี่ยน / tmp / src เป็น / src จะใช้ได้ผลหากคุณกังวลเกี่ยวกับสภาวะการแข่งขันที่อาจเกิดขึ้นนี้ ฉันจะแก้ไขคำตอบเพื่อสะท้อนสิ่งนี้เนื่องจากไม่มีข้อเสีย
headdab

3
ไม่ได้-v `pwd`:/srcหมายความว่าคำสั่งกำลังทำงานบนโฮสต์? ( pwdตัวอย่างเช่นโฮสต์แมปจะทำอย่างไรหากเป็นเครื่องอื่น - ทำไม่ได้) หากคำสั่ง docker ไม่ทำงานบนโฮสต์จะใช้ไม่ได้ ฉันเชื่อว่านั่นเป็นเหตุผลที่เรามี docker cp ดูเหมือนว่านี่จะไม่ใช่ "ทาง" สำหรับนักเทียบท่า แต่เป็นกรณีพิเศษที่ใช้ได้เฉพาะเมื่อคำสั่งนักเทียบท่าทำงานบนโฮสต์ ฉันเข้าใจถูกต้องหรือไม่?
Wyck

ใช่ฉันคิดว่าคุณพูดถูก pwdต้องแก้ไขเป็นไฟล์บนเครื่องโฮสต์ จากเอกสารการเมาท์ของนักเทียบท่า: "ในกรณีของการเชื่อมโยงการเชื่อมโยงฟิลด์แรกคือเส้นทางไปยังไฟล์หรือไดเร็กทอรีบนเครื่องโฮสต์"
headdab

1
ดังนั้นจึงไม่สามารถคัดลอกไฟล์ในเครื่องของคุณไปยังคอนเทนเนอร์ได้หากอยู่ในโฮสต์ระยะไกลเนื่องจากคุณกำลังต่อเชื่อมpwdซึ่งไม่จำเป็นต้องมีอยู่ในโฮสต์ระยะไกล การแก้ปัญหาโดย Dmytro Melnychuk (create + cp + rm) จะคัดลอกโลคัลลงในคอนเทนเนอร์ไม่ว่าจะทำงานอยู่ที่ใดก็ตาม
Xavi Montero

27

คุณไม่จำเป็นต้องเริ่มคอนเทนเนอร์เพื่อเพิ่มข้อมูลไปยังไดรฟ์ข้อมูลที่มีชื่อที่มีอยู่แล้วเพียงแค่สร้างคอนเทนเนอร์และคัดลอกข้อมูลที่นั่น:

docker container create --name temp -v my-jenkins-volume:/data busybox
docker cp . temp:/data
docker rm temp

2
โดยที่เนื้อหาของ busybox ไม่จำเป็นจริงๆ คุณสามารถทำได้hello-worldและยังใช้งานได้ busyboxคือ 1.22MB. แทนที่จะhello-worldเป็น 13.3kB คำถามคือวิธีเดียวกับที่เราทำ Dockerfile FROM scratch เราสามารถ "สร้างคอนเทนเนอร์นักเทียบท่า" โดย "ไม่มีอะไร" เป็นรูปภาพได้หรือไม่เพราะเราต้องการแค่ "ต่อเชื่อม" โวลุ่มและไม่เริ่มคอนเทนเนอร์
Xavi Montero

1
+1 สำหรับโซลูชันนี้ที่ได้รับการโหวตสูงสุด แต่ไวยากรณ์ที่ถูกต้องdocker cpคือdocker cp [OPTIONS] CONTAINER:SRC_PATH DEST_PATH
Marco Dufal

4

ต่อไปนี้เป็นขั้นตอนในการคัดลอกเนื้อหาของ~ / dataไปยัง docker volume ที่ชื่อmy-vol

ขั้นตอนที่ 1. แนบไดรฟ์ข้อมูลเข้ากับคอนเทนเนอร์ "ชั่วคราว" สำหรับการรันในเทอร์มินัลคำสั่งนี้:

docker run --rm -it --name alpine --mount type=volume,source=my-vol,target=/data alpine

ขั้นตอนที่ 2 เนื้อหาสำเนา~ / ข้อมูลลงใน-ฉบับของฉัน สำหรับการรันคำสั่งนี้ในหน้าต่างเทอร์มินัลใหม่:

cd ~/data docker cp . alpine:/data

สิ่งนี้จะคัดลอกเนื้อหาของ~ / dataไปยังไดรฟ์ข้อมูลmy-vol หลังจากคัดลอกออกจากคอนเทนเนอร์ชั่วคราว

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