最小演示示例:设置和准备

最小演示示例:设置和准备

在自建的Docker容器中,我想要/需要在特定的UID和GID下运行应用程序。尝试使用主机上不存在的 UID:GID 对会失败。


评论

  • 预期的 UID:GID 不一定存在于 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 范围的其他主机上会如何工作?)


问题

切换用户不起作用

问题是,虽然用户存在于容器的 passwd 等中,但我无法切换到它;既不通过 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。

我已经尝试过了戈苏作为替代方案,但行为是相同的,即用户不“存在”在容器/主机中。

[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

Docker--用户

在给定用户下运行容器失败,因为主机上不存在 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

答案1

回答我的问题

我没有为用户命名空间定义足够的 subuid/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

相关内容