這是一個簡單的工具,其簡單的事實是, 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
的一部分)