- Make systemd better for Podman with Quadlet
- podman-systemd.unit - systemd units using Podman Quadlet
- Quadlet Failed to enable unit: Unit xyz is transient or generated. #17567
需要部署一个应用容器做长期评估,执行 podman generate systemd ……
创建单元文件,提示:
DEPRECATED command: It is recommended to use Quadlets for running containers and pods under systemd.
Please refer to podman-systemd.unit(5) for details.
Quadlet 是 Podman 4.4 以来新增的帮助用户使用 systemd 管理容器的工具,相相较 podman generate systemd
隐藏了不少复杂细节。
首先需要一个 .container
单元文件描述需要哪个容器执行什么命令。以 rootless 身份使用 Quadlet 时,会在如下目录寻找单元文件(或这类文件的符号链接)。
$XDG_RUNTIME_DIR/containers/systemd/
$XDG_CONFIG_HOME/containers/systemd/
或$HOME/.config/containers/systemd/
/etc/containers/systemd/users/$UID
/etc/containers/systemd/users/
在本例中,笔者使用了一个符号链接:
mkdir -p $HOME/.config/containers/systemd/user/
touch $HOME/ContainerSpace/loki/loki.container
ln -s $HOME/ContainerSpace/loki/loki.container $HOME/.config/containers/systemd/user/
将 Grafana Loki 文档提供的 Docker 运行命令改写为 container 单元文件。
docker run --name loki -d -v $(pwd):/mnt/config -p 3100:3100 grafana/loki:3.0.0 -config.file=/mnt/config/loki-config.yaml
Docker 命令的参数可以按照 podman-systemd.unit - systemd units using Podman Quadlet 中的说明转换成 [Container]
配置。由于 Quadlet 和 Podman 还在快速迭代,如果提示什么参数不受支持,可以检查当前使用的 Podman 版本和网页右下角是否一致。
[Unit]
Description=Podman container-loki.service
Documentation=man:podman-systemd.unit
Wants=network-online.target
After=network-online.target
[Container]
Image=grafana/loki:3.0.0
PublishPort=3189:3100
Mount=type=bind,src=/home/yufan/ContainerSpace/loki/config,dst=/mnt/config,z
Exec=-config.file=/mnt/config/loki-config.yaml
[Install]
WantedBy=default.target
在系统启动或执行 systemctl daemon-reload
时,一个 systemd generator 会将其转换为服务单元,可以通过 systemctl start/status loki.service
启动服务或查看其状态。
> systemctl --user daemon-reload
> systemctl --user status loki.service
○ loki.service - Loki container
Loaded: loaded (/home/yufan/.config/containers/systemd/loki.container; gen>
Active: inactive (dead)
lines 1-3/3 (END)
> systemctl --user start loki.service
也可以使用 Quadlet 的 -dryrun
命令查看实际创建的服务单元:
> /usr/libexec/podman/quadlet -dryrun -user
quadlet-generator[3310]: Error occurred resolving path "/etc/containers/systemd/users": lstat /etc/containers/systemd/users: no such file or directory
quadlet-generator[3310]: Error occurred resolving path "/etc/containers/systemd/users/1002": lstat /etc/containers/systemd/users: no such file or directory
quadlet-generator[3310]: Loading source unit file /home/yufan/.config/containers/systemd/user/loki.container
---loki.service---
[Unit]
Description=Podman container-loki.service
Documentation=man:podman-systemd.unit
Wants=network-online.target
After=network-online.target
SourcePath=/home/yufan/.config/containers/systemd/user/loki.container
RequiresMountsFor=%t/containers
RequiresMountsFor=/home/yufan/ContainerSpace/loki/config
[X-Container]
Image=grafana/loki:3.0.0
PublishPort=3189:3100
Mount=type=bind,src=/home/yufan/ContainerSpace/loki/config,dst=/mnt/config,z
Exec=-config.file=/mnt/config/loki-config.yaml
[Install]
WantedBy=default.target
[Service]
Environment=PODMAN_SYSTEMD_UNIT=%n
KillMode=mixed
ExecStop=/usr/bin/podman rm -v -f -i --cidfile=%t/%N.cid
ExecStopPost=-/usr/bin/podman rm -v -f -i --cidfile=%t/%N.cid
Delegate=yes
Type=notify
NotifyAccess=all
SyslogIdentifier=%N
ExecStart=/usr/bin/podman run --name=systemd-%N --cidfile=%t/%N.cid --replace --rm --cgroups=split --sdnotify=conmon -d --publish 3189:3100 --mount type=bind,source=/home/yufan/ContainerSpace/loki/config,dst=/mnt/config,z grafana/loki:3.0.0 -config.file=/mnt/config/loki-config.yaml
尝试使用 systemctl --user enable --now loki.service
设置自启会收到 Unit is transient or generated
的错误消息,这是因为生成的文件通常没有持久的标识符,无法创建稳定的链接(也就是通常的 Install 方式)。不过由于 container 单元文件中声明了 [install]
配置,生成器会负责链接的动作,从某种角度上看,像是自动启用了 enable
。
Quadlet 还支持其他单元文件,例如:
.kube
要求 Quadlet 基于 Kubernetes 创建管理 pods 和容器的 systemd 服务单元.network
创建可以被.kube
和.container
使用的网络设备.volume
创建可以供.container
使用的卷