名称

podman-generate-systemd - [已弃用] 为容器或 Pod 生成 systemd 单元文件

简介

podman generate systemd [选项] 容器|Pod

描述

已弃用:注意:podman generate systemd 已弃用。在 systemd 下运行 Podman 容器或 Pod 时,我们建议使用 Quadlet 文件。目前没有移除此命令的计划。它将接收紧急错误修复,但不会有新功能。

podman generate systemd 创建一个 systemd 单元文件,可用于控制容器或 Pod。默认情况下,该命令将单元文件的内容打印到标准输出。

为 Pod 生成单元文件需要 Pod 使用基础设施容器创建(参见 --infra=true)。基础设施容器在 Pod 的整个生命周期内运行,因此 systemd 需要它来管理 Pod 主单元的生命周期。

  • 注意:将此命令与远程客户端(包括 Mac 和 Windows [不包括 WSL2] 机器)一起使用时,请将生成的单元放置在远程系统上。此外,请确保已设置 XDG_RUNTIME_DIR 环境变量。如果未设置,请通过 export XDG_RUNTIME_DIR=/run/user/$(id -u) 设置它。

  • 注意:生成的 podman run 命令包含一个 --sdnotify 选项,其值取自容器。如果容器没有显式设置任何值或值设置为 ignore,则使用值 conmon。覆盖默认值 container 的原因是,几乎没有容器工作负载发送通知消息。如果对不发送通知消息的容器使用值 container,systemd 会等待永远不会到来的就绪消息。用户使用默认值可能是无意的,因此覆盖了默认值。

Kubernetes 集成

Kubernetes YAML 可以通过 podman-kube@.service systemd 模板在 systemd 中执行。模板的参数是 YAML 文件的路径。假设主目录中有一个 workload.yaml 文件,可以按如下方式执行:

$ escaped=$(systemd-escape ~/workload.yaml)
$ systemctl --user start podman-kube@$escaped.service
$ systemctl --user is-active podman-kube@$escaped.service
active

选项

--after=依赖名称

添加 systemd 单元的 “after” (After=) 选项,该选项定义了依赖列表与此服务之间的排序依赖关系。此选项可以指定多次。

用户定义的依赖项将追加到生成的单元文件中,但任何现有或默认定义的选项(例如 online.target)都**不会**被删除或覆盖。

--container-prefix=前缀

设置容器的 systemd 单元名称前缀。默认为 container

--env, -e=环境变量

将环境变量设置为 systemd 单元文件。

如果指定的环境变量没有值,Podman 会检查主机环境中的值,并且只有在主机上设置了该变量时才设置该变量。特殊情况下,如果指定的环境变量以 * 结尾但没有值,Podman 会在主机环境中搜索以前缀开头的变量,并将这些变量添加到 systemd 单元文件。

--files, -f

生成文件而不是打印到标准输出。生成的文件名为 {容器,Pod}-{ID,名称}.service,并放置在当前工作目录中。

注意:在启用了 SELinux 的系统上,生成的文件继承当前工作目录的上下文。根据 SELinux 设置,可能需要使用 restoreconchconsemanage 对生成的文件进行更改,以允许 systemd 访问这些文件。或者,在运行 mvcp 时使用 -Z 选项。

--format=格式

以指定格式 (json) 打印创建的单元。如果指定了 --files,则打印创建文件的路径而不是单元内容。

--name, -n

使用容器名称作为单元文件中的启动、停止和描述。

--new

此选项生成的单元文件不要求容器和 Pod 存在。相反,新的容器和 Pod 将根据其配置文件创建。单元文件是尽力创建的,可能需要进一步编辑;请在使用前仔细审查生成的文件。

请注意,--new 仅适用于直接通过 Podman 创建的容器和 Pod(即 podman [container] {create,run}podman pod create)。它不适用于通过 REST API 或 podman kube play 创建的容器或 Pod。对于 podman kube play,请改用 podman-kube@.service systemd 模板。

--no-header

不生成包含元数据(如 Podman 版本和时间戳)的头。

--pod-prefix=前缀

设置 Pod 的 systemd 单元名称前缀。默认为 pod

--requires=依赖名称

设置 systemd 单元的 requires (Requires=) 选项。类似于 wants,但声明了更强的需求依赖关系。

--restart-policy=策略

设置 systemd 重启策略。重启策略必须是以下之一:“no”、“on-success”、“on-failure”、“on-abnormal”、“on-watchdog”、“on-abort”或“always”。默认策略是 on-failure,除非容器是使用自定义重启策略创建的。

请注意,在具有自定义重启策略的容器上生成不带 --new 的单元可能会在关闭时导致问题;systemd 会尝试停止该单元,而 Podman 会尝试重新启动它。建议在生成单元文件时创建不带 --restart 的容器,并使用 --restart-policy 选项。

--restart-sec=时间

设置 systemd 服务 restartsec 值。配置在重启服务前(根据 restart-policy 配置)休眠的时间。以秒为单位。

--separator=分隔符

