Gắn thư mục NFS vào Khối lượng máy chủ được chia sẻ với Docker


8

Hãy xem xét các container Docker sau:

docker run --rm -it -v /tmp:/mnt/tmp alpine sh

Điều này gắn kết thư mục máy chủ / tmp vào / mnt / tmp bên trong thùng chứa alpine.

Bây giờ, trên Hệ thống máy chủ, tôi gắn một khối lượng NFS vào thư mục / tmp:

mkdir /tmp/nfs
mount -t nfs4 192.168.1.100:/data /tmp/nfs

Gắn kết hoạt động trên Hệ thống máy chủ và tôi thấy như sau:

# ls /tmp/nfs
file1 file2 file3
#

Nhưng trên Docker Container, tôi thấy một thư mục trống:

# ls /mnt/tmp/nfs
#

Tôi biết rằng tôi có thể khắc phục điều này bằng cách thực hiện gắn kết trực tiếp trong Docker Container. Nhưng tôi thực sự quan tâm để biết lý do tại sao mount hoạt động trên container chủ mà không phải trong container docker?


Bạn có thể cần mô tả hệ điều hành, phiên bản docker, v.v. Tôi vừa thử điều này với Centos 7 và docker 1.10 từ các tính năng bổ sung và nó hoạt động như mong đợi; nội dung của mount NFS xuất hiện bên trong một thùng chứa debian / jessie. Ngoài ra, cho dù bạn có kiểm soát bảo mật (ví dụ: SELinux) và các cờ khác.
Stephen Harris

Tôi đang sử dụng Ubuntu 16.04 với Docker phiên bản 1.12.0-dev, không có kiểm soát bảo mật bổ sung. Vấn đề chỉ thể hiện khi tôi tạo NFS Mount sau khi tôi đã tạo ra vùng chứa Alps. Nếu tôi tạo Núi NFS trước khi tôi tạo thùng chứa Alps, tôi sẽ thấy nó như mong đợi.
Caleb

Câu trả lời:


15

Điều này xảy ra bởi vì âm lượng đang sử dụng privatelan truyền gắn kết. Điều này có nghĩa là một khi gắn kết xảy ra, bất kỳ thay đổi nào xảy ra ở phía gốc (ví dụ: phía "máy chủ" trong trường hợp Docker) sẽ không hiển thị bên dưới giá treo.

Có một số cách để xử lý việc này:

  1. Thực hiện gắn kết NFS trước, sau đó khởi động container. Gắn kết sẽ lan truyền đến container, tuy nhiên như trước khi có bất kỳ thay đổi nào đối với mount sẽ không được nhìn thấy bởi container (bao gồm cả unmounts).

  2. Sử dụng tuyên truyền "nô lệ". Điều này có nghĩa là một khi gắn kết được tạo, bất kỳ thay đổi nào ở phía gốc (máy chủ docker) sẽ có thể được nhìn thấy trong mục tiêu (trong vùng chứa). Nếu bạn tình cờ thực hiện gắn kết lồng nhau, bạn sẽ muốn sử dụng rslave( rcho đệ quy).

Ngoài ra còn có tuyên truyền "chia sẻ". Chế độ này sẽ thực hiện các thay đổi đối với điểm gắn kết từ bên trong container truyền đến máy chủ, cũng như cách khác. Vì người dùng của bạn thậm chí sẽ không có đặc quyền để thực hiện các thay đổi như vậy (trừ khi bạn thêm CAP_SYS_ADMIN), đây có thể không phải là điều bạn muốn.

Bạn có thể đặt chế độ lan truyền khi tạo mount như vậy:

$ docker run -v /foo:/bar:private

Cách khác là sử dụng âm lượng thay vì gắn máy chủ. Bạn có thể làm điều này như vậy:

$ docker volume create \
    --name mynfs \
    --opt type=nfs \
    --opt device=:<nfs export path> \
    --opt o=addr=<nfs host> \
    mynfs
$ docker run -it -v mynfs:/foo alpine sh

Điều này sẽ đảm bảo luôn luôn gắn kết trong container cho bạn, không phụ thuộc vào việc thiết lập máy chủ theo một cách cụ thể hoặc xử lý việc truyền bá mount.
lưu ý : :ở phía trước của đường dẫn thiết bị là bắt buộc, chỉ có điều gì đó kỳ lạ về mô-đun hạt nhân nfs.
lưu ý : Docker hiện không phân giải <nfs host>từ tên DNS (tên này sẽ là 1.13) vì vậy bạn sẽ cần cung cấp địa chỉ IP tại đây.

Thêm chi tiết về các gắn kết "cây con chung": https://www.kernel.org/doc/Documentation/filesystems/ Sharedsubtree.txt


Câu trả lời rất hay. Bạn có thể chỉnh sửa nó thành một câu trả lời độc lập giải thích cách đặt MountFlags = Slave trong Docker Daemon và không phụ thuộc vào ngữ cảnh của các câu trả lời khác. Sau đó tôi sẽ chuyển câu trả lời này sang câu trả lời được chấp nhận.
Caleb

4

Cho phép lan truyền gắn kết được chia sẻ trên ổ đĩa bằng cách thêm cờ: chia sẻ ở cuối đối số âm lượng:

docker run --rm -it -v /tmp:/mnt/tmp:shared alpine sh

Nếu Docker được cài đặt thông qua trình quản lý gói hoặc tập lệnh cài đặt cho systemd, bạn có thể cần điều chỉnh đối số daemon MountFlags. Để làm điều đó, định vị tệp docker.service:

$ sudo find /etc -name "docker.service"

Trong trường hợp của tôi trên Ubuntu 16.04, nó được đặt tại /etc/systemd/system/multi-user.target.wants/docker.service. Chỉnh sửa tệp này bằng vi hoặc nano và đảm bảo rằng tùy chọn MountFlags đọc:

MountFlags=shared

Lưu tệp, tải lại daemon args và khởi động lại docker:

$ sudo systemctl daemon-reload
$ sudo systemctl restart docker

Bây giờ bạn sẽ có thể đặt cờ lan truyền gắn kết chia sẻ trên các ổ đĩa khi sử dụng "docker run".


3

Bắt đầu từ docker 17,06, bạn có thể gắn cổ phiếu NFS trực tiếp vào container khi bạn chạy nó mà không cần thêm khả năng

export NFS_VOL_NAME=mynfs NFS_LOCAL_MNT=/mnt/mynfs NFS_SERVER=my.nfs.server.com NFS_SHARE=/my/server/path NFS_OPTS=vers=4,soft

docker run --mount \
  "src=$NFS_VOL_NAME,dst=$NFS_LOCAL_MNT,volume-opt=device=:$NFS_SHARE,\"volume-opt=o=addr=$NFS_SERVER,$NFS_OPTS\",type=volume,volume-driver=local,volume-opt=type=nfs" \
  busybox ls $NFS_LOCAL_MNT

Ngoài ra, bạn có thể tạo âm lượng trước khi chứa:

docker volume create --driver local \
  --opt type=nfs --opt o=addr=$NFS_SERVER,$NFS_OPTS \
  --opt device=:$NFS_SHARE $NFS_VOL_NAME

docker run --rm -v $NFS_VOL_NAME:$NFS_LOCAL_MNT busybox ls $NFS_LOCAL_MNT

Nhận gợi ý từ https://github.com/moby/moby/issues/28809

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.