基于Debian/Ubuntu的镜像运行嵌套rootless Podman需--privileged的原因及修复
嵌套Rootless Podman镜像构建问题
我尝试基于docker.io/python:3.10-slim-bullseye或docker.io/ubuntu:22.04构建一个能在Rootless Podman中运行Rootless Podman的镜像,目标是实现类似quay.io/podman/stable:latest的功能,但我的镜像必须添加--privileged参数才能正常运行,而官方基于Fedora的镜像无需该参数。
官方镜像运行示例
官方镜像可直接通过以下命令正常执行:
$ podman run --rm \ --security-opt label=disable \ --device /dev/fuse \ --user podman \ quay.io/podman/stable:latest podman info
该命令能正常输出podman info,容器内运行podman run hello-world也符合预期。
自制镜像问题
我编写的Debian/Ubuntu镜像(命名为podinpodtest)执行相同命令时失败:
$ podman run --rm \ --security-opt label=disable \ --device /dev/fuse \ --user podman \ podinpodtest podman info
报错信息:
Error: cannot setup namespace using newuidmap: exit status 1
添加--privileged参数后则可正常工作:
$ podman run --rm \ --security-opt label=disable \ --device /dev/fuse \ --user podman \ --privileged \ podinpodtest podman info
问题
- 为何基于Debian/Ubuntu的镜像运行嵌套Rootless Podman需要
--privileged参数? - 能否修改该镜像使其无需
--privileged参数即可像官方镜像一样正常工作?
问题解答
1. 为什么需要--privileged?
核心差异在于Debian/Ubuntu发行版的默认配置限制:
- Fedora默认允许非特权用户创建用户命名空间,而Debian/Ubuntu默认禁用了该能力,同时对uid/gid映射范围做了严格限制。
- 报错
cannot setup namespace using newuidmap正是因为容器内的podman用户无法创建所需的用户命名空间,--privileged参数会放开所有系统权限,包括用户命名空间的创建权限,因此能绕过这个限制。 - 此外,Debian/Ubuntu的
podman包默认配置没有针对容器内运行场景做优化,缺少必要的权限配置和系统参数设置。
2. 修改镜像实现无--privileged运行
通过调整Dockerfile的关键配置,可让镜像无需--privileged参数即可运行:
修改后的Dockerfile
#FROM docker.io/python:3.10-slim-bullseye FROM docker.io/ubuntu:22.04 RUN apt-get update && apt-get install -y \ containers-storage \ fuse-overlayfs \ podman \ uidmap \ && rm -rf /var/lib/apt/lists/* # 创建podman用户并配置标准uid/gid映射范围 RUN useradd -m podman; \ echo "podman:100000:65536" > /etc/subuid; \ echo "podman:100000:65536" > /etc/subgid; # 添加官方容器配置文件 ARG _REPO_URL="https://raw.githubusercontent.com/containers/podman/main/contrib/podmanimage/stable" ADD $_REPO_URL/containers.conf /etc/containers/containers.conf ADD $_REPO_URL/podman-containers.conf /home/podman/.config/containers/containers.conf # 修复权限并创建必要目录 RUN mkdir -p /home/podman/.local/share/containers /var/lib/shared \ && chown -R podman:podman /home/podman \ && chmod 644 /etc/containers/containers.conf # 修改存储配置以支持fuse-overlayfs RUN sed -e 's|^#mount_program|mount_program|g' \ -e '/additionalimage.*/a "/var/lib/shared",' \ -e 's|^mountopt[[:space:]]*=.*$|mountopt = "nodev,fsync=0"|g' \ /usr/share/containers/storage.conf \ > /etc/containers/storage.conf # 配置共享存储目录 RUN mkdir -p /var/lib/shared/overlay-images \ /var/lib/shared/overlay-layers \ /var/lib/shared/vfs-images \ /var/lib/shared/vfs-layers \ && touch /var/lib/shared/overlay-images/images.lock \ && touch /var/lib/shared/overlay-layers/layers.lock \ && touch /var/lib/shared/vfs-images/images.lock \ && touch /var/lib/shared/vfs-layers/layers.lock # 启用非特权用户命名空间支持 RUN echo "kernel.unprivileged_userns_clone=1" > /etc/sysctl.d/00-unprivileged-userns.conf RUN sysctl --system VOLUME /var/lib/containers VOLUME /home/podman/.local/share/containers ENV _CONTAINERS_USERNS_CONFIGURED=""
关键修改点:
- 安装
uidmap包:确保newuidmap/newgidmap工具可用,这是用户命名空间映射的核心依赖。 - 调整uid/gid映射范围:使用
100000:65536的标准映射区间,避免Debian/Ubuntu默认小范围映射导致的权限冲突。 - 启用非特权用户命名空间:通过
sysctl设置kernel.unprivileged_userns_clone=1,解除Debian/Ubuntu默认的用户命名空间创建限制。 - 移除冗余依赖:
libvshadow-utils并非Rootless Podman运行的必需包,可删除以精简镜像。
验证运行命令
修改后构建镜像,使用原命令即可正常运行:
$ podman run --rm \ --security-opt label=disable \ --device /dev/fuse \ --user podman \ podinpodtest podman info
内容的提问来源于stack exchange,提问作者19090gvaohda0
相关产品推荐
相关产品推荐

