LabHub
学习 学习路径 课程

Rootless Podman 运维

rootless 容器的运维

在 LabHub 中继续学习

目标

以 rootless 模式运行容器,亲自确认卷、用户映射和端口限制,并编写 Quadlet 单元文件

为什么重要

从 docker 迁移到 podman 时,一定会遇到一些固定问题。restart: always 并不表示开机自动启动(因为没有守护进程),无法绑定 1024 以下的端口,卷中文件的所有者会显示为陌生的 UID,而在 SELinux 环境中,如果没有 :Z 标签,就会出现 Permission denied。提前了解这四点,迁移只需 30 分钟;不了解则要花半天。

而在 podman 中,开机自动启动的正确答案是 Quadlet。放置 .container 文件后,systemd 会读取它并生成服务单元。podman generate systemd 已经过时。

本实验在虚拟机中运行

rootless podman 会真正运行。 在 Pod 中,newuidmap 需要 CAP_SETUID 才能分配 subuid 范围,因此本实验过去是不完整的——容器无法真正启动,评分也只能检查文件。

在 VM 中可以直接使用 podman run,第 7 步的 Quadlet 也会真正转换为服务并启动。你可以使用 systemctl --user status labhub-web 亲自确认。首次启动需要一分多钟。

步骤

  1. 创建 /root/podrun 目录,以 podster 权限加载 /opt/images/labhub-alpine.tar,然后将镜像列表保存为 /root/podrun/images.txt
  2. 使用该镜像运行一次容器并执行 echo labhub-ok,将输出保存为 /root/podrun/run.txt
  3. /home/podster/data 挂载到容器的 /data,在容器内创建 /data/hello.txt,然后从主机确认该文件可见,并将文件路径和内容保存到 /root/podrun/volume.txt
  4. 将第 3 步所建文件的主机端所有者 UID作为一行数字写入 /root/podrun/owner.txt
  5. 尝试发布特权端口并使其失败,将错误消息保存为 /root/podrun/port-fail.txt。然后改用 8090 端口重试,并将成功结果保存为 /root/podrun/port-ok.txt
  6. labhub-web 为名称在后台运行容器,并将 podman ps 的输出保存为 /root/podrun/ps.txt。列表中必须显示该名称。
  7. 编写 /home/podster/.config/containers/systemd/labhub-web.container。必须包含 [Unit][Container][Install] 三个节;[Container] 中必须有 ImagePublishPortVolume 三个键,[Install] 中必须有 WantedBy
  8. /root/podrun/diff.txt 创建为以下 6 行。 DAEMON=none / STORAGE=<podster 의 graphRoot 절대 경로> / PRIVPORT=denied / RESTART=quadlet / GPUFLAG=--device / SELINUX_LABEL=:Z

参考

加载镜像

创建 /root/podrun 目录,以 podster 权限加载 /opt/images/labhub-alpine.tar,然后将镜像列表保存为 /root/podrun/images.txt

由于没有互联网,请使用预先准备的归档。加载后在列表中确认。

运行容器

使用该镜像运行一次容器并执行 echo labhub-ok,将输出保存为 /root/podrun/run.txt

一次性运行时,请添加退出后清理容器的选项。将输出保存到文件中。

挂载卷

/home/podster/data 挂载到容器的 /data,在容器内创建 /data/hello.txt,然后从主机确认该文件可见,并将文件路径和内容保存到 /root/podrun/volume.txt

用冒号连接主机路径和容器路径。还应添加标签选项,以兼容 SELinux 环境。

确认用户映射

将第 3 步所建文件的主机端所有者 UID作为一行数字写入 /root/podrun/owner.txt

从主机查看卷中创建的文件时,其所有者会显示为映射后的 UID。使用 keep-id 选项时,结果会不同。

重现特权端口失败

尝试发布特权端口并使其失败,将错误消息保存为 /root/podrun/port-fail.txt。然后改用 8090 端口重试,并将成功结果保存为 /root/podrun/port-ok.txt

尝试发布 1024 以下的端口会失败。原样保存该错误消息,然后改用较高端口重试。

确认正在运行的容器

labhub-web 为名称在后台运行容器,并将 podman ps 的输出保存为 /root/podrun/ps.txt。列表中必须显示该名称。

指定名称后启动,管理起来更容易。有一个选项可指定输出格式。

编写 Quadlet 单元

编写 /home/podster/.config/containers/systemd/labhub-web.container。必须包含 [Unit][Container][Install] 三个节;[Container] 中必须有 ImagePublishPortVolume 三个键,[Install] 中必须有 WantedBy

这是扩展名为 .container 的文件。[Container] 节中必须包含 Image,也需要 [Install] 节。

总结与 docker 的差异

/root/podrun/diff.txt 创建为以下 6 行。 DAEMON=none / STORAGE=<podster 의 graphRoot 절대 경로> / PRIVPORT=denied / RESTART=quadlet / GPUFLAG=--device / SELINUX_LABEL=:Z

各项值必须是你在前面的步骤中实际确认过的值。存储路径请填写绝对路径。