khối lượng gắn docker trên máy chủ


134

Tôi đã có thể chia sẻ thành công các thư mục giữa một thùng chứa docker với khối lượng bằng cách sử dụng

docker run -v /host/path:/container/path ...

Nhưng câu hỏi của tôi là sự khác biệt giữa điều này và sử dụng VOLUMElệnh trong Dockerfile

VOLUME /path

Tôi đang sử dụng một hình ảnh có VOLUMElệnh và tôi muốn biết cách chia sẻ nó với máy chủ của mình. Tôi đã thực hiện nó bằng cách sử dụng -vlệnh trên, nhưng tôi không biết liệu tôi có cần cả -vVOLUME.

Câu trả lời:


154

Các VOLUMElệnh sẽ gắn kết một thư mục bên trong container của bạn và lưu trữ bất kỳ tập tin được tạo ra hoặc chỉnh sửa bên trong thư mục đó trên đĩa máy của bạn bên ngoài cấu trúc file container , qua mặt hệ thống tập tin công đoàn.

Ý tưởng là khối lượng của bạn có thể được chia sẻ giữa các container docker của bạn và chúng sẽ tồn tại xung quanh miễn là có một container (đang chạy hoặc dừng) tham chiếu đến chúng.

Bạn có thể có các thùng chứa khác gắn kết các khối lượng hiện có (chia sẻ chúng một cách hiệu quả giữa các container) bằng cách sử dụng --volumes-fromlệnh khi bạn chạy một container.

Sự khác biệt cơ bản giữa VOLUME-vlà đây: -vsẽ gắn các tệp hiện có từ hệ điều hành của bạn vào trong thùng chứa docker của bạn và VOLUMEsẽ tạo một khối lượng mới, trống trên máy chủ của bạn và gắn nó vào trong thùng chứa của bạn.

Thí dụ:

  1. Bạn có một Dockerfile xác định a VOLUME /var/lib/mysql.
  2. Bạn xây dựng hình ảnh docker và gắn thẻ nó some-volume
  3. Bạn chạy container

Và sau đó,

  1. Bạn có một hình ảnh docker khác mà bạn muốn sử dụng âm lượng này
  2. Bạn chạy container docker với các mục sau: docker run --volumes-from some-volume docker-image-name:tag
  3. Bây giờ bạn có một container docker đang chạy sẽ có âm lượng some-volumeđược gắn vào/var/lib/mysql

Lưu ý: Sử dụng --volumes-fromsẽ gắn kết âm lượng trên bất cứ thứ gì tồn tại ở vị trí của âm lượng. Tức là, nếu bạn có nội dung /var/lib/mysql, nó sẽ được thay thế bằng nội dung của tập.


12
Điều gì xảy ra nếu tôi sử dụng -v trên một thư mục đã được chỉ định trong VOLUME?
Jeff Storey

6
--volumes-fromsẽ gắn kết của bạn VOLUMEtrên đầu của bất cứ điều gì bạn chỉ định với -v. Thật thú vị, có vẻ như chạy container trong chế độ đặc quyền ( docker run --privileged) và umounting /var/lib/mysqlsẽ chỉ để lại một thư mục trống để -vmount của bạn hoàn toàn bị bỏ qua khi nó xung đột với a VOLUME.
Chris McKinnel

2
Bạn nói rằng khối lượng được giữ miễn là một container tham chiếu chúng, và tôi đã thấy điều đó ở nơi khác. docs.docker.com/userguide/dockervolume nói rằng "Khối lượng dữ liệu được thiết kế để duy trì dữ liệu, không phụ thuộc vào vòng đời của người chứa. được tham chiếu bởi một container. " Một trong những tuyên bố này phải sai.
mc0e

