Docker userns-remap配置后容器无法写入挂载目录求助
我之前也碰到过一模一样的问题,核心原因其实很明确:开启userns-remap后,容器内的root用户会被映射到主机上test用户对应的subuid/subgid范围(也就是100000-165535),而你挂载的目录默认权限大概率不允许这个UID段的用户写入,所以才会出现写入失败的情况。下面是一步步的排查和解决步骤:
1. 先确认挂载目录的权限现状
在主机上执行命令查看挂载目录的权限详情:
ls -ld /path/to/your/mount/dir
你会看到目录的所有者、组以及对应的读写执行权限,默认情况下这个目录可能只对主机root或特定普通用户开放写入权限,而映射后的容器用户(UID 100000+)不在允许范围内。
2. 调整挂载目录的权限或ACL
最精准的方式是给这个目录添加ACL规则,直接允许映射后的UID范围拥有读写权限:
# 给目录内已存在的文件/子目录添加权限 setfacl -R -m u:100000:rwx /path/to/your/mount/dir # 确保后续在目录内新建的文件也自动继承这个权限 setfacl -R -m d:u:100000:rwx /path/to/your/mount/dir
如果你的挂载目录原本就属于test用户,也可以直接修改目录的所属组,但要注意test的主UID和subuid是独立的范围,用ACL的方式适配映射场景更稳妥。
3. 验证用户映射是否真的生效
可以先启动一个测试容器,进入容器后执行id,你会看到容器内显示的是uid=0(root);然后回到主机上查看这个容器进程的实际UID:
ps aux | grep <container-name-or-id>
你应该能看到进程的UID是100000左右的数值,这就说明用户命名空间的映射确实生效了。
4. 确认Docker守护进程已正确重启
修改/etc/docker/daemon.json后,必须重启Docker服务才能让配置生效:
systemctl restart docker
如果之前没重启的话,userns的配置可能还停留在旧状态,这也会导致权限不匹配的问题。
5. 排查安全模块限制(SELinux/AppArmor)
如果你的Linux发行版开启了SELinux(比如CentOS/RHEL系列),可能会阻止容器写入挂载目录。可以临时关闭SELinux测试:
setenforce 0
如果此时容器能正常写入了,就需要给挂载目录设置正确的SELinux上下文:
chcon -Rt svirt_sandbox_file_t /path/to/your/mount/dir
对于开启AppArmor的系统(比如Ubuntu),可以检查对应的容器配置是否限制了文件访问权限。
内容的提问来源于stack exchange,提问作者Danilo Radenovic

