Docker挂载NFS目录权限异常:用户有权限但stat失败求助
使用--mount选项时的报错
执行命令:
docker run --mount type=bind,source=/home/myuser/docker_test/out_dir,target=/home/out_dir --user 12345:1000 -it docker-name:0.1 bash
返回错误:
docker: Error response from daemon: invalid mount config for type "bind": stat /home/myuser/docker_test/out_dir: permission denied.
本地执行stat目录正常:
stat /home/myuser/docker_test/out_dir
输出:
File: '/home/myuser/docker_test/out_dir'
Size: 4096 Blocks: 8 IO Block: 32768 directory
Device: 33h/51d Inode: 9275022755226025350 Links: 2
Access: (0770/drwxrwx---) Uid: (12345/ myuser) Gid: ( 1000/ hercules)
Access: 2022-12-01 02:12:54.430582000 -0500
Modify: 2022-12-01 02:12:38.239629000 -0500
Change: 2022-12-01 02:12:38.239629000 -0500
Birth: -
使用-v选项时的报错
执行命令:
docker run -v /home/myuser/docker_test/out_dir:/home/out_dir --user 12345:1000 -it docker-name:0.1:0.1 bash
返回错误:
docker: Error response from daemon: error while creating mount source path '/home/myuser/docker_test/out_dir': mkdir /home/myuser/docker_test: permission denied.
ERRO[0000] error waiting for container: context canceled
补充信息
- 操作环境:无root权限的网络机器,Docker服务由root安装
- 目录情况:/home是NFS挂载目录,挂载/tmp可正常工作;/home/myuser/docker_test/out_dir权限为700,无法修改为755
- 疑问:为何自身有权限访问目录,但Docker执行stat时失败?Docker是否以其他用户身份执行stat?
核心原因:Docker守护进程以root运行,NFS默认的root_squash限制了root访问
Docker守护进程(dockerd)始终以root身份运行,哪怕你用普通用户执行docker run,实际处理挂载请求的是root身份的守护进程。而NFS挂载默认启用root_squash选项,该选项会把远程root用户的权限映射为NFS服务器上的匿名用户(nobody/nfsnobody),导致root无法访问你权限为700的目录(700仅允许目录所有者访问)。
两种报错的具体解释
--mount报错:dockerd以root身份执行stat检查目录时,被NFS的root_squash映射为匿名用户,而你的目录权限是700,匿名用户无访问权限,因此返回permission denied。-v报错:使用-v选项时,如果Docker守护进程因权限问题看不到已存在的挂载源路径,会尝试自动创建父目录。这里dockerd因为被squash为匿名用户,看不到已存在的/home/myuser/docker_test,所以尝试创建它,但同样没有权限,因此报错。
可行解决思路(无需修改目录权限)
- 联系NFS管理员,针对你的目录禁用
root_squash(设置no_root_squash),让Docker的root身份能正常访问该目录。 - 如果无法修改NFS配置,可将需要挂载的内容复制到本地非NFS目录(比如/tmp),再挂载到容器中,因为/tmp是本地目录,不受NFS权限限制。
内容的提问来源于stack exchange,提问作者Raj Malhotra

