Home systemd 模板化服务
Post
Cancel

systemd 模板化服务

服务模板

Linux/Unix上的大多数服务都是单例服务:在一个特定的系统上,通常只有一个Syslog、Postfix或Apache实例同时运行。 但是有些服务会运行多个,常见的getty@.service,会为每个终端都运行一个,以显示登录提示,通常在tty1-tty6上运行。 还有常见的 systemd-fsck@.service,它是一个文件系统检查器,为每个需要检查的块设备实例化一次。

systemd中的服务时根据模式名命名的,如foobar.service,foobar是服务的标识字符串,模式支持扩展,如 foobar@quux.service,表示在quux上运行一个foobar服务,即实例化。例如:serial-getty@ttyS2.service是 为ttyS2实例化的串行getty服务。这种方式,不需要额外配置,就可以快速创建或运行一个新的服务。

1
# systemctl start serial-getty@ttyUSB0.service

运行以上命令后,systemd将优先根据该service的具体名称查找对应的单元配置文件。如果存在,就使用对应的具体的service 文件启动服务,(即支持写明特定的实例化对象,以进行模板的override)。如果不存在,则会套用模板serial-getty@.service, 该模板对所有示例都是通用的,大致内容如下:

1
2
3
4
5
6
7
8
9
[Unit]
Description=Serial Getty on %I
BindTo=dev-%i.device
After=dev-%i.device systemd-user-sessions.service

[Service]
ExecStart=-/sbin/agetty -s %I 115200,38400,9600
Restart=always
RestartSec=0

这相当于是一个简化版的getty@.service,这种模板服务和普通服务基本相同,主要是它多了 %i%I%i%I 会被systemd替换为服务的实例标识符。在上例中,就会被替换为ttyUSB0,查看验证:

1
2
3
4
5
6
7
$ systemctl status serial-getty@ttyUSB0.service
serial-getty@ttyUSB0.service - Getty on ttyUSB0
	  Loaded: loaded (/lib/systemd/system/serial-getty@.service; static)
	  Active: active (running) since Mon, 26 Sep 2011 04:20:44 +0200; 2s ago
	Main PID: 5443 (agetty)
	  CGroup: name=systemd:/system/getty@.service/ttyUSB0
		  └ 5443 /sbin/agetty -s ttyUSB0 115200,38400,9600

这就是systemd的模板化服务的核心思想,可以使用 systemctl enable 创建 .wants 中的软链接,实现实例化 的服务的自启动。

对于模板化的服务,是一定要指定一个实例名才可以创建服务,本身的服务是不能直接创建的,因为没有实例名。

%i 和 %I 的区别

%i 后面一般跟一个确切的名称,不带路径,没有转义。 %I 可以用在在路径的名称,会对 /进行转义

另外,还有其他特殊字符,具体参考手册。man systemd.unit

This post is licensed under CC BY 4.0 by the author.