设置容器/Pod 的名称/ID 与前缀之间的 systemd 单元名称分隔符。默认为 -

--start-timeout=

使用给定的秒数值覆盖容器的默认启动超时。

--stop-timeout=

使用给定的秒数值覆盖容器的默认停止超时。

--template

添加模板说明符以从 systemd 单元文件运行多个服务。

请注意,如果 --new 未设置为 true,则默认将其设置为 true。但是,如果 --new 明确设置为 false,则命令将失败。

--wants=依赖名称

添加 systemd 单元的 wants (Wants=) 选项,该服务对此具有(弱)依赖关系。此选项可以指定多次。此选项不影响服务启动或停止的顺序。

用户定义的依赖项将追加到生成的单元文件中,但任何现有或默认定义的选项(例如 online.target)都**不会**被删除或覆盖。

示例

为容器生成并打印 systemd 单元文件

为运行 nginx 的容器生成 systemd 单元文件,重启策略为 always,超时为 1 秒,并打印到标准输出。请注意,Unit 部分中的 RequiresMountsFor 选项确保在启动服务之前挂载 GraphRoot 和 RunRoot 的容器存储。对于容器存储位于 iSCSI 或其他远程块协议等磁盘上的系统,这可确保在任何必要的存储操作联机之前不执行 Podman。

$ podman create --name nginx nginx:latest
$ podman generate systemd --restart-policy=always -t 1 nginx
# container-de1e3223b1b888bc02d0962dd6cb5855eb00734061013ffdd3479d225abacdc6.service
# autogenerated by Podman 1.8.0
# Wed Mar 09 09:46:45 CEST 2020

[Unit]
Description=Podman container-de1e3223b1b888bc02d0962dd6cb5855eb00734061013ffdd3479d225abacdc6.service
Documentation=man:podman-generate-systemd(1)
Wants=network-online.target
After=network-online.target
RequiresMountsFor=/var/run/container/storage

[Service]
Restart=always
ExecStart=/usr/bin/podman start de1e3223b1b888bc02d0962dd6cb5855eb00734061013ffdd3479d225abacdc6
ExecStop=/usr/bin/podman stop \
        -t 1 de1e3223b1b888bc02d0962dd6cb5855eb00734061013ffdd3479d225abacdc6
KillMode=none
Type=forking
PIDFile=/run/user/1000/overlay-containers/de1e3223b1b888bc02d0962dd6cb5855eb00734061013ffdd3479d225abacdc6/userdata/conmon.pid

[Install]
WantedBy=default.target

使用 --new 标志为容器生成 systemd 单元文件

--new 标志生成 systemd 单元文件,这些文件在服务启动和停止命令时创建和删除容器(参见 ExecStartPre 和 ExecStopPost 服务操作)。此类单元文件不与单个机器绑定,可以轻松共享并在其他机器上使用。

$ sudo podman generate systemd --new --files --name bb310a0780ae
# container-busy_moser.service
# autogenerated by Podman 1.8.3
# Fri Apr  3 09:40:47 EDT 2020

[Unit]
Description=Podman container-busy_moser.service
Documentation=man:podman-generate-systemd(1)
Wants=network-online.target
After=network-online.target
RequiresMountsFor=/var/run/container/storage

[Service]
Environment=PODMAN_SYSTEMD_UNIT=%n
Restart=on-failure
ExecStartPre=/bin/rm -f %t/%n-pid %t/%n-cid
ExecStart=/usr/local/bin/podman run \
        --conmon-pidfile %t/%n-pid \
	--cidfile %t/%n-cid \
	--cgroups=no-conmon \
	-d \
	-dit alpine
ExecStop=/usr/local/bin/podman stop \
        --ignore \
        --cidfile %t/%n-cid -t 10
ExecStopPost=/usr/local/bin/podman rm \
        --ignore \
        -f \
	--cidfile %t/%n-cid
PIDFile=%t/%n-pid
KillMode=none
Type=forking

[Install]
WantedBy=default.target

为包含两个简单 alpine 容器的 Pod 生成 systemd 单元文件

请注意,systemctl 只能用于 Pod 单元,不能单独用于启动或停止容器。容器由 Pod 服务与内部基础设施容器一起管理。

使用 systemctl statusjournalctl 检查容器或 Pod 单元文件。

$ podman pod create --name systemd-pod
$ podman create --pod systemd-pod alpine top
$ podman create --pod systemd-pod alpine top
$ podman generate systemd --files --name systemd-pod
/home/user/pod-systemd-pod.service
/home/user/container-amazing_chandrasekhar.service
/home/user/container-jolly_shtern.service
$ cat pod-systemd-pod.service
# pod-systemd-pod.service
# autogenerated by Podman 1.8.0
# Wed Mar 09 09:52:37 CEST 2020

[Unit]
Description=Podman pod-systemd-pod.service
Documentation=man:podman-generate-systemd(1)
Requires=container-amazing_chandrasekhar.service container-jolly_shtern.service
Before=container-amazing_chandrasekhar.service container-jolly_shtern.service
Wants=network-online.target
After=network-online.target
RequiresMountsFor=/var/run/container/storage

