当前位置: 首页>>技术教程>>正文


如何覆盖或配置systemd服务?

, , ,

问题描述

许多sysv init脚本使用/etc/default中的相应文件来允许管理员对其进行配置。可以使用.override文件修改Upstart作业。现在systemd是Ubuntu中的默认设置,如何覆盖或配置systemd单元?

最佳解决思路

systemd单元无需服从/etc/default中的文件。 systemd易于配置,但要求您了解systemd单元文件的语法。

软件包通常在/lib/systemd/system/中提供单元文件。这些不需要编辑。相反,systemd允许您通过在/etc/systemd/system/中创建适当的文件来覆盖这些文件。

对于给定的服务foo,该包将提供/lib/systemd/system/foo.service。您可以使用systemctl status foo检查其状态,或使用journalctl -u foo查看其日志。要覆盖foo定义中的内容,请执行以下操作:

sudo systemctl edit foo

这将在以单元命名的/etc/systemd/system中创建一个目录,并在该目录中创建一个override.conf文件(/etc/systemd/system/foo.service.d/override.conf)。您可以使用此文件(或/etc/systemd/system/foo.service.d/中的其他.conf文件)添加或覆盖设置。

覆盖命令参数

getty服务为例。假设我想为我的用户提供TTY2自动登录(这不是建议,但只是一个例子)。 TTY2由getty@tty2服务运行(tty2是模板/lib/systemd/system/getty@service的实例)。为此,我必须修改getty@tty2服务。

$ systemctl cat getty@tty2
# /lib/systemd/system/getty@.service
#  This file is part of systemd.
#
#  systemd is free software; you can redistribute it and/or modify it
#  under the terms of the GNU Lesser General Public License as published by
#  the Free Software Foundation; either version 2.1 of the License, or
#  (at your option) any later version.

[Unit]
Description=Getty on %I
Documentation=man:agetty(8) man:systemd-getty-generator(8)
Documentation=http://0pointer.de/blog/projects/serial-console.html
After=systemd-user-sessions.service plymouth-quit-wait.service
After=rc-local.service

# If additional gettys are spawned during boot then we should make
# sure that this is synchronized before getty.target, even though
# getty.target didn't actually pull it in.
Before=getty.target
IgnoreOnIsolate=yes

# On systems without virtual consoles, don't start any getty. Note
# that serial gettys are covered by serial-getty@.service, not this
# unit.
ConditionPathExists=/dev/tty0

[Service]
# the VT is cleared by TTYVTDisallocate
ExecStart=-/sbin/agetty --noclear %I $TERM
Type=idle
Restart=always
RestartSec=0
UtmpIdentifier=%I
TTYPath=/dev/%I
TTYReset=yes
TTYVHangup=yes
TTYVTDisallocate=yes
KillMode=process
IgnoreSIGPIPE=no
SendSIGHUP=yes

# Unset locale for the console getty since the console has problems
# displaying some internationalized messages.
Environment=LANG= LANGUAGE= LC_CTYPE= LC_NUMERIC= LC_TIME= LC_COLLATE= LC_MONETARY= LC_MESSAGES= LC_PAPER= LC_NAME= LC_ADDRESS= LC_TELEPHONE= LC_MEASUREMENT= LC_IDENTIFICATION=

[Install]
WantedBy=getty.target
DefaultInstance=tty1

特别是,我必须更改ExecStart行,目前是:

$ systemctl cat getty@tty2 | grep Exec     
ExecStart=-/sbin/agetty --noclear %I $TERM

要覆盖它,请执行:

sudo systemctl edit getty@tty2

并添加:

[Service]
ExecStart=
ExecStart=-/sbin/agetty -a muru --noclear %I $TERM

注意:

  1. 在重新设定之前,我必须明确地清除ExecStart,因为它是添加剂设置,类似于AfterEnvironment(作为整体,不是per-variable)和EnvironmentFile,并且与诸如RestartSecType的超控设置相反。 ExecStart只能为Type=oneshot服务提供多个条目。

  2. 我不得不使用正确的节头。在原始文件中,ExecStart位于[Service]部分,因此我的覆盖也必须将ExecStart放入[Service]部分。通常,使用systemctl cat查看实际的服务文件将告诉您需要覆盖的内容以及它所在的部分。

通常,如果编辑systemd单元文件,要使其生效,则需要运行:

sudo systemctl daemon-reload

但是,systemctl edit会自动为您执行此操作。

现在:

$ systemctl cat getty@tty2 | grep Exec
ExecStart=-/sbin/agetty --noclear %I $TERM
ExecStart=
ExecStart=-/sbin/agetty -a muru --noclear %I $TERM

$ systemctl show getty@tty2 | grep ExecS
ExecStart={ path=/sbin/agetty ; argv[]=/sbin/agetty -a muru --noclear %I $TERM ; ... }

如果我这样做:

sudo systemctl restart getty@tty2

然后按下Ctrl Alt F2!我将在该TTY上登录我的帐户。

正如我之前所说,getty@tty2是模板的一个实例。那么,如果我想覆盖该模板的所有实例呢?这可以通过编辑模板本身来完成(删除实例标识符 – 在本例中为tty2):

systemctl edit getty@

压倒环境

/etc/default文件的常见用例是设置环境变量。通常,/etc/default是一个shell脚本,因此您可以在其中使用shell语言结构。但是,对于systemd,情况并非如此。您可以通过两种方式指定环境变量:

通过文件

假设您已在文件中设置环境变量:

$ cat /path/to/some/file
FOO=bar

然后,您可以添加到覆盖:

[Service]
EnvironmentFile=/path/to/some/file

特别是,如果您的/etc/default/grub仅包含赋值而没有shell语法,则可以将其用作EnvironmentFile

通过Environment条目

以上也可以使用以下覆盖来完成:

[Service]
Environment=FOO=bar

但是,对于多个变量,空格等,这可能会变得棘手。请查看one of my other answers以获取此类实例的示例。

进一步阅读

通过这种机制,可以很容易地覆盖systemd单元,以及撤消这些更改(只需删除覆盖文件)。这些不是唯一可以修改的设置。

以下链接很有用:

  • systemd上创建Arch Wiki条目

  • systemd for Administrators,第IX部分:在/etc /sysconfig和/etc /default上(由systemd的主要开发者,Lennart Poettering)

  • systemd手册,特别是systemd.unitsystemd.service的联机帮助页

  • 用于Upstart用户的Systemd上的Ubuntu Wiki条目

参考资料

本文由Ubuntu问答整理, 博文地址: https://ubuntuqa.com/article/1316.html,未经允许,请勿转载。