我知道 systemd 提供了一种出色的机制来覆盖包提供的单元文件以影响服务配置/行为。这通常通过使用以下命令来完成
sudo systemctl edit <unitfile>
在以下位置创建覆盖配置文件
/etc/systemd/system/<unitfile.d>/
Systemd 还提供了一种单独的机制来定义模板单元文件,并在运行时实例化它以创建特定于实例的单元。这需要将模板文件命名为
<servicename>@.service
然后将其实例化为
systemctl start <servicename>@<instancename>
现在,我遇到一种情况,我想将包提供的服务作为多个单元实例运行。我想避免创建自己的模板单元文件,因此我尝试查看是否可以覆盖包提供的单元文件来创建模板单元文件。
因为根据我的理解,模板单元文件的命名约定与常规单元文件不同,所以我认为我无法通过将模板文件放在 /etc/systemd/system 中来用模板文件覆盖包提供的单元文件。
是否有明确的方法来实现我想要做的事情?
具体场景:grafana 包安装了一个 grafana-server.service 单元文件。我想在我的计算机上运行两个 grafana 实例 - 分别用于 DEV 和 STG。我已经能够做到这一点:
- 修改 grafana-server.service 文件(使用 %I 设置文件夹位置和文件路径)
- 将修改后的 grafana-server.service 重命名为[电子邮件保护]
使用以下命令启动 grafana 实例:
sudo systemctl start grafana-server@dev
和
sudo systemctl start grafana-server@stg
但是,这会破坏与 grafana 提供的服务单元文件的链接,如果升级时他们增强了服务文件,我将需要再次重做此活动。我的目标是避免这种直接依赖,而是将其转换为覆盖依赖。
有什么想法吗?
答案1
对于以下两个选项,首先覆盖 grafana-server.service(不带 @)/etc/systemd/system
并抑制ExecStart
(假设它使用它)以使其不启动任何内容。开启/etc/systemd/system/grafana-server.service.d/10-disable-execstart.conf
:
[Service]
ExecStart=
WorkingDirectory=/path/to/your/confdir
选项 1 - 使用通用实例覆盖
[email protected]
使用以下配置创建与您的设置相对应的[Unit]
和[Service]
:
[Unit]
PartOf=grafana-server.service
ReloadPropagatedFrom=grafana-server.service
这些应该将 grafana-server 启动/停止/重启绑定到您的所有实例。魔法没有很好的文档记录,但如果你将<instance_name>.conf
文件放在你的上/path/to/your/confdir
,所有这些实例将自动绑定!
选项 2 - 覆盖特定实例以保留包配置
如果你想保留所有更新优点来自包服务文件,但接受维护自定义实例选项,为每个实例名称从通用创建一个符号链接
/lib/systemd/system/grafana-server.service
到
/etc/systemd/system/grafana-service@<instance>.service
然后使用以下方法仅覆盖该实例的特定选项
/etc/systemd/system/grafana-server@<instance>.service.d/99-my-options.conf
确保将以下配置添加到[Unit]
和:[Service]
99-my-options.conf
[Unit]
PartOf=grafana-server.service
ReloadPropagatedFrom=grafana-server.service
这将假设每个实例的所有grafana-server.service
选项,并将用99-my-options.conf
文件上的所有选项覆盖它们,并将启动/停止/重启操作绑定到 grafana-server.service。
在这两个选项上,如果你运行
systemctl start grafana-server.service
所有具有/path/to/confdir/<instance>.conf
文件的实例都将启动。这同样适用于stop
和,restart
并且您可以始终使用它们的grafana-server@<instance>
服务名称单独管理它们。