DEBUG.WIKI
京东云;让 AI 进入真实业务;零售 · 物流 · 客服 · 硬件;查看方案 →
ZgoCloud:多地区部署,按需选节点;日本、美国、香港、德国
Evoxt;最高 6.0GHz CPU;高频云服务器 · 免费每周备份;查看配置 →

Docker 开启 userns-remap 后,root 也不能修改挂载文件

容器root无法修改绑定挂载文件时,核对UID/GID重映射与宿主数字权限,在专用目录落实授权,避免关闭隔离或递归放宽。

容器里 id 显示 root,绑定挂载的文件却显示为 nobody,修改内容或执行 chmod 时仍报 Permission denied。如果 Linux Docker daemon 开启了 userns-remap,先核对用户命名空间映射:容器内的 UID 0,并不是宿主机的 UID 0。

这里针对普通 rootful Linux Engine 的用户命名空间重映射与 bind mount。Rootless Docker、Docker Desktop 文件共享及其他映射挂载需要按各自实现判断;不能直接把本机 Linux 的数字属主方案搬过去。

root 的编号需要换算到宿主机

userns-remap 为容器内的 UID、GID 指定宿主机上的从属编号范围。例如映射为:

         0     231072      65536

三列依次是命名空间内起始编号、外部起始编号、范围长度。这个示例中,容器 UID 0 对应宿主机 UID 231072,容器 UID 1000 对应宿主机 UID 232072。GID 有自己的映射,不能只查 UID 就推算全部权限。

231072 是示意数字,应以当前容器的实际映射为准。负责重映射的宿主机账户,例如 dockremap,其普通登录 UID 也不等于容器 root 映射后的 UID,不能直接把文件交给那个账户就认为已经匹配。

宿主机文件的属主如果不在当前映射范围内,容器里的名称或数字显示可能与宿主机不同。看到 nobody 只是线索,还要查宿主机的真实数字与容器映射;不能反向认定宿主文件真的属于 nobody。

同时查看进程、映射和真实源目录

先确认连接的是目标 Docker daemon。下面的 app-container 和路径都是占位值;镜像有相应工具时,可以只读查看:

docker inspect app-container --format '{{json .Mounts}}'
docker exec app-container id
docker exec app-container cat /proc/self/uid_map
docker exec app-container cat /proc/self/gid_map
docker exec app-container ls -ldn /data

检查实际 bind mount 的 Source、Destination 和可写标志,再到 daemon 所在的 Linux 宿主机查看源目录、父目录及失败文件的数字属主和模式。远程 Docker 的源目录在服务端,CLI 所在电脑上的同名目录不能代替它。

exec 的默认身份也不一定是应用身份。入口脚本如果降权,应核对真正访问文件的进程 UID、GID、附加组,再按它所在的映射范围换算。不要拿一个 root 诊断 shell 的输出代表全部 worker。

还要区分操作:修改文件内容看文件的写权限;删除文件主要涉及父目录的写入和搜索权限,并可能受 sticky bit 等条件限制。目录放成 777 后能够删除文件,并不能证明应用也有权修改文件或改变它的模式。

在专用挂载目录上落实映射后的权限

确认失败确实由身份映射与普通权限不匹配造成后,为这个服务准备专用数据目录,再按实际应用身份的宿主机映射编号设置属主、组或必要 ACL。只需要共享读访问时,也应按已有共享组与授权范围设计,不必把所有文件都交给容器 root。

变更前记录原属主、模式、ACL 与共享方,保留数据备份。先在隔离环境用相同映射和应用用户验证,再对明确范围内的目录实施。不要对 /home、整个项目树或其他服务的数据目录递归 chown;同一个宿主机数字身份也可能影响其他访问主体。

镜像里的 COPY --chown 不会修改运行时绑定挂载的宿主文件。挂载会遮住镜像中该位置的内容,修 Dockerfile 里的属主通常不能解决这个路径的问题。类似的镜像构建问题可另看非 root 构建时 COPY 后 chmod 失败。

也不要先关闭 userns-remap、加特权或放宽到 777。启用或停用 daemon 重映射还会影响 Docker 对既有镜像、容器等对象的可见布局,范围远超过一个目录的访问错误。

用原应用身份验收读写

修正后重复原先失败的业务文件操作,核对路径仍是预期挂载、进程身份没有被改成宿主高权限用户,以及其他共享方仍能按设计访问。仅看 root shell 能列目录,还不足以证明应用已恢复。

数字身份与模式正确却仍失败时,再查只读挂载、父目录、ACL 和实际安全拒绝记录。若有 SELinux AVC,应采用绑定挂载安全标签的检查路径,不要用不断扩大普通权限替代标签核对。

回退依据保存的属主、模式、ACL 和部署配置进行。恢复权限不会撤回变更期间已经写入或删除的数据;需要恢复内容时,单独按数据备份处理。