web-dev-qa-db-ja.com

systemdサービスをオーバーライドまたは構成するにはどうすればよいですか?

多くのsysv initスクリプトは、/etc/defaultの対応するファイルを使用して、管理者が設定できるようにしました。アップスタートジョブは、.overrideファイルを使用して変更できます。 systemdがUbuntuのデフォルトになったので、systemdユニットをオーバーライドまたは構成するにはどうすればよいですか?

105
muru

systemdユニットは、/etc/defaultのファイルに従う必要はありません。 systemdは簡単に設定できますが、systemdユニットファイルの構文を知っている必要があります。

パッケージは通常、ユニットファイルを/lib/systemd/system/で出荷します。これらはnot編集されません。代わりに、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ファイルが作成されます。このファイル(または.conf内の他の/etc/systemd/system/foo.service.d/ファイル)を使用して、設定を追加またはオーバーライドできます。

コマンド引数のオーバーライド

gettyサービスを例にとります。ユーザーにTTY2の自動ログインが必要だとしましょう(これはお勧めできませんが、単なる例です)。 TTY2はgetty@tty2サービスによって実行されます(tty2はテンプレート/lib/systemd/system/getty@serviceのインスタンスです)。これを行うには、getty@tty2サービスを変更する必要があります。

$ systemctl cat getty@tty2
# /lib/systemd/system/[email protected]
#  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 [email protected], 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. ExecStartAfter(全体ではなく、変数ごとではない)、Environmentに似た追加設定であり、EnvironmentFileRestartSecなどの設定をオーバーライドするのではなく、再設定する前に明示的にTypeをクリアする必要がありました。 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

を押す CtrlAltF2、プレスト!そのTTYでアカウントにログインします。

前にも言ったように、getty@tty2はテンプレートのインスタンスです。それで、そのテンプレートのすべてのインスタンスをオーバーライドしたい場合はどうなりますか?これは、テンプレート自体を編集することで実行できます(インスタンス識別子を削除します-この場合はtty2):

systemctl edit getty@

環境をオーバーライドする

/etc/defaultファイルの一般的な使用例は、環境変数の設定です。通常、/etc/defaultはシェルスクリプトであるため、シェル言語のコンストラクトを使用できます。ただし、systemdでは、そうではありません。次の2つの方法で環境変数を指定できます。

ファイル経由

ファイルに環境変数を設定したとします:

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

次に、オーバーライドに追加できます。

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

特に、/etc/default/grubに割り当てのみが含まれ、シェル構文が含まれていない場合は、EnvironmentFileとして使用できます。

Environmentエントリ経由

上記は、次のオーバーライドを使用して実現することもできます。

[Service]
Environment=FOO=bar

しかし、これは複数の変数、スペースなどでは扱いにくい場合があります。そのようなインスタンスの例については、 他の回答の1つ をご覧ください。

参考文献

このメカニズムにより、systemdユニットをオーバーライドしたり、(オーバーライドファイルを削除するだけで)そのような変更を元に戻したりすることが非常に簡単になります。変更できる設定はこれらだけではありません。

次のリンクが役立ちます。

178
muru