Docker中使用userns

您所在的位置:网站首页 docker权限设置 Docker中使用userns

Docker中使用userns

2023-07-17 12:55| 来源: 网络整理| 查看: 265

使用普通用户运行docker容器

在docker中,在容器内创建的文件在从主机检查时往往具有不可预测的所有权。默认情况下,卷上文件的所有者是root(uid 0),但只要非root用户帐户涉及容器并写入文件系统,所有者就会从主机角度变得或多或少随机 。 您需要使用调用docker命令的同一用户帐户从主机访问卷数据时,这是一个问题. 典型的解决方法是

在Dockerfiles中创建时强制用户uID(非可移植)将主机用户的UID作为环境变量传递给docker run命令,然后在入口点脚本中的卷上运行一些chown 命令 .

这两种解决方案都可以控制容器外的实际权限. 用户命名空间( user namespace)是这个问题的最终解决方案. 通过 user namespace 技术,把宿主机中的一个普通用户(只有普通权限的用户)映射到容器中的 root 用户。在容器中,该用户在自己的 user namespace 中认为自己就是 root,也具有 root 的各种权限,但是对于宿主机上的资源,它只有很有限的访问权限(普通用户)。

使用user namespace进行权限隔离设置如下:

1、kernel内核开启namespace grubby --args="namespace.unpriv_enable=1 user_namespace.enable=1" --update-kernel="$(grubby --default-kernel)" echo "user.max_user_namespaces=15076" >> /etc/sysctl.conf

重启系统生效

reboot 2、新建用户(这里的用户名为:dku) useradd -u 5000 dku groupadd -g 500000 dku-root useradd -u 500000 -g dku-root dku-root

在/etc/subuid 和 /etc/subgid 文件中修改自动生成的从属ID范围: dku:500000:65536 如果这两个文件有内容,就可以执行以下sed命令进行修改,没内容手动添加进入即可。

sed -ri '/dku/s/:[0-9]+:/:500000:/' /etc/subuid sed -ri '/dku/s/:[0-9]+:/:500000:/' /etc/subgid

用户dku 在当前的 user namespace 中具有 65536 个从属用户,用户 ID 为 500000-565535,在一个子 user namespace 中,这些从属用户被映射成 ID 为 0-65535 的用户。subgid 的含义和 subuid 相同。

3、使用docker权限映射(注意:使用映射代表容器root用户映射到宿主机docker指定的用户uid上)

这里有3步: (1)在/etc/default/docker上追加配置DOCKER_OPTS (2)修改 /usr/lib/systemd/system/docker.service 启动文件,在ExecStart前添加 EnvironmentFile变量文件 (3)修改 /usr/lib/systemd/system/docker.service 启动文件中的ExecStart,最后添加$DOCKER_OPTS

echo 'DOCKER_OPTS="--userns-remap=dku"' >> /etc/default/docker sed -i '/ExecStart/iEnvironmentFile=/etc/default/docker' /usr/lib/systemd/system/docker.service sed -i 's/ExecStart.*/& $DOCKER_OPTS/' /usr/lib/systemd/system/docker.service

重新启动docker:

systemctl daemon-reload systemctl restart docker.service 4、访问数据卷中的文件

假如,在容器里面创建一个 UID 为1000 的 test 用户,他能读取挂载在容器里面的什么权限的文件呢? 测试文件权限:在系统的 /data/test 目录上,创建几个不同的测试文件 1. 一个属主和属组都为 501000 的文件,权限为600,文件名为:501000.txt 。 3. 一个属主和属组都为 dku-root (UID为500000)的文件,权限为600,文件名为:dku-root.txt 。 4. 一个在系统上权限为 root (UID为0)的文件,权限为600,文件名为:root.txt 。 5. 一个在系统上权限为 root (UID为0)的文件,权限为666,文件名为:test.txt 。

在这里插入图片描述 6.启动一个centos 7.9 的容器,并在里面创建一个 UID 为 1000 的test 用户,进入挂载的 /test 目录。 查看权限如下: 在这里插入图片描述 结果是只有 501000.txt 和 test.txt 这两个文件可以看到里面内容。剩下两个均没有权限。其中501000.txt 有权限,是因为在系统上这个文件的属主和属组都是 501000,其映射在容器里面的属主和属组就是1000,所以UID 为 1000 的 test 用户可以查看里面的内容。 test.txt 能查看,因为文件的权限是666,other 位的权限是 rw,所以其他用户都有权限查看。

所以要给容器里面挂载一个有root 权限的目录,在系统上就需要给这个目录 权限给dku-root。比如要挂载的目录是 /data,那命令就是命令如下:

chown -R dku-root:dku-root /data 5、宿主机的进程 UID 和 容器的 UID

当启动了user namespace 后,容器里面的进程是怎样的呢?指定root 用户启动一个 centos 7.9 的容器,里面执 sleep 1000 命令。 在这里插入图片描述 在系统中查看该sleep 1000 的进程属主时发现不是 root,而是定义的UID 为 500000 的 dku-root 用户。 在这里插入图片描述 有没有办法可以在启动 user namespace 情况下,里面的进行又想恢复 root 运行呢?也是有的。

6、在容器中禁用 user namespace

一旦为docker daemon设置了"userns-remap"参数,所有的容器默认都会启用用户隔离的功能(默认创建一个新的 user namespace)。有些情况下我们可能需要回到没有开启用户隔离的场景,,这时可以通过--userns=host参数为单个的容器禁用用户隔离功能。在version: "3"版本的docker-compose.yml文件中对应的容器增加userns_mode: "host"

以同样的 sleep 1000 为例子,启动的时候加上--userns=host: 在这里插入图片描述 在系统中,查看 sleep 1000 进程时,进程的属主恢复为 root。 在这里插入图片描述

参考地址:https://www.shuzhiduo.com/A/ZOJPrrrxdv/



【本文地址】


今日新闻


推荐新闻


CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3