跳转到内容
搜索 AlmaLinux 文档

    浏览当前文档目录

    AlmaLinux 9:Quadlet 文件写法与调试

    在 AlmaLinux 9.8 特权容器(宿主内核 5.14.0-687.54.1.el9_8,podman 5.8.2)中实际执行:写 .container 文件、/usr/libexec/podman/quadlet -dryrun -v。日志:plans/content-expansion/evidence/logs/alma-quadlet-services.log。

    容器无 systemd,服务启动与开机自启未验证;本页聚焦「文件怎么写、生成结果对不对」。

    运行方式目录
    root/etc/containers/systemd/
    rootless~/.config/containers/systemd/

    文件名决定 unit 名:web.container → web.service。放错目录不会报错,但 unit 根本不存在——这是最常见的「写了没生效」。

    [Unit]
    Description=web
    After=network-online.target
    [Container]
    Image=docker.io/library/nginx:alpine
    ContainerName=web
    PublishPort=8080:80
    Volume=webdata:/usr/share/nginx/html:Z
    Environment=NGINX_ENTRYPOINT_QUIET_LOGS=1
    [Service]
    Restart=always
    [Install]
    WantedBy=multi-user.target

    四段各管一件事:[Unit] 依赖与描述、[Container] 容器参数、[Service] 重启策略、[Install] 开机自启。

    Terminal window
    sudo /usr/libexec/podman/quadlet -dryrun -v
    [Unit]
    Wants=network-online.target
    After=network-online.target
    Description=web
    SourcePath=/etc/containers/systemd/web.container
    [Service]
    Restart=always
    ExecStop=/usr/bin/podman rm -v -f -i web
    Type=notify
    ExecStart=/usr/bin/podman run --name web --replace --rm --cgroups=split \
    --sdnotify=conmon -d -v webdata:/usr/share/nginx/html:Z \
    --publish 8080:80 --env NGINX_ENTRYPOINT_QUIET_LOGS=1 \
    docker.io/library/nginx:alpine

    看三处就能确认配置对不对:ExecStart 里的 --publish、-v、--env,以及 After=network-online.target 是否保留。

    Terminal window
    sudo systemctl daemon-reload
    sudo systemctl restart web.service
    systemctl status web.service --no-pager

    daemon-reload 触发 Quadlet 重新生成 unit;不 reload 只 restart,用的还是旧 unit。

    • 缺 [Install]:systemctl enable 报找不到 unit;
    • 依赖没写:容器启动比网络快,监听端口时对端还没就绪;
    • rootless 目录写错:放 /etc 对普通用户不生效。

    练习:写文件、看生成、改参数再验证

    Section titled “练习:写文件、看生成、改参数再验证”
    Terminal window
    sudo mkdir -p /etc/containers/systemd
    sudo tee /etc/containers/systemd/lab.container >/dev/null <<'EOF'
    [Unit]
    Description=lab
    [Container]
    Image=docker.io/library/nginx:alpine
    PublishPort=8082:80
    [Install]
    WantedBy=multi-user.target
    EOF
    sudo /usr/libexec/podman/quadlet -dryrun -v | grep -E "ExecStart|PublishPort"

    检查:

    1. ExecStart 里出现 --publish 8082:80
    2. 把端口改成 8083,重跑 dryrun,ExecStart 跟着变
    3. 执行 daemon-reload 后 systemctl list-unit-files | grep lab 能看到生成的 unit

    常见问题

    Quadlet 文件写好了,systemctl 却找不到 unit?

    先确认目录正确(root 是 /etc/containers/systemd/),再执行 systemctl daemon-reload;Quadlet 的 unit 是动态生成的,不 reload 不会出现。

    端口、卷、环境变量分别对应哪个字段?

    PublishPort 对应 --publish,Volume 对应 -v,Environment 对应 --env;用 quadlet -dryrun -v 看 ExecStart 就能逐项核对。

    容器启动比网络早导致失败怎么办?

    在 [Unit] 里加 After=network-online.target 与 Wants=network-online.target,让 systemd 等网络就绪后再启动容器。