为什么Podman在使用不同UID时会报告“命名空间中没有足够的ID可用”?

13

事实:

  1. 无根Podman对uid 1480完美运行
  2. 无根Podman对uid 2088失败
  3. CentOS 7
  4. 内核版本为3.10.0-1062.1.2.el7.x86_64
  5. podman版本为1.4.4
  6. 两者之间几乎删除了整个环境
  7. /tmp的文件系统为xfs
  8. 但是,两个用户的capsh输出除了uid/用户名之外都是相同的
  9. 两个UID在/etc/sub{u,g}id文件中都有相同的条目
  10. $HOME/.config/containers/storage.conf是默认的,并且除了UID之外与两个相同。下面是参考的storage.conf

我编写了以下shell脚本,以演示两者操作的环境有多相似:

#!/bin/sh
for i in 1480 2088; do
  sudo chroot --userspec "$i":10 / env -i /bin/sh <<EOF
echo -------------- $i ----------------
/usr/sbin/capsh --print
grep "$i" /etc/subuid /etc/subgid
mkdir /tmp/"$i"
HOME=/tmp/"$i"
export HOME
podman --root=/tmp/"$i" info > /tmp/podman."$i"
podman run --rm --root=/tmp/"$i" docker.io/library/busybox printf "\tCOMPLETE\n"
echo -----------END $i END-------------
EOF
  sudo rm -rf /tmp/"$i"
done

这是脚本的输出结果:
$ sh /tmp/podman-fail.sh
[sudo] password for functional:
-------------- 1480 ----------------
Current: =
Bounding set =cap_chown,cap_dac_override,cap_dac_read_search,cap_fowner,cap_fsetid,cap_kill,cap_setgid,cap_setuid,cap_setpcap,cap_linux_immutable,cap_net_bind_service,cap_net_broadcast,cap_net_admin,cap_net_raw,cap_ipc_lock,cap_ipc_owner,cap_sys_module,cap_sys_rawio,cap_sys_chroot,cap_sys_ptrace,cap_sys_pacct,cap_sys_admin,cap_sys_boot,cap_sys_nice,cap_sys_resource,cap_sys_time,cap_sys_tty_config,cap_mknod,cap_lease,cap_audit_write,cap_audit_control,cap_setfcap,cap_mac_override,cap_mac_admin,cap_syslog,35,36
Securebits: 00/0x0/1'b0
 secure-noroot: no (unlocked)
 secure-no-suid-fixup: no (unlocked)
 secure-keep-caps: no (unlocked)
uid=1480(functional)
gid=10(wheel)
groups=0(root)
/etc/subuid:1480:100000:65536
/etc/subgid:1480:100000:65536
Trying to pull docker.io/library/busybox...Getting image source signatures
Copying blob 7c9d20b9b6cd done
Copying config 19485c79a9 done
Writing manifest to image destination
Storing signatures
ERRO[0003] could not find slirp4netns, the network namespace won't be configured: exec: "slirp4netns": executable file not found in $PATH
        COMPLETE
-----------END 1480 END-------------
-------------- 2088 ----------------
Current: =
Bounding set =cap_chown,cap_dac_override,cap_dac_read_search,cap_fowner,cap_fsetid,cap_kill,cap_setgid,cap_setuid,cap_setpcap,cap_linux_immutable,cap_net_bind_service,cap_net_broadcast,cap_net_admin,cap_net_raw,cap_ipc_lock,cap_ipc_owner,cap_sys_module,cap_sys_rawio,cap_sys_chroot,cap_sys_ptrace,cap_sys_pacct,cap_sys_admin,cap_sys_boot,cap_sys_nice,cap_sys_resource,cap_sys_time,cap_sys_tty_config,cap_mknod,cap_lease,cap_audit_write,cap_audit_control,cap_setfcap,cap_mac_override,cap_mac_admin,cap_syslog,35,36
Securebits: 00/0x0/1'b0
 secure-noroot: no (unlocked)
 secure-no-suid-fixup: no (unlocked)
 secure-keep-caps: no (unlocked)
uid=2088(broken)
gid=10(wheel)
groups=0(root)
/etc/subuid:2088:100000:65536
/etc/subgid:2088:100000:65536
Trying to pull docker.io/library/busybox...Getting image source signatures
Copying blob 7c9d20b9b6cd done
Copying config 19485c79a9 done
Writing manifest to image destination
Storing signatures
ERRO[0003] Error while applying layer: ApplyLayer exit status 1 stdout:  stderr: there might not be enough IDs available in the namespace (requested 65534:65534 for /home): lchown /home: invalid argument
ERRO[0003] Error pulling image ref //busybox:latest: Error committing the finished image: error adding layer with blob "sha256:7c9d20b9b6cda1c58bc4f9d6c401386786f584437abbe87e58910f8a9a15386b": ApplyLayer exit status 1 stdout:  stderr: there might not be enough IDs available in the namespace (requested 65534:65534 for /home): lchown /home: invalid argument
Failed
Error: unable to pull docker.io/library/busybox: unable to pull image: Error committing the finished image: error adding layer with blob "sha256:7c9d20b9b6cda1c58bc4f9d6c401386786f584437abbe87e58910f8a9a15386b": ApplyLayer exit status 1 stdout:  stderr: there might not be enough IDs available in the namespace (requested 65534:65534 for /home): lchown /home: invalid argument

