2. RHEL容器工具链安装与基础配置
RHEL 8/9 的容器能力并不是靠一个孤立的 Docker 守护进程撑起来的,而是由一组职责清晰、可组合的命令行工具构成。理解这套工具链的分工,是后续所有容器操作的基础。本节围绕 Podman、Buildah、Skopeo 三个核心工具展开,同时完成仓库源配置、普通用户运行权限设置,并用 podman info 与 skopeo list 做最终验证。
一、工具链分工:三个工具各管一段
Podman 负责容器的生命周期管理,包括拉取镜像、创建、启动、停止、删除容器,以及生成 systemd 服务单元。Buildah 专注于镜像构建,它可以在不依赖 Dockerfile 守护进程的情况下,从基础镜像开始逐层添加文件、执行命令并提交为镜像,也支持直接构建 Dockerfile。Skopeo 则处理镜像在仓库之间的搬运与检查,例如从远端仓库复制镜像到本地目录、检查远端镜像的标签与摘要、在不同 registry 之间同步镜像。
三者共享同一套底层存储(默认位于 /var/lib/containers/storage 或用户家目录下的 ~/.local/share/containers/storage),因此 Buildah 构建出的镜像可以被 Podman 直接运行,Skopeo 拉取的镜像也能被 Podman 使用。这种共享存储是它们能协同工作的关键。
二、安装三个工具
在 RHEL 8/9 上,这三个工具都包含在 container-tools 模块中。推荐直接安装模块,它会一次性带齐 Podman、Buildah、Skopeo、crun、runc 等组件,并保证版本兼容。
# 查看可用模块流
dnf module list container-tools
# 安装默认模块流(RHEL 8 通常为 4.0,RHEL 9 为 5.0 或更高)
dnf module install -y container-tools
# 验证三个命令是否可用
podman --version
buildah --version
skopeo --version
如果只需要单个工具,也可以分别安装 podman、buildah、skopeo 三个独立包。但模块安装能避免依赖版本错配,在生产环境中更稳妥。安装完成后,podman --version 应输出类似 podman version 4.9.4 的信息,说明命令已就绪。
三、配置容器仓库源
Podman 和 Skopeo 读取的仓库配置位于 /etc/containers/registries.conf,以及 /etc/containers/registries.conf.d/ 目录下的片段文件。RHEL 默认已经预置了 registry.redhat.io 和 quay.io 的条目,但 registry.redhat.io 需要登录认证才能拉取镜像。
登录方式有两种。第一种是交互式登录:
podman login registry.redhat.io
# 输入 Red Hat 账号与密码
第二种是使用 Registry 服务账号令牌,适合自动化场景:
podman login --username <服务账号> --password-stdin registry.redhat.io < token.txt
登录成功后,凭据默认保存在 ${XDG_RUNTIME_DIR}/containers/auth.json(普通用户)或 /run/containers/0/auth.json(root)。可以用 podman login --get-login registry.redhat.io 确认当前登录的账号。对于 quay.io,公共镜像无需登录即可拉取,私有仓库则需要 podman login quay.io。
如果企业内网有镜像加速或代理仓库,可以在 /etc/containers/registries.conf.d/ 下新增一个 .conf 文件,用 [[registry]] 段声明 location、insecure、blocked 等参数。修改后无需重启服务,Podman 每次执行时会重新读取配置。
四、让普通用户也能运行容器
RHEL 默认允许 root 运行容器,但普通用户直接执行 podman run 会失败,原因是缺少 subuid/subgid 映射。用户命名空间需要把容器内的 root 映射到宿主机上的一个普通用户 ID 区间,这个区间由 /etc/subuid 和 /etc/subgid 定义。
检查当前用户是否已有映射:
grep $USER /etc/subuid
grep $USER /etc/subgid
如果没有输出,可以用 usermod 添加。例如给用户 devuser 分配 100000 起始、65536 个 ID:
usermod --add-subuids 100000-165535 --add-subgids 100000-165535 devuser
分配完成后,需要清理该用户旧的容器存储,让 Podman 重新按新映射初始化:
podman system migrate
这一步很关键。如果跳过,旧的存储元数据仍按旧映射记录,新容器可能报 cannot set up namespace 或权限错误。执行 podman system migrate 后,再用普通用户执行 podman run --rm hello-world 或 podman run --rm registry.access.redhat.com/ubi9/ubi echo ok,能正常输出即表示 rootless 模式已生效。
~/.local/share/containers/storage,与 root 的存储完全隔离。因此 root 拉取的镜像,普通用户看不到,需要重新拉取或使用 skopeo copy 搬运。五、验证:podman info 与 skopeo list
安装和配置完成后,用两条命令做最终确认。podman info 输出内容较多,重点关注以下几个字段:
podman info --format '{{.Host.Security.Rootless}}'
podman info --format '{{.Store.GraphRoot}}'
podman info --format '{{.Host.OCIRuntime.Name}}'
第一条应输出 true(普通用户)或 false(root),第二条显示当前存储根目录,第三条显示 OCI 运行时名称(通常为 crun 或 runc)。如果 Rootless 为 true 且 GraphRoot 指向用户家目录,说明 rootless 配置正确。
skopeo list 用于检查远端仓库的标签列表,验证仓库连通性与认证状态:
skopeo list-tags docker://registry.access.redhat.com/ubi9/ubi
skopeo list-tags docker://quay.io/podman/stable
第一条命令会返回 UBI9 基础镜像的所有可用标签,例如 9.4、9.4-xxx、latest 等。第二条返回 quay.io 上 Podman 稳定版的标签。能正常返回 JSON 格式的标签列表,说明仓库源配置、网络连通和认证都没有问题。如果返回 unauthorized,则需要重新执行 podman login;如果返回 connection refused,则检查网络或代理设置。
六、常见问题与判断依据
| 现象 | 可能原因 | 处理方式 |
|---|---|---|
| 普通用户 podman run 报权限错误 | 缺少 subuid/subgid 映射 | usermod 添加映射后执行 podman system migrate |
| podman login registry.redhat.io 失败 | 账号无 Registry 服务权限或密码错误 | 在 Red Hat 客户门户确认服务账号并重新登录 |
| skopeo list-tags 返回 unauthorized | 未登录或凭据过期 | 重新 podman login 对应仓库 |
| podman info 中 Rootless 为 false | 以 root 身份执行,或用户命名空间未启用 | 切换到普通用户执行,检查 /etc/subuid 配置 |