Docker 总是有一个USER命令以特定用户身份运行进程,但总的来说,许多事情必须以ROOT身份运行。
USER
我看过很多图像,使用ENTRYPOINTwith gosu来提升运行的过程。
ENTRYPOINT
gosu
我仍然对的需求感到困惑gosu。USER不够吗?
我知道Docker 1.10的安全性已经发生了很大变化,但是我仍然不清楚在Docker容器中运行进程的推荐方法。
有人可以解释的时候我会用gosu对比USER?
谢谢
编辑:
Docker 最佳实践指南不是很明确:它说如果进程可以在没有特权的情况下运行,请使用USER,如果需要sudo,则可能要使用gosu。这很令人困惑,因为可以将各种各样的东西作为ROOT安装在中Dockerfile,然后创建一个用户并赋予它适当的权限,然后最终切换到该用户并以该用户CMD身份运行。那么为什么我们需要sudo gosu呢?
Dockerfile
CMD
Dockerfile用于创建映像。当您无法再在Dockerfile中的运行命令之间更改用户时,我认为gosu作为容器初始化的一部分更有用。
创建映像后,可以使用gosu之类的东西在容器内入口点的末尾删除root权限。您最初可能需要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主机。更改组需要在容器内部具有root用户访问权限。如果我USER jenkins在dockerfile中使用过,我会被镜像中定义的docker组的gid所卡住,如果它与正在运行的docker主机不匹配,它将无法工作。但是,运行gosu所在的应用程序时,可以删除root用户访问权限。
USER jenkins
在脚本末尾,exec调用可防止shell分叉gosu,而是用该进程替换pid 1。Gosu依次执行相同的操作,切换uid,然后执行jenkins进程,以使其接替pid1。这允许正确处理信号,否则外壳将忽略该信号为pid 1。