Docker启用User Namespace后,容器内UID 0映射为宿主机普通UID(如100000),实现“假root、真受限”;需配置daemon.json启用userns-remap,自动创建dockremap用户及子ID范围,挂载卷时须同步属主至映射UID,且--privileged等特权操作被禁用。

在 Docker 中启用 User Namespace,核心目标是让容器内 UID 0(root)不再等同于宿主机的 root,而是映射为宿主机上一个普通、无特权的 UID(如 100000),从而切断容器逃逸后直接操控宿主机关键资源的能力。这不是禁止 root,而是“假 root、真受限”。
配置 Docker Daemon 启用全局 UserNS 映射
修改 /etc/docker/daemon.json,添加并保存:
{
"userns-remap": "default"
}
执行 sudo systemctl restart docker 重启服务。Docker 会自动创建系统用户 dockremap,并在 /etc/subuid 和 /etc/subgid 中为其分配一段子 ID 范围(例如 dockremap:100000:65536)。此后所有容器运行时,其内部 UID/GID 都会按此偏移映射到宿主机。
理解并验证 UID 映射效果
启动一个容器:docker run -it --rm alpine id,输出显示 uid=0(root) gid=0(root);但回到宿主机执行 ps aux | grep apk 或查看对应进程,你会发现该进程实际以 UID 100000+ 运行,而非 0。
这种映射是透明且强制的:容器内一切操作(包括文件属主、进程权限)都基于映射后的 UID 计算,但对容器自身完全无感。
适配挂载卷与权限一致性
使用 -v 挂载宿主机目录时,若容器内需写入,宿主机目录的属主必须设为映射范围内的 UID/GID,否则权限拒绝:
- 查映射起始 UID:awk -F':' '/dockremap/ {print $2}' /etc/subuid(通常为 100000)
- 同步属主:sudo chown -R 100000:100000 /host/data
- 镜像中硬编码的非 root 用户(如 USER 1001)也会被整体偏移(→ 101001),不影响应用逻辑
避开常见冲突与限制
User Namespace 与部分高危能力互斥,启用后以下操作将失败或被忽略:
- --privileged:完全禁用,因特权模式要求真实 root 权限
- --cap-add=CAP_SYS_ADMIN:几乎等同于 root,不应添加
- 绑定挂载 /var/run/docker.sock:需额外映射 docker 组 GID,否则容器无法调用 Docker API
- 构建阶段(docker build)不运行在 UserNS 下,仅运行时(docker run)生效


















