这是一个简单的工具,其简单的事实是, su
和sudo
具有非常奇怪且常常令人讨厌的TTY和信号抛光行为。它们的设置和使用也有些复杂(尤其是在sudo
的情况下),这允许表现出很大的表现力,但是如果您需要的只是“作为此特定用户运行此特定应用程序并退出管道”。
gosu
工作原理的核心是直接从Docker/LibContainer本身启动容器内的应用程序(实际上,实际上是在Libcontainer的代码库中直接使用/etc/passwd
处理代码)的核心。
$ gosu
Usage: ./gosu user-spec command [args]
eg: ./gosu tianon bash
./gosu nobody:root bash -c 'whoami && id'
./gosu 1000:1 id
./gosu version: 1.1 (go1.3.1 on linux/amd64; gc)
一旦处理了用户/组,我们将切换到该用户,然后我们exec
指定的过程,而gosu
本身不再居住或根本涉及生命周期。这避免了信号传递和TTY的所有问题,并将它们逐步调用了gosu
的过程以及它们所属的gosu
所援引的过程。
gosu
的核心用例是在容器启动期间(通常是在入口点,通常在ENTRYPOINT
)从根到root
私有的用户。
除此之外的gosu
的使用很可能会遭受CVE-2016-2779等脆弱性(Docker用例自然而然地掩盖了我们);有关这一点的讨论,请参见tianon/gosu#37
。
高级步骤:
gosu-$(dpkg --print-architecture | awk -F- '{ print $NF }')
作为gosu
gosu-$(dpkg --print-architecture | awk -F- '{ print $NF }').asc
为gosu.asc
gpg --batch --keyserver hkps://keys.openpgp.org --recv-keys B42F6819007F00F88E364FD4036A9C25BF357DD4
gpg --batch --verify gosu.asc gosu
chmod +x gosu
有关明确的Dockerfile
指令,请参见INSTALL.md
。
$ docker run -it --rm ubuntu:trusty su -c ' exec ps aux '
USER PID %CPU %MEM VSZ RSS TTY STAT START TIME COMMAND
root 1 0.0 0.0 46636 2688 ? Ss+ 02:22 0:00 su -c exec ps a
root 6 0.0 0.0 15576 2220 ? Rs 02:22 0:00 ps aux
$ docker run -it --rm ubuntu:trusty sudo ps aux
USER PID %CPU %MEM VSZ RSS TTY STAT START TIME COMMAND
root 1 3.0 0.0 46020 3144 ? Ss+ 02:22 0:00 sudo ps aux
root 7 0.0 0.0 15576 2172 ? R+ 02:22 0:00 ps aux
$ docker run -it --rm -v $PWD /gosu-amd64:/usr/local/bin/gosu:ro ubuntu:trusty gosu root ps aux
USER PID %CPU %MEM VSZ RSS TTY STAT START TIME COMMAND
root 1 0.0 0.0 7140 768 ? Rs+ 02:22 0:00 ps aux
此外,由于gosu
正在使用Docker自己的代码来处理这些user:group
,它与Docker自己的--user
标志具有1:1均衡。
如果您对gosu
处理的边缘案例感到好奇,请参见“ Dockerfile.test-alpine
套件”(以及相关的test.sh
。
(请注意, sudo
目标与该项目有不同的目标,并且它不是打算是sudo
替换;例如,请参阅此堆栈溢出答案,以简短说明sudo
为什么要fork
+ exec
而不是仅仅执行exec
。)
chroot
使用--userspec
标志, chroot
可以提供类似的好处/行为:
$ docker run -it --rm ubuntu:trusty chroot --userspec=nobody / ps aux
USER PID %CPU %MEM VSZ RSS TTY STAT START TIME COMMAND
nobody 1 5.0 0.0 7136 756 ? Rs+ 17:04 0:00 ps aux
setpriv
可在新的util-linux
( >= 2.32.1-0.2
,by debian; https://manpages.debian.org/buster/util-linux/setpriv.1.en.html)中提供。
$ docker run -it --rm buildpack-deps:buster-scm setpriv --reuid=nobody --regid=nogroup --init-groups ps faux
USER PID %CPU %MEM VSZ RSS TTY STAT START TIME COMMAND
nobody 1 5.0 0.0 9592 1252 pts/0 RNs+ 23:21 0:00 ps faux
su-exec
在Alpine Linux生态系统中, su-exec
是C中gosu
的最小重写,可制造出较小的二进制文件,并且可在main
Alpine软件包存储库中使用。但是,从0.2版开始,它具有非常严重的解析器错误,该错误已经发行了很多年(哪种错误的行为是错别字导致运行代码出乎意料的根源?)。
我对它们并不非常熟悉,但是我知道的其他一些替代方法包括:
chpst
( runit
的一部分)