1
Các tệp trong ổ đĩa được lưu trên đĩa khi một thùng chứa không còn tham chiếu đến nó nữa, nhưng chính ổ đĩa đó không còn sử dụng được nữa (trừ khi bạn biết chính xác cách móc âm lượng lên một cách thủ công, nhưng ngay cả khi đó tôi không ' t biết nếu điều này là có thể). Khi tôi nói không còn sử dụng được nữa, ý tôi là bạn không thể sử dụng --volume-từ để sử dụng nó. Khi họ nói "thu gom rác" ở trên, họ có nghĩa là xóa các tệp khỏi đĩa của bạn trong ổ đĩa.
Chris McKinnel

1
Chúng có thể được sử dụng bằng cách sử dụng -v, nhưng không --volume-from. Các tập-từ lấy một tên container để lấy dữ liệu âm lượng từ (tôi tin rằng nó mất TẤT CẢ các điểm âm lượng). Tuy nhiên, đối với -v, hướng dẫn sử dụng đề cập rằng bạn có thể cung cấp âm lượng được đặt tên cho -v ở dạng named-volume:/path/in/container. Các khối không được đặt tên được băm cho các tên và các giá trị băm đó có thể được cung cấp thay vì đường dẫn máy chủ để truy cập các khối mồ côi. :) Hãy nhận biết volume lscó thể không hiển thị tất cả - hãy thử docker volume ls -f dangling=true.
Jasmine Hegman

43

Hãy để tôi thêm câu trả lời của riêng mình, vì tôi tin rằng những người khác đang thiếu quan điểm của Docker.

Sử dụng VOLUME trong Dockerfile là Right Way ™, vì bạn cho Docker biết rằng một thư mục nhất định chứa dữ liệu cố định. Docker sẽ tạo ra một khối lượng cho dữ liệu đó và không bao giờ xóa nó, ngay cả khi bạn loại bỏ tất cả các container sử dụng nó.

Nó cũng bỏ qua hệ thống tập tin liên minh, do đó, khối lượng thực tế là một thư mục thực tế được gắn (đọc-ghi hoặc đọc) ở đúng vị trí trong tất cả các thùng chứa chia sẻ nó.

Bây giờ, để truy cập dữ liệu đó từ máy chủ lưu trữ, bạn chỉ cần kiểm tra vùng chứa của mình:

# docker inspect myapp
[{
    .
    .
    .
    "Volumes": {
        "/var/www": "/var/lib/docker/vfs/dir/b3ef4bc28fb39034dd7a3aab00e086e6...",
        "/var/cache/nginx": "/var/lib/docker/vfs/dir/62499e6b31cb3f7f59bf00d8a16b48d2...",
        "/var/log/nginx": "/var/lib/docker/vfs/dir/71896ce364ef919592f4e99c6e22ce87..."
    },
    "VolumesRW": {
        "/var/www": false,
        "/var/cache/nginx": true,
        "/var/log/nginx": true
    }
}]

Những gì tôi thường làm là tạo liên kết tượng trưng ở một số vị trí tiêu chuẩn, chẳng hạn như / srv , để tôi có thể dễ dàng truy cập vào các ổ đĩa và quản lý dữ liệu chứa trong đó (chỉ dành cho các ổ đĩa bạn quan tâm):

ln -s /var/lib/docker/vfs/dir/b3ef4bc28fb39034dd7a3aab00e086e6... /srv/myapp-www
ln -s /var/lib/docker/vfs/dir/71896ce364ef919592f4e99c6e22ce87... /srv/myapp-log

Nếu máy chủ docker đang chạy trong VM thì sao? Ví dụ: boot2docker trên mac. Sau đó, các khối lượng chỉ có sẵn từ xa. Ngoài ra, khi sử dụng các ổ đĩa trong Dockerfile như bạn mô tả, nội dung của hình ảnh sẽ được sao chép vào ổ đĩa. Tuy nhiên, khi gắn vào thư mục cục bộ, việc sao chép này không xảy ra. Bạn có biết tại sao lại như vậy không? Có cách nào để có âm lượng được gắn cục bộ nhưng vẫn 'bắt đầu mới' với các tệp từ hình ảnh không?
LostSalad

4
với docker-compose bạn có thể thực hiện chính xác điều đó, gắn một âm lượng vào một vị trí cụ thể của hệ điều hành máy chủ . Không cần liên kết tượng trưng ...
Hugo Koopmans

