怎么对docker容器中的用户进行隔离?针对这个问题,这篇文章详细介绍了相对应的分析和解答,希望可以帮助更多想解决这个问题的小伙伴找到更简单易行的方法。
User namespace 的用户映射
在配置 docker daemon 启用 user namespace 前,我需要先来了解一些关于从属(subordinate)用户/组和映射(remapping)的概念。从属用户和组的映射由两个配置文件来控制,分别是 /etc/subuid 和 /etc/subgid。看下它们的默认内容:在配置 docker daemon 启用 user namespace 前,我需要先来了解一些关于从属(subordinate)用户/组和映射(remapping)的概念:
对于 subuid,这一行记录的含义为:
用户 nick,在当前的 user namespace 中具有 65536 个从属用户,用户 ID 为 100000-165535,在一个子 user namespace 中,这些从属用户被映射成 ID 为 0-65535 的用户。subgid 的含义和 subuid 相同。
比如说用户 nick 在宿主机上只是一个具有普通权限的用户。我们可以把他的一个从属 ID(比如 100000 )分配给容器所属的 user namespace,并把 ID 100000 映射到该 user namespace 中的 uid 0。此时即便容器中的进程具有 root 权限,但也仅仅是在容器所在的 user namespace 中,一旦到了宿主机中,你顶多也就有 nick 用户的权限而已。
当开启 docker 对 user namespace 的支持时(docker 的 userns-remap 功能),我们可以指定不同的用户映射到容器中。比如我们专门创建一个用户 dockeruser,然后手动设置其 subuid 和 subgid:
nick:100000:65536 dockeruser:165536:65536并把它指定给 docker daemon:
{ "userns-remap": "dockeruser" }请注意 subuid 的设置信息,我们为 dockeruser 设置的从属 ID 和 nick 用户是不重叠的,实际上任何用户的从属 ID 设置都是不能重叠的。
或者一切从简,让 docker 为我们包办这些繁琐的事情,直接把 docker daemon 的 userns-rempa 参数指定为 "default":
{ "userns-remap": "default" }这时,docker 会自动完成其它的配置。
配置 docker daemon 启用用户隔离
这里笔者采取简单的方式,让 docker 创建默认的用户用于 user namespace。我们需要先创建 /etc/docker/daemon.json 文件:
$ sudo touch /etc/docker/daemon.json然后编辑其内容如下(如果该文件已经存在,仅添加下面的配置项即可),并重启 docker 服务:
{ "userns-remap": "default" }$ sudo systemctl restart docker.service下面我们来验证几个关于用户隔离的几个点。
首先验证 docker 创建了一个名为 dockremap 的用户:
然后查看 /etc/subuid 和 /etc/subgid 文件中是否添加了新用户 dockremap 相关的项:
接下来我们发现在 /var/lib/docker 目录下新建了一个目录: 165536.165536,查看该目录的权限:
165536 是由用户 dockremap 映射出来的一个 uid。查看 165536.165536 目录的内容:
与 /var/lib/docker 目录下的内容基本一致,说明启用用户隔离后文件相关的内容都会放在新建的 165536.165536 目录下。
通过上面的检查,我们可以确认 docker daemon 已经启用了用户隔离的功能。
宿主机中的 uid 与容器中 uid
在 docker daemon 启用了用户隔离的功能后,让我们看看宿主机中的 uid 与容器中 uid 的变化。
$ docker run -d --name sleepme ubuntu sleep infinityuid 165536 是用户 dockremap 的一个从属 ID,在宿主机中并没有什么特殊权限。然而容器中的用户却是 root,这样的结果看上去很完美:
新创建的容器会创建 user namespace
在 docker daemon 启用用户隔离的功能前,新创建的容器进程和宿主机上的进程在相同的 user namespace 中。也就是说 docker 并没有为容器创建新的 user namespace:
上图中的容器进程 sleep 和宿主机上的进程在相同的 user namespace 中(没有开启用户隔离功能的场景)。
在 docker daemon 启用用户隔离的功能后,让我们查看容器中进程的 user namespace:
郑重声明:本文版权归原作者所有,转载文章仅为传播更多信息之目的,如作者信息标记有误,请第一时间联系我们修改或删除,多谢。