前言
在 Docker 中,默认情况下,容器内运行的进程以 root 用户身份运行,这可能会带来安全隐患。如果将容器的目录挂载到宿主机,容器内创建的文件将归属于宿主机上的 root 用户。本文将介绍如何通过用户命名空间重映射(User Namespaces Remapping)来解决这个问题,使得容器内的 root 用户映射为宿主机上的非特权用户。
步骤
1. 永久修改内核参数
首先,需要确保内核允许创建足够的用户命名空间。默认情况下,user.max_user_namespaces 参数可能为 0,需要将其修改为较大的值,例如 10000。
临时修改内核参数
sudo sysctl -w user.max_user_namespaces=10000
永久修改内核参数
将该参数写入 /etc/sysctl.conf 文件,以确保在系统重启后设置依然生效:
echo "user.max_user_namespaces=10000" | sudo tee -a /etc/sysctl.conf
重新加载 sysctl 配置
sudo sysctl -p
2. 设置 /etc/subuid 和 /etc/subgid 文件
接下来,需要配置子用户和子用户组。假设我们创建了一个用户 lbs,并且其 UID 和 GID 均为 1001。可以使用以下命令确认用户的 UID 和 GID:
id lbs
输出应类似于:
uid=1001(lbs) gid=1001(lbs) groups=1001(lbs),27(sudo),999(docker)
配置 /etc/subuid 文件
sudo nano /etc/subuid
添加以下内容:
lbs:1001:1
lbs:100000:65536
配置 /etc/subgid 文件
sudo nano /etc/subgid
添加以下内容:
lbs:1001:1
lbs:100000:65536
3. 配置 /etc/docker/daemon.json 文件
编辑 Docker 守护进程配置文件 /etc/docker/daemon.json,启用用户命名空间重映射:
sudo nano /etc/docker/daemon.json
添加以下内容:
{
"userns-remap": "lbs"
}
4. 重启 Docker 并启动容器验证
重启 Docker 服务
sudo systemctl restart docker
确认目录权限
确保挂载目录的权限正确:
sudo chown -R lbs:lbs /home/lbs/data
重新尝试运行容器
切换到 lbs 用户并重新运行容器:
su lbs
cd ~
docker run -it --rm \
-v $PWD/data:/data \
bash:5.0 \
touch /data/lbs_with_subuid
检查文件权限
ls -l data
输出应类似于:
-rw-r--r-- 1 lbs lbs 0 0 00:00 lbs_with_subuid
限制
但这个方案会有一些限制:
- 不可使用
--pid=host或--network=host。 - 不可使用无法识别或使用用户映射的挂载磁盘。
- 若使用
docker run --privileged则必须同时使用--userns=host。
总结
通过以上步骤,我们成功地配置了 Docker 的用户命名空间重映射,使得容器内的 root 用户被映射为宿主机上的非特权用户 lbs。这样在挂载目录中创建的文件将归属于 lbs 用户,而不是 root 用户,从而提高了系统的安全性和方便性。
这种方法特别适用于需要在多用户环境中运行 Docker 容器的场景,可以有效避免由于目录挂载权限导致的安全问题。如果还有其他问题或需要进一步配置,请参考 Docker 官方文档或联系系统管理员。