1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

systemdのserviceユニットを作る(基本的な設定)

Last updated at Posted at 2025-03-01

以下のコマンドは、基本的にroot権限で実行するものとする。

1.最小限のユニットファイル

1.1 ユニットファイルを作成

コマンドでsystemctl edit --full --force <作成するユニット名>.serviceを実行すると、エディタが自動で開く。
エディタで以下のように入力し、エディタを閉じれば、最低限のユニットファイルができあがる。(ここでは仮に、tcpdumpでパケットキャプチャをするサービスを作ってみる)

[Unit]
Description=systemdユニットのテスト
[Service]
ExecStart=/usr/bin/tcpdump -w /var/log/capture.pcap

「Description」はユニットの説明、「ExecStart」はsystemctl start <ユニット名>.serviceで実行される、ユニットの処理を開始するコマンドを指定する。

これを設定することで、systemctl status <ユニット名>でユニットの情報表示、systemctl start <ユニット名>でユニットの起動、systemctl stop <ユニット名>でユニットの停止ができるようになる。

1.2 解説

systemdのユニットファイルは、/usr/lib/systemd/system/(/lib/systemd/system/の場合もある)の下、もしくは/etc/systemd/system/の下に配置される。/usr/lib/systemd/system/はパッケージマネージャが管理するので、基本的に編集するのは/etc/systemd/system/下のファイルになる。
systemctl editコマンドを使うと、/etc/systemd/system下のファイルを操作できる。オプションによって以下のように動作が変わる。

  • systemctl edit <ユニット名>.service: 既存のユニットファイルの設定の一部をオーバーライドする。ファイルは/etc/systemd/system/<ユニット名>.d/下に保存される。
  • systemctl edit --full <ユニット名>.service: 上のように別ディレクトリでオーバーライドするのではなく、/etc/systemd/system/<ユニット名>.serviceを直接書き換える。
  • systemctl edit --full --force <ユニット名>.service: 指定したユニットが存在しない場合、/etc/systemd/system/<ユニット名>.serviceを新規作成する。

エディタなどで直接/etc/systemd/system/の下にファイルを作ってもよい。ただし、その場合は編集後に、設定を反映するためにsystemctl daemon-reloadを実行する必要がある。

2.serviceの動作を変更する

1で作ったシンプルなユニットファイルでも機能するが、もう少し細かい設定をしてみたい。
以下の設定は[Service]の下で設定する。
※ここでは一部の設定項目しか紹介していない。他の設定項目については、systemd.unit(5)、systemd.service(5)、systemd.exec(5)、systemd-kill(5)、systemd.resource-control(5)などを参照のこと。

Type=

serviceのタイプを指定する。
Type=simple
 デフォルト。基本的にはこれを使えば問題ない。
Type=forking
 親プロセスがすぐに終了し、子プロセスを起動するようなコマンドの場合、このタイプを使う。
Type=oneshot
 設定の変更やある種の起動コマンドのような、一瞬で処理が終了する(裏で長時間プロセスを動かさない)コマンドに使う。このタイプでは、一緒にRemainAfterExit=true(プロセスが終了しても、サービスはActive状態として扱われる)を設定することがある。

Restart=

プロセスが終了したときに、プロセスを自動でもう一度開始するかどうかを設定できる。(systemctl stopなどで明示的に停止した場合は再開されない)
Restart=no
 再開しない(デフォルト)
Restart=on-failure
 異常終了した場合は再開する。(終了コード0以外の場合に異常終了とみなす。)
Restart=always
 必ず再開する。

RestartSec=

Restart=の設定で再開するまでの間隔を指定できる。
デフォルトは100ms(100ミリ秒)

StartLimitBurst=, StartLimitIntervalSec=

StartLimitIntervalSec秒以内にStartLimitBurst回以上、サービスを開始しようとすると無効になる。
Restart=と組み合わせて、何度も繰り返し再開を試みるのを抑止できる。
デフォルトは10秒、5回

SuccessExitStatus=

デフォルトで正常終了扱いになる「0」以外に、正常終了扱いにする終了コードを指定できる。

User=,Group=

コマンドの実行ユーザ、実行グループを指定できる。(デフォルトではroot)

ExecStop=

systemctl stopなどでサービスを停止するときに実行するコマンドを指定できる。(デフォルトではSIGTERMを送ってプロセスを終了する)

ExecStopPost=

プロセスが終了した後に、後処理として実行するコマンドを指定できる。
プロセスが異常終了し、Restart=on-failureの設定などで再起動される場合にも実行される。

CPUQuota=

CPUの最大使用率を制限する。単位として「%」をつけて指定する。
topコマンドなどのCPU使用率の表示と同じように、1コアをすべて使った場合に100%となるので、マルチコアのシステムでは100%以上を指定してもよい。

MemoryHigh=

最大使用メモリを指定する。単位としてK, M, G, Tが使える。
メモリ制限を超過してもプロセスは停止しないが、実行が非常に遅くなる。

MemoryMax=

上のMemoryHighと同様だが、メモリ制限を超過するとプロセスが停止する。

1.1のユニットファイルの改善

上で紹介した設定項目を使用して、1.1のユニットファイルを改善してみた。

・改善点

  • 異常終了時に自動で再開する
  • プロセス終了時にキャプチャファイルの名前を変更し、上書きされないようにする
[Unit]
Description=systemdユニットのテスト
[Service]
Type=simple
ExecStart=/usr/bin/tcpdump -w /var/log/capture.pcap
Restart=on-failure
ExecStopPost=/usr/local/bin/mv_capture.sh

また、以下のようなスクリプト/usr/local/bin/mv_capture.shを作成しておく。(ExecStopPost=で直接コマンドを書かないのは、systemdはシェルを通さずにコマンドを実行するため、コマンド置換が使えないから)

#!/bin/bash
mv /var/log/capture.pcap /var/log/capture_$(date '+%Y%m%d%H%M%S').pcap

参考リンク

https://www.freedesktop.org/software/systemd/man/latest/systemd.service.html
https://www.freedesktop.org/software/systemd/man/latest/systemd.unit.html
https://www.freedesktop.org/software/systemd/man/latest/systemd.exec.html
https://www.freedesktop.org/software/systemd/man/latest/systemd.kill.html

1
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?