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 根本不存在——这是最常见的「写了没生效」。
一个完整的 .container
Section titled “一个完整的 .container”[Unit]Description=webAfter=network-online.target
[Container]Image=docker.io/library/nginx:alpineContainerName=webPublishPort=8080:80Volume=webdata:/usr/share/nginx/html:ZEnvironment=NGINX_ENTRYPOINT_QUIET_LOGS=1
[Service]Restart=always
[Install]WantedBy=multi-user.target四段各管一件事:[Unit] 依赖与描述、[Container] 容器参数、[Service] 重启策略、[Install] 开机自启。
用 dryrun 验证翻译
Section titled “用 dryrun 验证翻译”sudo /usr/libexec/podman/quadlet -dryrun -v[Unit]Wants=network-online.targetAfter=network-online.targetDescription=webSourcePath=/etc/containers/systemd/web.container
[Service]Restart=alwaysExecStop=/usr/bin/podman rm -v -f -i webType=notifyExecStart=/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 是否保留。
改动如何生效
Section titled “改动如何生效”sudo systemctl daemon-reloadsudo systemctl restart web.servicesystemctl status web.service --no-pagerdaemon-reload 触发 Quadlet 重新生成 unit;不 reload 只 restart,用的还是旧 unit。
- 缺
[Install]:systemctl enable报找不到 unit; - 依赖没写:容器启动比网络快,监听端口时对端还没就绪;
- rootless 目录写错:放
/etc对普通用户不生效。
练习:写文件、看生成、改参数再验证
Section titled “练习:写文件、看生成、改参数再验证”sudo mkdir -p /etc/containers/systemdsudo tee /etc/containers/systemd/lab.container >/dev/null <<'EOF'[Unit]Description=lab[Container]Image=docker.io/library/nginx:alpinePublishPort=8082:80[Install]WantedBy=multi-user.targetEOFsudo /usr/libexec/podman/quadlet -dryrun -v | grep -E "ExecStart|PublishPort"检查:
ExecStart里出现--publish 8082:80- 把端口改成 8083,重跑 dryrun,
ExecStart跟着变 - 执行
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 等网络就绪后再启动容器。
- 容器与镜像:容器与镜像
- 防火墙放行:firewalld 放行端口
- 安装后核对:新装系统 7 项核对