[Service]
Restart=on-failure
ExecStart=/usr/bin/podman start 77a818221650-infra
ExecStop=/usr/bin/podman stop \
        -t 10 77a818221650-infra
KillMode=none
Type=forking
PIDFile=/run/user/1000/overlay-containers/ccfd5c71a088768774ca7bd05888d55cc287698dde06f475c8b02f696a25adcd/userdata/conmon.pid

[Install]
WantedBy=default.target

已生成 systemd 单元文件的安装。

Podman 生成的单元文件包含一个 [Install] 部分,其中包含单元的安装信息。它在安装过程中由 systemctl(1) 的 enable 和 disable 命令使用。

生成 systemd 单元文件后,将其安装到 /etc/systemd/system 以供 root 用户运行,或安装到 $HOME/.config/systemd/user 以供非 root 用户安装。使用 systemctl enable 启用复制的单元文件。

注意:将单元文件复制到 /etc/systemd/system 并启用它会标记该单元文件在启动时自动启动。同样,将单元文件复制到 $HOME/.config/systemd/user 并启用它会标记该单元文件在用户登录时自动启动。

# Generated systemd files.
$ podman pod create --name systemd-pod
$ podman create --pod systemd-pod alpine top
$ podman generate systemd --files --name systemd-pod

# Copy all the generated files.

$ sudo cp pod-systemd-pod.service container-great_payne.service /etc/systemd/system
$ systemctl enable pod-systemd-pod.service
Created symlink /etc/systemd/system/multi-user.target.wants/pod-systemd-pod.service → /etc/systemd/system/pod-systemd-pod.service.
Created symlink /etc/systemd/system/default.target.wants/pod-systemd-pod.service → /etc/systemd/system/pod-systemd-pod.service.
$ systemctl is-enabled pod-systemd-pod.service
enabled

要在该用户首次登录时运行放置在 $HOME/.config/systemd/user 中的用户服务,请使用 --user 标志启用该服务。

$ systemctl --user enable <.service>

systemd 用户实例在用户最后一次会话关闭后被终止。systemd 用户实例可以在启动时启动,并且即使在用户注销后也能通过启用 lingering 来保持运行,使用以下命令:

$ loginctl enable-linger <username>

使用 systemctl 对生成的已安装单元文件执行操作。

参考上述示例,为 Pod 创建并启用 systemd 单元文件,并使用 systemctl 执行操作。

由于 systemctl 默认使用 root 用户,因此通过在 podman cli 命令后附加 sudo 可以看到所有使用 systemctl 的更改。要以非 root 用户身份执行 systemctl 操作,请在与 systemctl 交互时使用 --user 标志。

注意:如果之前创建的容器或 Pod 正在使用共享资源(例如端口),请确保在启动生成的 systemd 单元之前将其删除。

$ systemctl --user start pod-systemd-pod.service
$ podman pod ps
POD ID         NAME          STATUS    CREATED          # OF CONTAINERS   INFRA ID
0815c7b8e7f5   systemd-pod   Running   29 minutes ago   2                 6c5d116f4bbe
$ sudo podman ps # 0 Number of pods on root.
CONTAINER ID  IMAGE  COMMAND  CREATED  STATUS  PORTS  NAMES
$ systemctl stop pod-systemd-pod.service
$ podman pod ps
POD ID         NAME          STATUS   CREATED          # OF CONTAINERS   INFRA ID
272d2813c798   systemd-pod   Exited   29 minutes ago   2                 6c5d116f4bbe

创建一个简单的 alpine 容器并使用 --new 标志生成 systemd 单元文件。启用服务并使用 systemctl 命令控制操作。

注意:当使用 systemctl start 启动容器时,它会启动一个具有类似配置的“新”容器,而不是更改已经运行的容器。

# Enable the service.

$ sudo podman ps -a
CONTAINER ID  IMAGE                            COMMAND  CREATED        STATUS     PORTS  NAMES
bb310a0780ae  docker.io/library/alpine:latest  /bin/sh  2 minutes ago  Created           busy_moser
$ sudo systemctl start container-busy_moser.service
$ sudo podman ps -a
CONTAINER ID  IMAGE                            COMMAND  CREATED        STATUS        PORTS      NAMES
772df2f8cf3b  docker.io/library/alpine:latest  /bin/sh  1 second ago   Up 1 second              distracted_albattani
bb310a0780ae  docker.io/library/alpine:latest  /bin/sh  3 minutes ago  Created                  busy_moser

另请参阅

podman(1)podman-container(1)systemctl(1)systemd.unit(5)systemd.service(5)conmon(8)podman-systemd.unit(5)

历史

2020 年 4 月,Sujil Shah (sushah at redhat dot com) 更新了详细信息并添加了将生成的 .service 文件用作 root 和非 root 的用例

2019 年 8 月,Valentin Rothberg (rothberg at redhat dot com) 更新了对 pod 的支持

2019 年 4 月,由 Brent Baude (bbaude at redhat dot com) 最初编译