码头使用高速对 USER

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

我见过很多使用 ENTRYPOINTgosu来降低运行过程的图像。

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

我知道 Docker 1.10在安全性方面有了很大的改变,但是我仍然不清楚在 Docker 容器中运行流程的推荐方法。

有人能解释一下我什么时候用 gosuUSER吗?

谢谢

编辑:

Docker 最佳实践指南不是很清楚: 它说如果进程可以在没有特权的情况下运行,那么使用 USER,如果需要 sudo,那么可能需要使用 gosu。 这是令人困惑的,因为可以在 Dockerfile中以 ROOT 的形式安装各种东西,然后创建一个用户并给它适当的特权,最后切换到该用户并以该用户的身份运行 CMD。 那么我们为什么需要 sudo 或 gosu呢?

59628 次浏览

I am using gosu and entrypoint.sh because I want the user in the container to have the same UID as the user that created the container.

Docker Volumes and Permissions.

The purpose of the container I am creating is for development. I need to build for linux but I still want all the connivence of local (OS X) editing, tools, etc. My keeping the UIDs the same inside and outside the container it keeps the file ownership a lot more sane and prevents some errors (container user cannot edit files in mounted volume, etc)

Dockerfiles are for creating images. I see gosu as more useful as part of a container initialization when you can no longer change users between run commands in your Dockerfile.

After the image is created, something like gosu allows you to drop root permissions at the end of your entrypoint inside of a container. You may initially need root access to do some initialization steps (fixing uid's, host mounted volume permissions, etc). Then once initialized, you run the final service without root privileges and as pid 1 to handle signals cleanly.


Edit: Here's a simple example of using gosu in an image for docker and jenkins: https://github.com/bmitch3020/jenkins-docker

The entrypoint.sh looks up the gid of the /var/lib/docker.sock file and updates the gid of the docker user inside the container to match. This allows the image to be ported to other docker hosts where the gid on the host may differ. Changing the group requires root access inside the container. Had I used USER jenkins in the dockerfile, I would be stuck with the gid of the docker group as defined in the image which wouldn't work if it doesn't match that of the docker host it's running on. But root access can be dropped when running the app which is where gosu comes in.

At the end of the script, the exec call prevents the shell from forking gosu, and instead it replaces pid 1 with that process. Gosu in turn does the same, switching the uid and then exec'ing the jenkins process so that it takes over as pid 1. This allows signals to be handled correctly which would otherwise be ignored by a shell as pid 1.

Advantage of using gosu is also signal handling. You may trap for instance SIGHUP for reloading the process as you would normally achieve via systemctl reload <process> or such.