systemd:模板单元文件

欢迎回到我们关于 systemd 功能的后续系列。 正如您在我们之前的文章中看到的,systemd 为服务启动和管理带来了更多的功能和灵活性。 我们介绍的 systemd 中的一些特性是为了与旧的 SysVinit 兼容。 然而,systemd 的一个全新特性是模板单元文件。

什么是模板单元文件?

模板单元文件允许 systemd 从单个配置文件中处理多个单元。 您可以使用特殊格式调用 systemd 模板单元文件来使用此功能:

<service_name>@<argument>.service

参数是传递给 systemd 以在单元文件中使用的一些文本(字符串)。 该参数可用于自定义 systemd 处理该单元的特定实例的方式。 可以存在同一单元的多个实例。

单元文件中使用了两个标识符来传递实例参数。

  • %i 传递参数,特别格式化(转义)
  • %I 逐字传递参数而不转义

转义在使用之前使用特殊规则格式化标识符。 否则会破坏文件名的字符将被替换。

现实世界的例子

OpenVPN,用于 example, 使用模板单元文件来允许多个实例使用同一个单元文件。 这是供参考的单元文件:

[Unit]
Description=OpenVPN Robust And Highly Flexible Tunneling Application On %I
After=network.target

[Service]
PrivateTmp=true
Type=forking
PIDFile=/var/run/openvpn/%i.pid
ExecStart=/usr/sbin/openvpn --daemon --writepid /var/run/openvpn/%i.pid --cd /etc/openvpn/ --config %i.conf

[Install]
WantedBy=multi-user.target

在这里,您可以看到在调用文件名的任何地方使用的转义参数 %i。 描述中使用未转义的参数 %I 以便更易于阅读。

这个设置允许你调用 [email protected] 来启动一个以 myconfig 作为配置文件名的 openvpn 实例。 在这种情况下,该命令将使用 /etc/openvpn/myconfig.conf 作为配置文件启动 OpenVPN。 它还将进程 ID 文件存储为 /var/run/openvpn/myconfig.pid。

其他 example 是每个基于文本的终端 Fedora 系统。 当用户使用 Ctrl+Alt+F2、Ctrl+Alt+F3 等切换控制台时,会生成一个新终端。 在这种情况下,systemd 调用名为 [email protected] 的服务。 systemd 搜索单元模板 getty.service 并为单元文件提供适当的参数,例如 tty2 或 tty3。 %i 标识符提供实例字符串,以便终端在新控制台上启动。

示例模板

为了 example,你可以为一个花哨的 web 服务器编写一个模板单元文件,如下所示:

# fancy-web-server.service
[Unit]
Description=My HTTP server
AssertPathExists=/srv/webserver

[Service]
Type=notify
ExecStart=/usr/sbin/some-fancy-httpd-server %i.conf
Nice=5

[Install]
WantedBy=multi-user.target

使用上述配置,我们可以从单个模板配置文件启动多个实例。 例如:

$ sudo systemctl start [email protected]
$ sudo systemctl start [email protected]

这将启动两个 fancy-http-server 实例,启动命令

/usr/sbin/some-fancy-httpd-server config1.conf
/usr/sbin/some-fancy-httpd-server config2.conf

config1 和 config2 字符串取自 systemd 命令,并替换为单元文件中 %i 的实例。

此功能很有用,因为您的服务可以使用许多不同的配置或设置,而无需每次都重写您的服务。

进一步阅读

FreeDesktop 网站有 附加信息 如果您想了解有关使用模板单元文件的更多信息。 (提示:在该文档中查找单词模板以查看该主题所涵盖的位置。)