这是 1480 用户的 storage.conf,与之前相同只是将 1480 替换为 2088
[storage]
  driver = "vfs"
  runroot = "/run/user/1480"
  graphroot = "/tmp/1480/.local/share/containers/storage"
  [storage.options]
    size = ""
    remap-uids = ""
    remap-gids = ""
    remap-user = ""
    remap-group = ""
    ostree_repo = ""
    skip_mount_home = ""
    mount_program = ""
    mountopt = ""
    [storage.options.thinpool]
      autoextend_percent = ""
      autoextend_threshold = ""
      basesize = ""
      blocksize = ""
      directlvm_device = ""
      directlvm_device_force = ""
      fs = ""
      log_level = ""
      min_free_space = ""
      mkfsarg = ""
      mountopt = ""
      use_deferred_deletion = ""
      use_deferred_removal = ""
      xfs_nospace_max_retries = ""

您可以看到,对于用户来说,两个podman info输出基本上没有区别:
$ diff -u /tmp/podman.1480 /tmp/podman.2088
--- /tmp/podman.1480    2019-10-17 22:41:21.991573733 -0400
+++ /tmp/podman.2088    2019-10-17 22:41:26.182584536 -0400
@@ -7,7 +7,7 @@
   Distribution:
     distribution: '"centos"'
     version: "7"
-  MemFree: 45654056960
+  MemFree: 45652697088
   MemTotal: 67306323968
   OCIRuntime:
     package: containerd.io-1.2.6-3.3.el7.x86_64
@@ -24,7 +24,7 @@
   kernel: 3.10.0-1062.1.2.el7.x86_64
   os: linux
   rootless: true
-  uptime: 30h 17m 50.23s (Approximately 1.25 days)
+  uptime: 30h 17m 54.42s (Approximately 1.25 days)
 registries:
   blocked: null
   insecure: null
@@ -35,14 +35,14 @@
   - quay.io
   - registry.centos.org
 store:
-  ConfigFile: /tmp/1480/.config/containers/storage.conf
+  ConfigFile: /tmp/2088/.config/containers/storage.conf
   ContainerStore:
     number: 0
   GraphDriverName: vfs
   GraphOptions: null
-  GraphRoot: /tmp/1480
+  GraphRoot: /tmp/2088
   GraphStatus: {}
   ImageStore:
     number: 0
-  RunRoot: /run/user/1480
-  VolumePath: /tmp/1480/volumes
+  RunRoot: /run/user/2088
+  VolumePath: /tmp/2088/volumes

我不相信在podman的源代码中会有像if (2088 == uid) { abort(); }或类似的无聊内容。我错了吗?

3个回答

17

在CentOS 8.1上对我有效。 - bvanlew
在 Fedora 34 中工作过。 - garlicFrancium
在Ubuntu 18.04上工作过。 - nashter
尽管我没有正在运行需要迁移的容器,但是在更新了/etc/subuid和/etc/subgid之后,这个命令解决了错误。 - Amr

4
据我所知,在用户之间,子UID和GID范围不应该重叠。参考一下 useradd 的手册,这就是它对于这个问题的解释。
   SUB_GID_MIN (number), SUB_GID_MAX (number), SUB_GID_COUNT
   (number)
       If /etc/subuid exists, the commands useradd and newusers
       (unless the user already have subordinate group IDs)
       allocate SUB_GID_COUNT unused group IDs from the range
       SUB_GID_MIN to SUB_GID_MAX for each new user.

       The default values for SUB_GID_MIN, SUB_GID_MAX,
       SUB_GID_COUNT are respectively 100000, 600100000 and 65536.

   SUB_UID_MIN (number), SUB_UID_MAX (number), SUB_UID_COUNT
   (number)
       If /etc/subuid exists, the commands useradd and newusers
       (unless the user already have subordinate user IDs) allocate
       SUB_UID_COUNT unused user IDs from the range SUB_UID_MIN to
       SUB_UID_MAX for each new user.

       The default values for SUB_UID_MIN, SUB_UID_MAX,
       SUB_UID_COUNT are respectively 100000, 600100000 and 65536.

关键词为“未使用”。

1
请始终先查阅man手册,然后再去StackOverflow寻找答案,感谢您记得我。这篇Red Hat博客文章在同一语境下提供了一些启示:https://www.redhat.com/sysadmin/rootless-podman - Stephan Kristyn

-1

2
似乎OP已经成功地运行了无根Podman(并且并没有询问Buildah)? - larsks

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接