Docker - 可以将 NFS 共享挂载到容器中,但不能挂载到容器的子目录中

use*_*919 7 nfs docker

我有一个具有以下属性的 NFS 共享:

  • 安装在我的主机上 /nfs/external_disk
  • 所有者用户test_userUID 1234
  • 团体test_groupGID 2222
  • 权限是 750

我有一个包含以下内容的小型 Dockerfile

ARG tag=lts
from jenkins/jenkins:${tag}

user root

# Create a new user and new group that matches what is on the host.
ARG username=test_user
ARG groupname=test_group
ARG uid=1234
ARG gid=2222
RUN groupadd -g ${gid} ${groupname} && \
    mkdir -p /users && \
    useradd -l -m -u ${uid} -g ${groupname} -s /bin/bash -d /users/${username} ${username}

user ${username}
Run Code Online (Sandbox Code Playgroud)

构建映像(名为custom_jenkins)后,当我运行以下命令时,容器已正确启动,我看到原始的 Jenkins 本垒打内容现在已复制到共享中。

docker run -td --rm -v /nfs/external_disk:/var/jenkins_home custom_jenkins

但是,如果我想挂载 NFS 共享的子目录,例如${NFS_SHARE}/jenkins_home,则会出现错误:

docker run -td --rm -v /nfs/external_disk/jenkins_home:/var/jenkins_home custom_jenkins

docker:来自守护进程的错误响应:创建挂载源路径“/nfs/external_disk/jenkins_home”时出错:mkdir /nfs/external_disk/jenkins_home:权限被拒绝。

现在,即使我尝试在启动容器之前自己创建子目录,我仍然会遇到相同的错误。即使我将子目录的权限设置为777.

请注意,我正在运行,test_user它具有与容器中相同的 UID/GID,并且它实际上拥有 NFS 共享。

我有一种感觉,当 docker 尝试创建一个子目录时,它会尝试将它创建为某个不同的用户(例如“docker”用户),这会导致它在创建文件夹时失败,因为它在共享中没有访问权限。

任何人都可以帮忙吗?提前致谢。

Neo*_*son 2

我尝试重现。对我来说效果很好。也许我缺少一些约束。无论如何希望这会有所帮助。请注意第 6 步中我从容器创建的文件的所有者和组。这可能会回答您的问题之一。

第 1 步:我在 LAN 中的某个位置创建了一个 NFS 共享
第 2 步:我在运行 docker 引擎的计算机上安装了该共享

sudo mount 192.168.0.xxx:/i-data/b4024d5b/nfs/NFS /mnt/nsa320/
Run Code Online (Sandbox Code Playgroud)
neo@neo-desktop:nsa320$ mount | grep NFS
192.168.0.xxx:/i-data/b4024d5b/nfs/NFS on /mnt/nsa320 type nfs (rw,relatime,vers=3,rsize=32768,wsize=32768,namlen=255,hard,proto=tcp,timeo=600,retrans=2,sec=sys,mountaddr=192.168.0.xxx,mountvers=3,mountport=3775,mountproto=udp,local_lock=none,addr=192.168.0.xxx)
Run Code Online (Sandbox Code Playgroud)

第 3 步:我创建了一些示例文件和一个子目录:

neo@neo-desktop:nsa320$ ls -la /mnt/nsa320/
total 12
drwxrwxrwx 3 root root 4096 Jul 21 22:54 .
drwxr-xr-x 3 root root 4096 Jul 21 22:41 ..
-rw-r--r-- 1 neo  neo     0 Jul 21 22:45 dummyFile
-rw-r--r-- 1 root root    0 Jul 21 22:53 fileCreatedFromContainer << THIS WAS CREATED FROM A CONTAINER THAT WAS NOT LAUNCHED WITH THE --user OPTION
drwxr-xr-x 2 neo  neo  4096 Jul 21 22:54 subfolder

Run Code Online (Sandbox Code Playgroud)

步骤 4:启动虚拟容器并安装子目录(1000 是neo我的操作系统中用户的 UID):

docker run -d -v /mnt/nsa320/subfolder:/var/externalMount --user 1000 alpine tail -f /dev/null
Run Code Online (Sandbox Code Playgroud)

步骤5:在容器中连接以检查挂载(我可以在位于NFS上的子文件夹中读写)

neo@neo-desktop:nsa320$ docker exec -ti ded1dc79773e sh
/ $ ls /var/externalMount/
fileInSubfolder
/ $ touch /var/externalMount/fileInSubfolderCreatedFromContainer
Run Code Online (Sandbox Code Playgroud)

第6步:回到主机,我从容器中创建的文件属于谁:

neo@neo-desktop:nsa320$ ls -la /mnt/nsa320/subfolder/
total 8
drwxr-xr-x 2 neo  neo  4096 Jul 21 23:23 .
drwxrwxrwx 3 root root 4096 Jul 21 22:54 ..
-rw-r--r-- 1 neo  neo     0 Jul 21 22:54 fileInSubfolder
-rw-r--r-- 1 neo  root    0 Jul 21 23:23 fileInSubfolderCreatedFromContainer
Run Code Online (Sandbox Code Playgroud)

也许偏离主题:在容器中执行的 whoami 仅返回 UID:

$ whoami
whoami: unknown uid 1000
Run Code Online (Sandbox Code Playgroud)