跳转到内容
搜索 RunEntLinux 文档

仅搜索 RunEntLinux 通用文档,各发行版文档使用各自的搜索入口。

    浏览当前文档目录

    Podman Quadlet 入门

    适用于 Podman 4.4+(EL 9.2 起随 container-tools 提供,EL 9.4+/10 均已包含;用 podman --version 确认,4.4 以下没有 Quadlet)

    要让容器在开机时自动启动、崩溃后自动重启,过去你得用 podman generate systemd 生成一份服务单元。这个方式已经被官方弃用。从 Podman 4.4 起,Podman 内置了 Quadlet:你只写一份声明式的 .container 文件,systemd 在启动时自动把它转换成服务单元来管理。配置更清晰,改起来也更简单。

    • Quadlet 是什么,以及它为什么取代 podman generate systemd
    • 把单元文件放在哪里(root 与 rootless 的区别)
    • 写一个 nginx.container 文件并用 systemd 启动它
    • 配置 rootless 自动启动与自动更新
    • 其它单元类型(.volume、.network、.pod 等)的用途
    • 一台运行 EL 9.4+ 或 EL 10 的系统
    • 已安装 Podman 4.4 及以上(EL 9.4+/EL 10 默认自带)
    • 普通用户的 sudo 权限

    Quadlet 是 Podman 4.4 起内置的一个 systemd 生成器。你把一份描述容器的 .container 文件交给 systemd,systemd 在 daemon-reload 时调用 Quadlet,自动生成对应的 .service 单元。

    它的优势在于声明式:你只描述”想要什么”,而不是像 podman generate systemd 那样生成一份”当前状态的快照”。容器参数变化后,旧方式需要重新生成单元文件,而 Quadlet 只需编辑文件再 daemon-reload。

    Quadlet 会扫描固定的目录。放对位置是它能工作的前提:

    场景目录
    系统级(root)/etc/containers/systemd/(或发行版自带的 /usr/share/containers/systemd/)
    用户级(rootless)~/.config/containers/systemd/

    下面用一个 Nginx 容器演示完整流程。先创建单元文件:

    nginx.container
    [Unit]
    Description=Nginx web server
    [Container]
    Image=docker.io/library/nginx:latest
    PublishPort=8080:80
    Volume=/srv/nginx/html:/usr/share/nginx/html:Z
    Environment=TZ=Asia/Shanghai
    AutoUpdate=registry
    [Service]
    Restart=always
    [Install]
    WantedBy=default.target

    几个关键点:

    • Image= 写镜像全路径(docker.io/library/...),避免 short-name 触发交互式仓库选择。
    • PublishPort= 等同于 podman run -p,这里把宿主 8080 映射到容器 80。
    • Volume= 的 :Z 后缀在 SELinux 系统上自动打上正确标签(私有标签),等同于 podman run -v ...:Z。
    • AutoUpdate=registry 启用镜像自动更新(见下文)。
    • 服务名 = 文件名去掉扩展名:nginx.container → nginx.service。

    接着按 root 或 rootless 分别启动。

    把文件放进 /etc/containers/systemd/,然后:

    1. 重新加载,让 systemd 生成对应的 nginx.service:

      重新加载单元
      $ sudo systemctl daemon-reload
    2. 启动服务(注意服务名是 nginx,不是 nginx.container):

      启动并查看状态
      $ sudo systemctl start nginx
      $ sudo systemctl status nginx

    在 [Container] 里写 AutoUpdate=registry 后,再启用对应的定时器,Podman 会定期检查上游镜像是否更新并自动滚动:

    启用自动更新定时器
    $ sudo systemctl enable --now podman-auto-update.timer
    手动触发一次(可选)
    $ podman auto-update

    Quadlet 不止 .container,常见单元类型还有:

    文件后缀用途
    .container单个容器
    .volume命名卷,可被 .container 的 Volume= 引用
    .network自定义网络,可被 Network= 引用
    .pod一组共享网络命名空间的容器(Pod)
    .kube直接运行 Kubernetes YAML(play kube)
    .image预先拉取镜像,供其它单元依赖

    例如先声明一个卷,再在容器里引用它:

    app-data.volume
    [Volume]
    # 生成名为 systemd-app-data 的卷
    app.container(片段)
    [Container]
    Image=docker.io/library/postgres:16
    Volume=app-data.volume:/var/lib/postgresql/data:Z

    如果你还在用 podman generate systemd 生成的 container-*.service,迁移思路很直接:把 podman run 的参数逐项翻译成 [Container] 段的字段。

    podman run 参数Quadlet 字段
    --name(可选)ContainerName=
    -p 8080:80PublishPort=8080:80
    -v src:dst:ZVolume=src:dst:Z
    -e KEY=valEnvironment=KEY=val
    --restart=always[Service] 段的 Restart=always

    迁移后停用并删除旧的 container-*.service,避免端口/名称冲突。

    改了 .container 文件却没生效? Quadlet 只在 daemon-reload 时重新生成单元。每次编辑后都要 systemctl daemon-reload(rootless 加 --user),再 restart 服务。

    systemctl start nginx.container 报找不到单元? 服务名是文件名去掉扩展名:nginx.container 对应 nginx.service,所以应执行 systemctl start nginx,而不是带 .container。

    rootless 容器一退出登录就停了? 没有启用 linger。执行 sudo loginctl enable-linger $(whoami),用户服务才会在你不在线时继续运行。

    启动时卡住,提示选择镜像仓库? Image= 写了 short-name(如 nginx)触发了交互式选择。在单元文件里写镜像全路径 docker.io/library/nginx:latest。

    卷挂载后容器读不到文件(权限拒绝)? SELinux 拦截了。给 Volume= 加 :Z 后缀,例如 Volume=/srv/data:/data:Z,让 Podman 自动打上正确的 SELinux 标签。