web-dev-qa-db-ja.com

Dockerコンテナーのコンテキスト内でのユーザー切り替え

自作のDockerコンテナでは、特定のUIDとGIDでアプリケーションを実行する必要があります。ホストに存在しないUID:GIDペアを使用しようとすると失敗します。


備考

  • 意図したUID:GIDは必ずしもDocker Host /名前空間に存在するわけではありません
  • カーネルとdockerdはユーザー名前空間を有効にして実行されます
  • UID:GIDは、26551:1000などの厳しい外部要件によって決定されます。
  • コンテナー内のターゲットUID:GIDは、ホスト上のUID:GIDに依存するべきではありません
  • 私のビルドユーザー、つまり自分の「デスクトップユーザー」はUID:GID = 1000:1000を持っています
  • ユーザーの名前空間の場合、subuidおよびsubgidは10000:14095以内です。

最小限のデモの例:セットアップと準備

Dockerfile:ユーザー作成

したがって、私はコンテナーのDockerfile(新しいビルドステージをより簡単にトリガーするためのARG + ENV)でユーザーを作成し始めました-ここでは、$ {HOME}ディレクトリの作成を含む26551:1000として

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}  

docker build

ビルド中に機密情報を挿入する必要があるため、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をマップします。

私はすでに代替案として gos を試しましたが、動作は同じです。つまり、ユーザーはコンテナ/ホストに「存在」していません。

[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 --user

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:GIDをホストで使用可能ないくつかのsubuid:subgidにマッピングすることによって、ホストに存在しないUIDの下でコンテナー内のプロセスをどのように実行できますか?


補遺#1

  • SELinuxが無効になっています
  • この問題は、コンテナ内で実際に使用できるユーザー:グループに関連しているようです

コンテナービルドで定義/作成されたユーザー/グループの1つに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
3
THX

私の問題への回答

ユーザー名前空間に十分な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
1
THX