怎么对docker容器中的用户进行隔离

怎么对docker容器中的用户进行隔离?针对这个问题,这篇文章详细介绍了相对应的分析和解答,希望可以帮助更多想解决这个问题的小伙伴找到更简单易行的方法。

让客户满意是我们工作的目标,不断超越客户的期望值来自于我们对这个行业的热爱。我们立志把好的技术通过有效、简单的方式提供给客户,将通过不懈努力成为客户在信息化领域值得信任、有价值的长期合作伙伴,公司提供的服务项目有:域名注册虚拟主机、营销软件、网站建设、孝南网站维护、网站推广。

为钦北等地区用户提供了全套网页设计制作服务,及钦北网站建设行业解决方案。主营业务为成都网站设计、网站制作、外贸营销网站建设、钦北网站设计,以传统方式定制建设网站,并提供域名空间备案等一条龙服务,秉承以专业、用心的态度为用户提供真诚的服务。我们深信只要达到每一位用户的要求,就会得到认可,从而选择与我们长期合作。这样,我们也可以走得更远!

User namespace 的用户映射

在配置 docker daemon 启用 user namespace 前,我需要先来了解一些关于从属(subordinate)用户/组和映射(remapping)的概念。从属用户和组的映射由两个配置文件来控制,分别是 /etc/subuid 和 /etc/subgid。看下它们的默认内容:在配置 docker daemon 启用 user namespace 前,我需要先来了解一些关于从属(subordinate)用户/组和映射(remapping)的概念:

怎么对docker容器中的用户进行隔离

对于 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 的用户:

怎么对docker容器中的用户进行隔离

然后查看 /etc/subuid 和 /etc/subgid 文件中是否添加了新用户 dockremap 相关的项:

怎么对docker容器中的用户进行隔离

接下来我们发现在 /var/lib/docker 目录下新建了一个目录: 165536.165536,查看该目录的权限:

怎么对docker容器中的用户进行隔离

165536 是由用户 dockremap 映射出来的一个 uid。查看 165536.165536 目录的内容:

怎么对docker容器中的用户进行隔离

与 /var/lib/docker 目录下的内容基本一致,说明启用用户隔离后文件相关的内容都会放在新建的 165536.165536 目录下。

通过上面的检查,我们可以确认 docker daemon 已经启用了用户隔离的功能。

宿主机中的 uid 与容器中 uid

在 docker daemon 启用了用户隔离的功能后,让我们看看宿主机中的 uid 与容器中 uid 的变化。

$ docker run -d --name sleepme ubuntu sleep infinity

怎么对docker容器中的用户进行隔离

uid 165536 是用户 dockremap 的一个从属 ID,在宿主机中并没有什么特殊权限。然而容器中的用户却是 root,这样的结果看上去很完美:

怎么对docker容器中的用户进行隔离

新创建的容器会创建 user namespace

在 docker daemon 启用用户隔离的功能前,新创建的容器进程和宿主机上的进程在相同的 user namespace 中。也就是说 docker 并没有为容器创建新的 user namespace:

怎么对docker容器中的用户进行隔离

上图中的容器进程 sleep 和宿主机上的进程在相同的 user namespace 中(没有开启用户隔离功能的场景)。

在 docker daemon 启用用户隔离的功能后,让我们查看容器中进程的 user namespace:

怎么对docker容器中的用户进行隔离

上图中的 4404 就是我们刚启动的容器中 sleep 进程的 PID。可以看出,docker 为容器创建了新的 user namespace。在这个 user namespace 中,容器中的用户 root 就是天神,拥有至高无上的权力!

访问数据卷中的文件

我们可以通过访问数据卷中的文件来证明容器中 root 用户究竟具有什么样的权限?创建四个文件,分别属于用户 root 、165536 和 nick。rootfile 只有 root 用户可以读写,用户 nick 具有 nickfile 的读写权限,uid 165536 具有文件 165536file 的读写权限,任何用户都可以读写 testfile 文件:

怎么对docker容器中的用户进行隔离

下面把这几个文件以数据卷的方式挂载到容器中,并检查从容器中访问它们的权限:

$ docker run -it --name test -w=/testv -v $(pwd)/testv:/testv ubuntu

怎么对docker容器中的用户进行隔离

容器中的 root 用户只能访问 165536file 和 testfile,说明这个用户在宿主机中只有非常有限的权限。

在容器中禁用 user namespace

一旦为 docker daemon 设置了 "userns-remap" 参数,所有的容器默认都会启用用户隔离的功能(默认创建一个新的 user namespace)。有些情况下我们可能需要回到没有开启用户隔离的场景,这时可以通过 --userns=host 参数为单个的容器禁用用户隔离功能。--userns=host 参数主要给下面三个命令使用:

docker container create
docker container run
docker container exec

比如执行下的命令:

$ docker run -d --userns=host --name sleepme ubuntu sleep infinity

查看进程信息:

怎么对docker容器中的用户进行隔离

进程的有效用户又成 root 了,并且也没有为进程创建新的 user namespace:

怎么对docker容器中的用户进行隔离

已知问题

User namespace 属于比较高级的功能,目前 docker 对它的支持还算不上完美,下面是已知的几个和现有功能不兼容的问题:

  • 共享主机的 PID 或 NET namespace(--pid=host or --network=host)

  • 外部的存储、数据卷驱动可能不兼容、不支持 user namespace

  • 使用 --privileged 而不指定 --userns=host

总结

Docker 是支持 user namespace 的,并且配置的方式也非常简便。在开启 user namespace 之后我们享受到了安全性的提升,但同时也会因为种种限制让其它的个别功能出现问题。这时我们需要作出选择,告别一刀切的决策,让合适的功能出现的合适的场景中。

关于怎么对docker容器中的用户进行隔离问题的解答就分享到这里了,希望以上内容可以对大家有一定的帮助,如果你还有很多疑惑没有解开,可以关注创新互联行业资讯频道了解更多相关知识。


分享文章:怎么对docker容器中的用户进行隔离
本文来源:http://azwzsj.com/article/jjiejd.html