Docker 容器上下文中的使用者切換
在自建的 Docker 容器中,我希望/需要在特定的 UID 和 GID 下執行應用程序。嘗試使用主機上不存在的 UID:GID 對失敗。
評論
- 預期的 UID:GID(s) 不一定存在於 Docker 主機/命名空間中
- 核心和 dockerd 在啟用使用者命名空間的情況下執行
- UID:GID 由硬外部要求決定,例如 26551:1000
- 容器中的目標 UID:GID 不應依賴於主機上的 UID:GID
- 我的建構使用者,即我自己的“桌面使用者”,具有 UID:GID = 1000:1000
- 對於使用者命名空間 subuid 和 subgid 在 10000:14095 內
最小展示範例:設置和準備
Dockerfile:使用者創建
因此,我開始在容器的 Dockerfile 中創建一個使用者(ARG+ENV 以便於觸發新的建構階段)——這裡是 26551:1000,包括創建一個 ${HOME} 目錄
ARG USERID=26551 ENV runUID=${USERID} ARG GROUPID=1000 ENV runGID=${GROUPID} ARG USERNAME='testuser' ENV runUSER=${USERNAME} ARG groupNAME='testgroup' ENV runGROUP=${groupNAME} RUN groupadd -g ${runGID} ${runGROUP} && \ useradd -u ${runUID} -g ${runGID} -ms /bin/bash ${runUSER}
碼頭工人建造
由於我需要在建構期間注入敏感資訊,因此我正在使用 BuildKit
> DOCKER_BUILDKIT=1 docker build --secret id=foo_file,src=secret/foo.file --progress=plain . -t testfoo:latest
容器上下文
作為互動式容器在圖像中導航,${HOME} 目錄屬於我的“主機使用者”的 subuid:subgid 範圍中的 UID:GID
[root@e436d2050f67 /]# grep testuser /etc/passwd testuser:x:26551:26551::/home/testuser:/bin/bash [root@e436d2050f67 /]# ls -all /home total 0 drwxr-xr-x. 1 root root 16 Aug 16 13:40 . drwxr-xr-x. 1 root root 248 Aug 16 13:51 .. drwx------. 1 12455 12455 64 Aug 16 13:40 testuser
這可能是公平的,因為我真的不需要 ${HOME} (儘管我想知道這將如何在具有不同 subuid/subgid 範圍的其他主機上工作?)
問題
切換使用者不起作用
問題是,儘管使用者存在於容器的密碼等中,但我無法切換到它;既不通過 chroot 也不通過 su(do):
[root@e436d2050f67 /]# chroot --userspec=1000:26551 / id chroot: failed to set group-ID: Invalid argument
但是,切換到我的“主機使用者”有效
[root@e436d2050f67 /]# chroot --userspec=1000:1000 / id uid=1000 gid=1000 groups=1000
雖然我沒有在容器中定義使用者,但只有 dockerd 會映射 UID:GID。
我已經嘗試過gosu作為替代方案,但行為是相同的,即使用者在容器/主機中不“存在”。
[root@e436d2050f67 /]# gosu 26551:26551 id error: failed switching to "26551:26551": invalid argument [root@e436d2050f67 /]# gosu 1000:1000 id uid=1000 gid=1000 groups=1000
碼頭工人–使用者
在給定使用者下執行容器失敗,因為主機上不存在 UID
> docker run --user=26551 -it testfoo:latest /bin/bash docker: Error response from daemon: OCI runtime create failed: container_linux.go:345: starting container process caused "setup user: cannot set uid to unmapped user in user namespace": unknown.
問題
如何在主機上不存在的 UID 下的容器中執行程序,也許通過將容器 UID:GID 映射到主機上可用的某個 subuid:subgid ?
附錄#1
- SELinux 被禁用
- 該問題似乎與容器中實際可用的使用者:組有關
雖然我無法使用 su 或 gosu 切換到容器建構中定義/創建的使用者/組之一,但我可以切換到容器中的主機使用者的 UID:GID
[root@5e5137b95434 /]# gosu nobody id uid=99(nobody) gid=99(nobody) groups=99(nobody) [root@5e5137b95434 /]# su --group=99 testuser id su: group 99 does not exist [root@5e5137b95434 /]# su nobody id This account is currently not available. [root@5e5137b95434 /]# su --group=120000 testuser id su: group 120000 does not exist [root@5e5137b95434 /]# gosu 26551:26551 id error: failed switching to "26551:26551": invalid argument [root@5e5137b95434 /]# cat /etc/group root:x:0: bin:x:1: daemon:x:2: sys:x:3: adm:x:4: tty:x:5: disk:x:6: lp:x:7: mem:x:8: kmem:x:9: wheel:x:10: cdrom:x:11: mail:x:12: man:x:15: dialout:x:18: floppy:x:19: games:x:20: tape:x:33: video:x:39: ftp:x:50: lock:x:54: audio:x:63: nobody:x:99: users:x:100: utmp:x:22: utempter:x:35: input:x:999: systemd-journal:x:190: systemd-network:x:192: dbus:x:81: testgroup:x:26551:
切換到主機使用者,該使用者未在容器中明確定義
[root@5e5137b95434 /]# gosu 1000:1000 id uid=1000 gid=1000 groups=1000 [root@5e5137b95434 /]# gosu 1000:1000 whomai error: exec: "whomai": executable file not found in $PATH [root@5e5137b95434 /]# gosu 1000:1000 echo "testfooout" > /home/testuser/1000_1000 > host > ls -all /tmp/foo/1000_1000 -rw-r--r-- 1 120000 120000 11 Aug 21 10:02 /tmp/foo/1000_1000 > host > id uid=1000(hartlocal) gid=1000(hartlocal) groups=1000(hartlocal),10(wheel),969(docker) [root@5e5137b95434 /]# gosu 1000:1000 sleep 600 > host > cat /proc/5737/cmdline sleep600 > host > ls -all /proc/5737/cmdline -r--r--r-- 1 121000 121000 0 Aug 21 10:04 /proc/5737/cmdline
回答我的問題
我沒有為使用者命名空間定義足夠的 subuids/subgids。
前
/etc/subuid /etc/subgid dockeruser:120000:10000
我在 UID=26551 的容器中創建了一個使用者 - 其中 26551 不在其中
$$ 120000,120000+10000 $$因此切換到該使用者失敗。 使固定
將 subuid 和 subgid 範圍擴展到
$$ 200000,200000+100000 $$並實際包含 UID
/etc/subuid /etc/subgid dockeruser:200000:100000