2022年11月4日更新
Podman 4.3.0 引入了选项 uid 和 gid,可以应用于 --userns keep-id
。
此答案中描述的 UID 和 GID 映射现在可以改为使用 --userns keep-id:uid=$uid,gid=$gid
。唯一的区别是新语法更加简洁,省去了一些打字。
请参考以下故障排除提示:
Podman 运行失败,显示错误消息 "Error: unrecognized namespace mode keep-id:uid=1000,gid=1000 passed"
是的,你可以使用命令行选项--uidmap来重新映射 UID。
看起来你正在使用的容器 UID 是
102002-100000+1=2003
数字1存在的原因是在容器中,默认情况下,主机上的普通UID被映射到容器中的root帐户。
该示例演示了此类计算(1002002-100000+1=2003)。
$ id -un
testuser
$ grep testuser /etc/subuid
testuser:100000:65536
$ grep testuser /etc/subgid
testuser:100000:65536
$ mkdir dir1
$ chmod 777 dir1
$ podman run --rm -v ./dir1:/dir1:Z \
--user 2003:2003 \
docker.io/library/ubuntu touch /dir1/a
$ ls -l dir1/a
-rw-r--r--. 1 102002 102002 0 Jan 19 19:35 dir1/a
$
让我们定义一些变量,以便这个 Stackoverflow 的答案能够更具可重用性。
uid=2003
subuidStart=100000
subuidSize=65536
你可以尝试同时使用以下三个选项来运行
podman
:
--uidmap $uid:0:1
--uidmap 0:1:$uid
--uidmap $(($uid+1)):$(($uid+1)):$(($subuidSize-$uid))
请注意$(( expression ))
是Bash语法,因此您需要使用Bash shell。
--uidmap $uid:0:1
将容器中的UID $uid 映射到主机上的普通UID。
主机UID |
中间UID |
容器UID |
普通主机UID |
0 |
$uid |
--uidmap 0:1:$uid
将容器内UID在0至$uid-1之间的UID映射到子UID的较低部分(从$subuidStart到$subuidStart+$uid-1)。
主机UID |
中间UID |
容器UID |
$subuidStart |
1 |
0 |
$subuidStart + 1 |
2 |
1 |
... |
... |
... |
$subuidStart+$uid-1 |
$uid |
$uid-1 |
--uidmap $(($uid+1)):$(($uid+1)):$(($subuidSize-$uid))
将容器内UID在$uid+1至$subuidSize之间的UID映射到其余子UID。
主机UID |
中间UID |
容器UID |
$subuidStart + $uid |
$uid + 1 |
$uid + 1 |
$subuidStart + $uid + 1 |
$uid + 2 |
$uid + 2 |
... |
... |
... |
$subuidStart + $subuidSize - 1 |
$subuidSize |
$subuidSize |
请注意,主机UID和中间UID之间的映射不能由用户修改。普通主机UID始终映射到中间UID 0。
请注意,一般情况下可能存在多个子UID范围。
有一个类似的命令行选项--gidmap用于GID。
更新于2022-02-14
我在Podman文档中写了一个故障排除提示。
uidmap
软件包进行了修复。 - Pablo Bianchi