@Tobia: ví dụ docker-compose xem docs docs.docker.com/compose/compose-file/ Kẻ
Hugo Koopmans

11

VOLUME được sử dụng Dockerfileđể hiển thị âm lượng được sử dụng bởi các container khác. Ví dụ, tạo Dockerfilenhư:

TỪ Ubuntu: 14.04

RUN mkdir /myvol  
RUN echo "hello world" > /myvol/greeting  
VOLUME /myvol

xây dựng hình ảnh:

$ docker build -t testing_volume .

Chạy container, nói container1:

$ docker run -it <image-id of above image> bash

Bây giờ hãy chạy một container khác với tùy chọn khối lượng từ (say-container2)

$ docker run -it --volumes-from <id-of-above-container> ubuntu:14.04 bash

Bạn sẽ nhận được tất cả dữ liệu từ /myvolthư mục container1 vào container2 tại cùng một vị trí.

-vtùy chọn được đưa ra tại thời gian chạy của container được sử dụng để gắn thư mục chứa trên máy chủ. Nó là đơn giản để sử dụng, chỉ cần cung cấp -vtùy chọn với đối số là <host-path>:<container-path>. Toàn bộ lệnh có thể là$ docker run -v <host-path>:<container-path> <image-id>


8

Về cơ bản VOLUME-vtùy chọn gần như bằng nhau. Điều này có nghĩa là 'gắn thư mục cụ thể vào thùng chứa của bạn'. Ví dụ, VOLUME /data-v /datachính xác là cùng một ý nghĩa. Nếu bạn chạy hình ảnh có VOLUME /datahoặc có -v /datatùy chọn, /datathư mục sẽ được gắn thùng chứa của bạn. Thư mục này không thuộc về container của bạn.

Hãy tưởng tượng rằng bạn thêm một số tệp /datavào vùng chứa, sau đó cam kết vùng chứa vào hình ảnh mới. Không có bất kỳ tệp nào trên thư mục dữ liệu vì /datathư mục được gắn thuộc về bộ chứa gốc.

$ docker run -it -v /data --name volume ubuntu:14.04 bash
root@2b5e0f2d37cd:/# cd /data
root@2b5e0f2d37cd:/data# touch 1 2 3 4 5 6 7 8 9
root@2b5e0f2d37cd:/data# cd /tmp
root@2b5e0f2d37cd:/tmp# touch 1 2 3 4 5 6 7 8 9
root@2b5e0f2d37cd:/tmp# exit
exit

$ docker commit volume nacyot/volume  
835cfe3d8d159622507ba3256bb1c0b0d6e7c1419ae32751ad0f925c40378945
nacyot $ docker run -it nacyot/volume
root@dbe335c7e64d:/# cd /data
root@dbe335c7e64d:/data# ls
root@dbe335c7e64d:/data# cd /tmp
root@dbe335c7e64d:/tmp# ls
1  2  3  4  5  6  7  8  9
root@dbe335c7e64d:/tmp# 
root@dbe335c7e64d:/tmp# 

Thư mục được gắn kết như thế /datanày được sử dụng để lưu trữ dữ liệu không thuộc về ứng dụng của bạn. Và bạn có thể xác định trước thư mục dữ liệu không thuộc về vùng chứa bằng cách sử dụngVOLUME .

Một sự khác biệt giữa Volume-vtùy chọn là bạn có thể sử dụng -vtùy chọn động khi bắt đầu chứa. Nó có nghĩa là bạn có thể gắn kết một số thư mục động. Và một sự khác biệt nữa là bạn có thể gắn thư mục máy chủ của mình vào thùng chứa bằng cách sử dụng-v


8

Đây là từ tài liệu Docker, có thể hữu ích, đơn giản và dễ hiểu:

"Về bản chất, thư mục máy chủ phụ thuộc vào máy chủ. Vì lý do này, bạn không thể gắn thư mục máy chủ từ Dockerfile, lệnh VOLUME không hỗ trợ truyền một máy chủ lưu trữ, vì hình ảnh được xây dựng nên có thể mang theo được. thư mục sẽ không có sẵn trên tất cả các máy chủ tiềm năng. ".

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.