Nfs

將 NFS 目錄掛載到與 Docker 共享的主機捲中

  • October 3, 2018

考慮以下 Docker 容器:

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

這會將主機目錄 /tmp 掛載到 alpine 容器內的 /mnt/tmp 中。

現在,在主機系統上,我將 NFS 卷掛載到 /tmp 目錄:

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

掛載在主機系統上工作,我看到以下內容:

# ls /tmp/nfs
file1 file2 file3
#

但在 Docker 容器上,我看到一個空白目錄:

# ls /mnt/tmp/nfs
#

我知道我可以通過直接在 Docker 容器中進行掛載來解決這個問題。但我真的很想知道為什麼掛載可以在主機容器上工作,但不能在 docker 容器上工作?

發生這種情況是因為卷正在使用private掛載傳播。這意味著一旦掛載發生,在源端(例如 Docker 的“主機”端)發生的任何更改都不會在掛載下可見。

有幾種方法可以處理這個問題:

  1. 先掛載 NFS,然後啟動容器。掛載將傳播到容器,但是和以前一樣,容器不會看到對掛載的任何更改(包括解除安裝)。
  2. 使用“奴隸”傳播。這意味著一旦創建掛載,源端(docker 主機)上的任何更改都將能夠在目標端(容器中)中看到。如果你碰巧在做嵌套安裝,你會想要使用rslave( rfor recursive)。

還有“共享”傳播。此模式將從容器內部對掛載點的更改傳播到主機,反之亦然。由於您的使用者甚至沒有進行此類更改的權限(除非您添加 CAP_SYS_ADMIN),這可能不是您想要的。

您可以在創建掛載時設置傳播模式,如下所示:

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

另一種選擇是使用捲而不是主機掛載。你可以這樣做:

$ 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

這將確保始終為您安裝在容器中,不依賴於以某種特定方式設置主機或處理安裝傳播。

注意:設備路徑前面的 是必需的,只是關於 nfs 核心模組的一些奇怪的東西。

注意:Docker 目前不能<nfs host>從 DNS 名稱解析(它將在 1.13 中),因此您需要在此處提供 IP 地址。

有關“共享子樹”掛載的更多詳細資訊:https ://www.kernel.org/doc/Documentation/filesystems/sharedsubtree.txt

引用自:https://unix.stackexchange.com/questions/292999