启用用户命名空间隔离需三步:1.配置/etc/subuid和/subgid映射;2.在daemon.json中设置"userns-remap"字段;3.调整绑定挂载目录属主为映射uid范围,重启docker后验证进程uid是否落入子id区间。
在 daemon.json 中启用用户命名空间(user namespace)隔离,核心是配置 "userns-remap" 字段,并确保宿主机已正确准备子用户/组映射。这不是一个“开箱即用”的开关,而是需要前后协同的三步动作:配置映射规则 → 修改 daemon 配置 → 调整挂载路径权限。
1. 先配置 /etc/subuid 和 /etc/subgid
Daemon 启用 userns-remap 依赖系统级的 UID/GID 映射表。必须先为某个用户(如 dockremap 或你指定的普通用户)分配一段连续的子 ID 范围:
- 执行命令添加映射(以
100000~165535为例):echo "dockremap:100000:65536" | sudo tee -a /etc/subuidecho "dockremap:100000:65536" | sudo tee -a /etc/subgid - 若使用
"userns-remap": "default",Docker 会自动创建dockremap用户并写入上述文件;但手动预设更可控、更清晰 - 确保该用户存在:
sudo useradd -r -u 1001 dockremap(UID 1001 仅为示例,不参与映射,仅作命名空间 owner)
2. 在 daemon.json 中启用 remap
编辑 /etc/docker/daemon.json,加入 userns-remap 配置项:
- 最简方式(使用默认用户):
{"userns-remap": "default"} - 指定映射用户(推荐,便于审计和权限收敛):
{"userns-remap": "dockremap"} - 也可为不同环境配置不同 remap 用户,例如:
{"userns-remap": "user-a"},前提是/etc/subuid中已定义user-a的映射段
⚠️ 注意:userns-remap 启用后,Docker 会自动重置 /var/lib/docker 所有权,并要求所有绑定挂载目录(-v)的属主与 remap 范围对齐,否则容器启动失败。
3. 同步调整绑定挂载目录权限
容器内 UID 0(root)将映射到宿主机上 100000 起始的 UID。因此,挂载进容器的宿主机目录必须归属该范围:
- 例如挂载
/home/user-a/app-data到容器/app/data:sudo chown -R 100000:100000 /home/user-a/app-data - 若用
default模式且未自定义 subuid,Docker 默认使用100000:65536,仍需按此范围设属主 - 建议配合
id -u dockremap和getent subuid dockremap确认实际映射起始值
4. 重启并验证是否生效
保存配置后重启服务:
sudo systemctl restart docker- 运行测试容器:
docker run --rm alpine id,输出应为uid=0(root) gid=0(root)(容器内视角) - 查宿主机进程:
ps aux | grep containerd-shim,观察其真实 UID 是否落在100000+区间 - 检查
/proc/[pid]/status中的Uid:行,确认映射生效
启用后,--privileged 将被强制拒绝,这是安全兜底机制;同时需注意现有镜像、卷、构建缓存会因所有权变更而不可用,首次启用需清空或迁移数据。











