Linux

Docker 容器上下文中的使用者切換

  • August 22, 2019

在自建的 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

引用自:https://unix.stackexchange.com/questions/535888