Cách phù hợp để thêm dữ liệu vào một ổ đĩa có tên hiện có trong Docker là gì?


88

Tôi đang sử dụng Docker theo cách cũ, với vùng chứa khối lượng:

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

Nhưng bây giờ tôi đã thay đổi theo cách mới bằng cách tạo một tập có tên:

 docker volume create --name my-jenkins-volume 

Tôi đã liên kết tập mới này với một thùng chứa Jenkins mới. Thứ duy nhất tôi còn lại là một thư mục trong đó tôi có vùng /var/jenkins_homechứa jenkins trước đây của mình. (bằng cách sử dụng docker cp) Bây giờ tôi muốn lấp đầy ổ đĩa mới có tên của mình với nội dung của thư mục đó.

Tôi có thể sao chép nội dung của thư mục đó vào /var/lib/jenkins/volume/my-jenkins-volume/_datakhông?

Câu trả lời:


134

Bạn chắc chắn có thể sao chép dữ liệu trực tiếp vào /var/lib/docker/volumes/my-jenkins-volume/_data, nhưng bằng cách này, bạn sẽ:

  • Dựa vào quyền truy cập vật lý vào máy chủ docker. Kỹ thuật này sẽ không hoạt động nếu bạn đang tương tác với một api docker từ xa.

  • Việc dựa vào một khía cạnh cụ thể của việc triển khai khối lượng có thể thay đổi trong tương lai, phá vỡ bất kỳ quy trình nào bạn dựa vào đó.

Tôi nghĩ bạn tốt hơn nên dựa vào những thứ bạn có thể hoàn thành bằng cách sử dụng api docker, thông qua ứng dụng khách dòng lệnh. Giải pháp đơn giản nhất có lẽ chỉ là sử dụng một vùng chứa trợ giúp, giống như:

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

3
Về dấu đầu dòng thứ hai, bạn có thể chạy docker volume inspect my-jenkins-volume --format '{{.Mountpoint}}'để lấy vị trí thực của nó theo lập trình. Vẫn không cảm thấy đó là một ý tưởng tuyệt vời.
c24w

8
Vùng chứa trợ giúp này không bao giờ cần thực sự chạy. Chỉ cần tạo nó, sau đó chạy docker cpvà sau đó gỡ bỏ nó là đủ.
Alex

Bạn không thể thực thi vào vùng chứa đó để xem kết quả hoặc sửa đổi tệp theo cách thủ công.
CodeOrElse

3
Lưu ý rằng danh sách /var/lib/docker/volumes/my-jenkins-volume/_datakhi sử dụng Docker cho Mac không hoạt động vì các tệp được lưu trữ bên trong máy ảo xhyve . Xem forums.docker.com/t/var-lib-docker-does-not-exist-on-host/18314
Ortomala Lokni

1
True được giải thích ở đây stackoverflow.com/questions/29762231/…
Zuabi

32

Bạn có thể giảm câu trả lời được chấp nhận xuống một dòng bằng cách sử dụng, ví dụ:

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

1
Tôi đang tự hỏi liệu bản chất nhất thời của / tmp có thể gây ra rủi ro vùng chứa có thể xóa dữ liệu của bạn trước khi cp hoàn thành không? pathname.com/fhs/pub/fhs-2.3.html#TMPTEMPORARYFILES
thurt

1
Liên kết không thực sự làm rõ thời gian tồn tại của tệp trong / tmp. Tôi tuyên bố: "Các chương trình không được giả định rằng bất kỳ tệp hoặc thư mục nào trong / tmp đều được giữ nguyên giữa các lần gọi của chương trình." điều này ngụ ý rằng các tệp sẽ tồn tại, nhưng đó là một sự đảm bảo. Tùy chọn -v cho docker sẽ tạo một thư mục trong vùng chứa nếu không tồn tại, vì vậy việc thay đổi / tmp / src thành / src sẽ hoạt động nếu bạn lo lắng về điều kiện chủng tộc tiềm năng này. Tôi sẽ chỉnh sửa câu trả lời để phản ánh điều này, vì không có nhược điểm.
headdab

3
không -v `pwd`:/srcngụ ý rằng lệnh đang chạy trên máy chủ? (Làm thế nào máy chủ lưu trữ có thể ánh xạ pwdnếu đó là một máy khác? - nó không thể.) Nếu lệnh docker không chạy trên máy chủ, điều này không hoạt động. Tôi tin rằng đó là lý do tại sao chúng ta có cp docker. Điều này có vẻ như nó không phải là "cách" cho docker - nó chỉ là một trường hợp đặc biệt chỉ hoạt động khi lệnh docker đang chạy trên máy chủ. Tôi có hiểu đúng?
Wyck

Vâng, tôi nghĩ bạn đúng. pwdphải phân giải thành một tệp trên máy chủ. Từ tài liệu về gắn kết của docker: "Trong trường hợp gắn kết liên kết, trường đầu tiên là đường dẫn đến tệp hoặc thư mục trên máy chủ."
headdab

1
Do đó, điều này không hoạt động để sao chép các tệp cục bộ của bạn vào vùng chứa nếu ở trong một máy chủ từ xa, vì bạn đang gắn kết pwdmà thậm chí không cần tồn tại trong máy chủ từ xa. Thay vào đó, giải pháp của Dmytro Melnychuk (tạo + cp + rm) sao chép các tệp cục bộ vào vùng chứa bất kể nó đang chạy ở đâu.
Xavi Montero

25

Bạn không cần bắt đầu một số vùng chứa để thêm dữ liệu vào ổ đĩa đã đặt tên hiện có, chỉ cần tạo vùng chứa và sao chép dữ liệu vào đó:

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

2
Với điều kiện là nội dung của busybox không thực sự cần thiết; bạn có thể làm điều này với hello-worldvà nó cũng hoạt động. busyboxlà 1,22MB. Thay vào đó hello-worldlà 13,3kB. Câu hỏi đặt ra là: Giống như cách chúng ta có thể tạo Dockerfile TỪ đầu, liệu chúng ta có thể thực hiện "tạo bộ chứa docker" với "không có gì" như hình ảnh mà chúng ta chỉ muốn "gắn" ổ đĩa và không bao giờ khởi động vùng chứa không?
Xavi Montero

1
+1 cho giải pháp này so với giải pháp được bình chọn hàng đầu nhưng cú pháp chính xác docker cpdocker cp [OPTIONS] CONTAINER:SRC_PATH DEST_PATH
Marco Dufal

4

Dưới đây là các bước để sao chép nội dung của ~ / data vào ổ đĩa docker có tên là my-vol

Bước 1. Đính kèm ổ đĩa vào một thùng chứa "tạm thời". Để chạy trong terminal, lệnh này:

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

Bước 2. Sao chép nội dung của ~ / data vào my-vol . Để chạy lệnh này trong cửa sổ đầu cuối mới:

cd ~/data docker cp . alpine:/data

Thao tác này sẽ sao chép nội dung của ~ / data vào tập của tôi . Sau khi sao chép, thoát khỏi vùng chứa tạm thời.

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.