名称

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

概要

podman generate systemd [选项] 容器|Pod

描述

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

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 可以通过 [email protected] 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=) 选项,用于在依赖项列表和此服务之间排序依赖项。此选项可以指定多次。

用户定义的依赖项会附加到生成的 service 文件,但任何默认情况下需要的或定义的选项(例如,online.target不会被删除或覆盖。

--container-prefix=前缀

设置容器的 systemd 服务名称前缀。默认值为 container

--env, -e=env

将环境变量设置到 systemd 服务文件中。

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

--files, -f

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

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

--format=格式

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

--name, -n

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

--new

此选项会生成不希望容器和 Pod 存在的 service 文件。相反,将根据它们的配置文件创建新的容器和 Pod。服务文件是尽力创建的,可能需要进一步编辑;在生产环境中使用之前,请仔细查看生成的配置文件。

请注意,--new 仅适用于通过 Podman 直接创建的容器和 Pod(即 podman [container] {create,run}podman pod create)。它不适用于通过 REST API 或通过 podman kube play 创建的容器或 Pod。对于 podman kube play,请改用 [email protected] 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 值。配置在重启服务(如重启策略配置)之前要休眠的时间。接受以秒为单位的值。

--separator=分隔符

设置容器/Pod 的名称/ID 和前缀之间 systemd 服务名称的分隔符。默认值为 -

--start-timeout=

使用给定的以秒为单位的值覆盖容器的默认启动超时。

--stop-timeout=

使用给定的以秒为单位的值覆盖容器的默认停止超时。

--template

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

请注意,如果未将 --new 设置为 true,则默认情况下会将其设置为 true。但是,如果将 --new 显式设置为 false,则该命令将失败。

--wants=依赖项名称

添加 systemd 服务的 wants (Wants=) 选项,表明此服务(弱)依赖于它。此选项可以指定多次。此选项不会影响服务的启动或停止顺序。

用户定义的依赖项会附加到生成的 service 文件,但任何默认情况下需要的或定义的选项(例如,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 用户实例将被杀死。可以使用 lingering 标记启用 systemd 用户实例,使其在启动时启动并在用户注销后继续运行,方法是:

$ 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

使用 --new 标记创建一个简单的 Alpine 容器并生成 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 月,更新了详细信息,并添加了使用生成的 .service 文件作为 root 用户和非 root 用户的用例,作者是 Sujil Shah(sushah at redhat dot com)。

2019 年 8 月,更新了对 Pod 的支持,作者是 Valentin Rothberg(rothberg at redhat dot com)。

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