Docker使用gosu和USER

Dockertypes总是有一个USER命令来运行一个特定用户的进程,但总的来说很多东西都必须作为ROOT来运行。

我已经看到很多使用ENTRYPOINT的图像去ENTRYPOINT进程运行。

我对gosu的需求还是有点困惑。 用户不够用?

我知道Docker 1.10在安全性方面已经发生了很大的变化,但我仍然不清楚在docker容器中运行一个进程的推荐方式。

有人可以解释我什么时候使用gosu vs. USER吗?

谢谢

编辑:

Docker 最佳实践指南并不十分清楚:它说如果进程可以无特权运行,使用USER ,如果需要sudo,则可能需要使用gosu 。 这是令人困惑的,因为可以在Dockerfile各种东西安装为ROOT,然后创build一个用户并给予适当的权限,最后切换到该用户并以该用户身份运行CMD 。 那么为什么我们需要sudo或gosu

Dockerfiles用于创build图像。 当你不能再在Dockerfile中的运行命令之间改变用户时,我将gosu看作是容器初始化的一部分。

在创build映像之后,像gosu这样的东西允许您在容器内的入口点结束时删除根权限。 您可能最初需要root权限才能执行一些初始化步骤(修复uid,主机装入的卷权限等)。 然后,一旦初始化,你运行没有root权限的最终服务,并作为PID 1干净地处理信号。


编辑:这里是一个简单的例子,在docker和jenkins的图像中使用gosu: https : //github.com/bmitch3020/jenkins-docker

entrypoint.sh查找/var/lib/docker.sock文件的gid,并更新容器内的docker用户的gid以匹配。 这允许将图像移植到主机上的gid可能不同的其他docker主机。 更改组需要在容器内部进行根访问。 如果我在USER jenkins中使用了USER jenkins ,那么我将停留在图像中定义的docker组的gid,如果它不匹配正在运行的docker主机,那么将无法工作。 但是在运行gosu进入的应用程序时,可以放弃root权限。

在脚本的最后,exec调用阻止shell分叉gosu,而是用这个过程replacepid 1。 Gosu反过来也是这样做的,切换uid,然后执行jenkins过程,以便接pipepid 1.这样可以正确处理信号,否则shell将会忽略这些信号作为pid 1。

我正在使用gosu和entrypoint.sh,因为我希望容器中的用户具有与创build容器的用户相同的UID。

Docker卷和权限。

我创造的容器的目的是为了发展。 我需要为Linux构build,但我仍然希望所有的本地(OS X)编辑,工具等的保留。我保持容器内部和外部相同的UID,它使文件的所有权更加理智,并防止一些错误容器用户不能编辑装入卷中的文件等)

使用gosu好处也是信号处理。 您可能会trap重新加载进程的SIGHUP实例,就像您通常通过systemctl reload <process>等实现的那样。