podman -unshare - 在修改后的用户命名空间中运行命令
概述
podman unshare 命令用于在新的用户命名空间中启动一个进程(默认情况下为 $SHELL
)。这个用户命名空间配置成使得调用用户的 UID 和主 GID 分别看起来像是 UID 0 和 GID 0。任何在 /etc/subuid
和 /etc/subgid
文件中与该用户和组匹配的范围也会被映射为它们自身,这是通过 newuidmap(1) 和 newgidmap(1) 这两个辅助程序完成的。
podman unshare 在进行无特权操作的故障排查和手动清理与镜像和容器相关的存储和其他数据时非常有用。
它对于使用 podman mount 命令也很有用。如果一个非特权用户想要挂载和操作一个容器,他们需要在 podman unshare 会话中执行此操作。非特权用户执行 podman mount 命令会失败,除非用户正在一个 podman unshare 会话中运行。
unshare 会话定义了两个环境变量:
- CONTAINERS_GRAPHROOT:容器持久化数据的路径。
- CONTAINERS_RUNROOT:容器易失数据的路径。
重要提示:此命令在远程 Podman 客户端中不可用。
选项
--help, -h
打印用法说明
--rootless-netns
加入用于 netavark 网络的无特权网络命名空间。它可用于通过 IP 地址(桥接网络)连接到无特权容器。否则,从主机网络命名空间连接到容器是不可能的。
开发者手册 - podman unshare
一、概述
podman unshare
是 Podman 容器管理工具中的一个命令,它允许用户在修改后的用户命名空间中执行其他命令。通过修改用户命名空间,这个命令可以帮助开发者以 root 用户的身份执行操作,同时保持用户的安全性和隔离性。这在容器故障排除、数据清理和特殊网络配置等场景中非常有用。
二、使用场景
故障排除:当开发者需要深入排查容器内部的问题时,可以使用
podman unshare
进入一个具有更高权限的环境,从而更容易地访问和修改容器相关的文件和设置。数据清理:在某些情况下,开发者可能需要手动清理容器存储或删除不再需要的镜像。使用
podman unshare
可以更容易地访问和操作这些资源。网络配置:通过
--rootless-netns
选项,开发者可以连接到 rootless 容器的网络命名空间,这对于需要进行特殊网络配置或调试的场景非常有用。
三、选项详解
--help, -h
这个选项用于显示 podman unshare
命令的帮助信息,包括可用的选项和简单的用法说明。
--rootless-netns
这个选项允许用户加入 rootless 容器的网络命名空间。这对于需要通过网络 IP 地址连接到容器的场景非常有用,因为在默认情况下,从主机网络命名空间是无法直接连接到 rootless 容器的。
四、注意事项
安全性:尽管
podman unshare
提供了更高的权限,但开发者仍然需要谨慎使用,避免执行可能破坏系统或泄露敏感信息的操作。远程客户端不可用:需要注意的是,
podman unshare
命令在远程 Podman 客户端中是不可用的。它只能在本地机器上直接运行 Podman 的环境中使用。
五、总结
podman unshare
是一个强大的工具,可以帮助开发者在修改后的用户命名空间中执行命令。通过合理使用这个命令,开发者可以更方便地进行容器故障排除、数据清理和网络配置等操作。然而,使用时需要注意安全性问题,并避免在远程客户端环境中使用。
退出码
podman unshare
的退出码提供了关于容器为何运行失败或为何退出的信息。当 podman unshare
命令以非零码退出时,退出码遵循 chroot
标准,如下所示:
125 错误在于 podman
自身
$ podman unshare --foo; echo $?
Error: unknown flag: --foo
125
126 执行 容器内的命令,但 命令 无法被调用
$ podman unshare /etc; echo $?
Error: fork/exec /etc: permission denied
126
127 执行 容器内的命令,但 命令 未找到
$ podman unshare foo; echo $?
Error: fork/exec /usr/bin/bogus: no such file or directory
127
退出码 为 容器内命令 的退出码
$ podman unshare /bin/sh -c 'exit 3'; echo $?
3
podman unshare
podman unshare
命令允许用户在 rootless 模式下执行命令,在一个隔离的用户命名空间中运行这些命令。此命令特别有用,因为它允许用户以 root 权限执行命令,同时确保这些命令在受限的、隔离的环境中运行,这有助于增强安全性。
退出码和错误消息提供了关于命令为何失败或为何容器退出的信息。例如,如果 podman unshare
尝试执行一个不存在的命令,它将返回退出码 127,并显示一个错误消息,表明无法找到该命令。
示例
执行指定命令
在 rootless 用户命名空间中执行 id
命令以查看当前用户的 ID 和组 ID:
$ podman unshare id
uid=0(root) gid=0(root) groups=0(root),65534(nobody)
注意,尽管你是在宿主机上以非 root 用户身份运行 podman unshare
,但在用户命名空间中执行的命令将以 root 用户身份运行。
显示用户命名空间映射
你可以使用 podman unshare
查看 rootless 容器的用户命名空间映射。这有助于了解 UID 和 GID 如何在宿主机和容器之间映射:
$ podman unshare cat /proc/self/uid_map /proc/self/gid_map
0 1000 1
1 10000 65536
0 1000 1
1 10000 65536
这里显示的是 UID 和 GID 的映射关系,用于在容器和宿主机之间转换用户和组的 ID。
显示网络命名空间信息
使用 --rootless-netns
选项,你可以在 rootless 用户的网络命名空间中查看网络状态。例如,使用 ip addr
命令查看容器的 IP 地址:
$ podman unshare --rootless-netns ip addr
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000
link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
inet 127.0.0.1/8 scope host lo
valid_lft forever preferred_lft forever
inet6 ::1/128 scope host
valid_lft forever preferred_lft forever
2: tap0: <BROADCAST,UP,LOWER_UP> mtu 65520 qdisc fq_codel state UNKNOWN group default qlen 1000
link/ether aa:8c:0b:73:98:f6 brd ff:ff:ff:ff:ff:ff
inet 10.0.2.100/24 brd 10.0.2.255 scope global tap0
valid_lft forever preferred_lft forever
inet6 fd00::a88c:bff:fe73:98f6/64 scope global dynamic mngtmpaddr
valid_lft 86389sec preferred_lft 14389sec
inet6 fe80::a88c:bff:fe73:98f6/64 scope link
valid_lft forever preferred_lft forever
在这个示例中,你可以看到回环接口 (lo
) 和一个虚拟网络接口 (tap0
),它们都有各自的 IP 地址和状态信息。
另请参阅
- podman(1): Podman 的主文档,描述了如何使用 Podman 管理容器。
- podman-mount(1): 描述如何使用
podman mount
命令挂载容器的文件系统。 - namespaces(7): Linux 手册页,详细描述了 Linux 命名空间及其如何用于隔离进程。
- newuidmap(1), newgidmap(1): 这两个工具用于在用户命名空间中管理 UID 和 GID 的映射。
- usernamespaces(7): Linux 手册页,详细描述了用户命名空间及其工作原理。