設定 - Systemdサービスユニット

提供:MochiuWiki : SUSE, EC, PCB
ナビゲーションに移動 検索に移動

概要

サービスとは、PCの起動時に自動的に実行され、バックグラウンドで仕事をするために待機するソフトウェアのことである。

一般的に、サービスはグラフィカルユーザインターフェースを持たず、ユーザの操作無しに動作する。
最もよく知られているサービスは、Web、メール、データベース等のサーバで、Apache、MySQL等がある。

また、ハードウェアの検出やUSBメモリの自動統合(マウント)等もサービスによって行われる。

サービスには、システム起動時に関連するタスクやハードウェアに関連するタスクを行う"内部サービス"と、
その後にユーザがインストールするサービス(通常は全てのサーバサービスを含む)の2種類がある。

技術用語やコンピュータ用語では、サービスは伝統的にデーモンと呼ばれている。
そのため、サーバコンポーネントであるsshdやmysqldのように、サービスを表すプログラムの最後の文字として"d"が用いられることが多い。

一方、Systemdは、システムおよびセッションマネージャ(initシステム)であり、
コンピュータの起動プロセスからシャットダウンまでの全動作時間にわたって、システム上で動作するすべてのサービスを管理する役割を担っている。

プロセスは常に(可能な限り)並行して起動され、起動プロセスを可能な限り短くする。
ここで、.serviceで終わる設定ファイルを作成して、Systemdが制御・監視するプロセスに関するコードを保持する場合をSystemd Service Unitファイルと呼ぶ。

Systemdには、サービス、タイマ、マウントポイント、ソケット、スワップスペース、デバイス等のユニットが存在する。
そのため、Systemdは管理用の設定の全てをファイルから取得する。

Systemdの用語では、これらを"ユニット"と呼び、システム全体に適用されるユニットと各ユーザ領域にのみ適用されるユニットがある。

ユニットには、サービスを開始するためのサービスユニットや、ある時点でのアクションを(繰り返し)実行するためのタイマユニット等、様々な種類がある。

各タイプのユニットファイルに共通しているのは、iniファイルに似た構造をしていることである。
ユニットファイルは、いくつかのセクション(多くの場合、3セクション)で構成されている。

Systemdではセクションと呼ばれ、その中に一連のキーと値のペア(Systemdではディレクティブと呼ばれる)が格納されている。


コマンドライン

コマンドラインやターミナルでSystemdを管理するツールはsystemctlと呼ばれる。

多くのコマンドはシステムに深く介入するため、root権限が必要である。
そのため、必要な操作を行うには、このコマンドをスーパユーザ権限で実行する必要がある。


ログ

Systemdは、ログ情報を中央のジャーナルに書き込む。
これは、journalctlコマンドにより読み出すことができ、検索やフィルタのオプションも含まれている。


システム全体の単位

usr/lib/systemd/systemディレクトリには、サービスによってシステム全体にプレインストールされているユニットの全てのファイルがある。

/etc/systemd/systemディレクトリには、ユーザが作成または編集したシステム全体のユニットの全てのファイルがある。
/etc/systemd/systemディレクトリと/usr/lib/systemd/systemdディレクトリで同名のユニットファイルがある場合は、
/etc/systemd/systemディレクトリのファイルが優先される。


ユニットの種類

ユニットには様々な種類があり、ファイルの拡張子に応じてsystemdの扱いが異なる。

Systemdユニットファイルの種類
種類(拡張子) 説明
.device デバイスファイルを作成する。
.mount ファイルシステムのマウントとアンマウントをする。
.path ファイルやディレクトリの変更に応じたサービスユニットを実行する。
.network ネットワークの設定を行う。
.service サービスを設定する。
.socket プロセス間の接続を確立する。
.target ユニットのグループを定義する。
.timer Cronジョブのような定期的なタスクを実行する。


ここでは、.service拡張子のユニットについて記載する。


ユニットファイルの構造

ユニットファイルは、3つのセクションで構成される。

  • [Unit]セクション
    ユニットの種類によらない一般的なオプションの設定
    • Description
      このユニットの説明を記述する。
      sudo systemctl statusを実行する時に表示される。
    • Documentation
      このユニットについてのドキュメントのURIを記述する。
    • After
      このユニットの前に起動するユニットを記述する。
    • Before
      このユニットの後に起動するユニットを記述する。
    • Requires
      このユニットが依存するユニットを記述する。
      前のユニットの起動が失敗した場合は起動しない。
    • Wants
      このユニットが依存するユニットを記述する。
      前のユニットの起動が失敗した場合でも起動する。
    • Conflicts
      指定したユニットと一緒に起動しない。

  • [Service]セクション
    サービスに関する設定を記述する。
    • Type
      プロセスの起動方法を記述する。
      各方法は以下の6通りある。
      "起動が完了する"とは、次の他ユニットが実行可能であることを意味する。
      • simple
        デフォルト。プロセスが起動した時点で起動が完了する。
      • forking
        フォークして親プロセスが終了した時点で起動が完了する。
      • oneshot
        simpleと似ているが、次のユニットを実行する前に自身のプロセスを終了する。
      • dbus
        D-Busを使用するプロセスであり、D-Busの接続名を見つけた時に起動が完了する。
      • notify
        simpleと似ているが、sd_notify関数で起動完了のメッセージを受信した時に起動が完了する。
      • idle
        simpleと似ているが、他のジョブが終了するまで待機する。(シェルへの出力が混ざらないようにするため)
    • ExecStart
      起動時に実行するコマンドを記述する。
    • ExecStop
      停止時に実行するコマンドを記述する。
    • ExecReload
      リロード時に実行するコマンドを記述する。
    • Restart
      プロセスが停止した時、プロセスを再起動する条件を記述する。
      各条件は以下の4つがある。
      • always
        常に自動的に再起動する。
      • no
        再起動しない。
      • on-success
        終了コードが0で再起動する。
      • on-failure
        終了コードが0以外で再起動する。
      • on-abort
        キャッチできないシグナルで終了した時に再起動する。
      • on-watchdog
        監視時間切れで再起動する。
      • on-abnormal
        SIGHUP、SIGINT、SIGTERM、SIGPIPE以外のシグナルで終了した時に再起動する。
    • RestartSec
      再起動するまでの待ち時間(秒)を記述する。
    • ExecStartPreおよびExecStartPost
      サービス起動前(ExecStartPre)およびサービス起動後(ExecStartPost)の追加コマンドを指定する。
      これは、サービスの起動判定には関連させたくないコマンドを指定する。
    • ExecStopPost
      サービス停止後に実行するコマンドを指定する。
      これは、サービスが異常終了した場合にも実行される。
    • KillMode
      ExecStopで停止せずに残ったプロセスの処理方法を指定する。
      • none
        残プロセスは放置する。
      • process
        メインプロセスが残っている場合、SIGTERM / SIGKILLで停止する。
        その他の残プロセスは放置する。
      • control-group
        グループ内の全ての残プロセスをSIGTERM / SIGKILLで停止する。
      • mixed
        メインプロセスをSIGTERM / SIGKILLで停止して、続けてグループ内の全ての残プロセスをSIGKILLで停止する。
    • PIDFile
      fork型サービスのメインプロセスのPIDファイルを指定する。
    • BusName
      D-Bus型サービスのbus接続名を指定する。
    • User
      プロセスを起動するユーザを指定する。
    • Group
      プロセスを起動するグループを指定する。
    • PrivateTmp
      このサービス専用の/tmpと/var/tmpを用意する。
    • ReadOnlyDirectories
      指定ディレクトリ以下をReadOnlyモードにする。
    • InaccessibleDirectories
      指定ディレクトリ以下をアクセス不可にする。
    • RootDirectory
      指定ディレクトリにchrootする。
  • [Install]セクション
    インストール時の設定を記述する。
    • Alias
      sudo systemctl enableコマンドの実行時に、Aliasで指定された名前のユニットのシンボリックリンクを作成する。
    • RequiredBy
      sudo systemctl enableコマンドの実行時に、このユニットの".required"ディレクトリにリンクを作成する。
    • WantedBy
      sudo systemctl enableコマンドの実行時に、このユニットの".wants"ディレクトリにリンクを作成する。
    • Also
      sudo systemctl enable / disableコマンドの実行時に、同時にenable / disableするユニットを記述する。


ユニットの詳細を知りたい場合は、以下のコマンドを実行する。

man systemd.unit


サービスの詳細を知りたい場合は、以下のコマンドを実行する。

man systemd.service


以下に、よく使用されるユニットファイルのフォーマットを示す。

[Unit]
Description=<ユニットファイルの説明>
After=<指定したユニットリストの起動後に実行する>
Before=<指定したユニットリストの前に実行する>
Requires=<指定したユニットリストの起動成功後に実行する。(ユニット起動時に依存ユニットも起動するが、依存ユニット失敗時は起動しない)>
Wants=<指定したユニットリストが起動失敗しても実行する。(ユニット起動時に依存ユニットも起動するが、依存ユニット失敗時でも起動する)>

[Service]
Environment=<環境変数リスト>
EnvironmentFile=<環境変数ファイル>
Type=<simple | forking | oneshot | dbus | notify | idle>
ExecStart=<起動コマンド>
ExecStop=<停止コマンド>
ExecReload=<再起動コマンド>
Restart=<always | on-abort | on-watchdog | on-abnormal | on-failure | on-success | no>
RemainAfterExit=<yes | no>
PIDFile=<メインプロセスのPIDファイルパス>
User=<ユニットファイルの実行ユーザ>
SuccessExitStatus=<(0以外に)メインプロセス正常終了とみなすexitコードリスト>

[Install]
Alias=<ユニットの別名>
RequiredBy=<sudo systemctl enableコマンドの実行時に、このユニットの".required"ディレクトリにリンクを作成する>
WantedBy=<sudo systemctl enableコマンドの実行時に、このユニットの".wants"ディレクトリにリンクを作成する>
Also=<同時に起動および停止するユニット>



ユニットの依存関係および順序の確認

Systemdユニットの依存関係および順序は、以下のコマンドで確認できる。

指定したユニットが必要とするユニットを表示する。ユニット名を省略した時は、default.targetが指定される。
依存関係のユニットがTargetタイプの場合、さらに、それが必要なユニットを再帰的に表示する。
--allオプションを付加することにより、全てのユニットを再帰的に表示する。

sudo systemctl list-dependencies <ユニット名>


指定したユニットよりも先に起動するユニットを表示する。

sudo systemctl list-dependencies <ユニット名> --after


指定したユニットよりも後に起動するユニットを表示する。

sudo systemctl list-dependencies <ユニット名> --before



独自のユニットやSystemdサービスファイルの作成

例えば、PC起動時に何らかのスクリプトやソフトウェアをバックグラウンドで実行したいとする。
そのためには、サービスユニットを作成する必要がある。

サービスユニットを作成するための構文を、以下に示す。

まず、/etc/systemd/systemディレクトリまたは/usr/lib/systemd/systemディレクトリに、ユニットファイルを作成する。
一般的には、ユーザが任意で作成するユニットファイルは、/etc/systemd/systemディレクトリに配置する。

sudo vi /usr/lib/systemd/system/<ユニットファイル名>.service
または
sudo vi /etc/systemd/system/<ユニットファイル名>.service


# スクリプトを使用する場合

[Unit]
Description =           # サービスの説明を記述する
After = network.target  # ※指定しなくてもよい

[Service]
User=              # ユーザ名  例. root  ※指定しなくてもよい
WorkingDirectory=  # 実行するファイルまたはスクリプトがあるディレクトリのフルパス  ※指定しなくてもよい
ExecStart =        # 実行するファイルまたはスクリプトへのフルパス または ファイル名のみ(WorkingDirectoryを指定する場合)
Restart=always     # ※指定しなくてもよい

[Install]
WantedBy =         # multi-user.target または graphical.target等


# Pythonを使用する場合

[Unit]
Description =           # サービスの説明を記述する
After = network.target  # ※指定しなくてもよい

[Service]
User=              # ユーザ名  例. root  ※指定しなくてもよい
WorkingDirectory=  # 実行する.pyファイルがあるディレクトリのフルパス  ※指定しなくてもよい
ExecStart =        # <Pythonの実行ファイル> <実行する.pyファイルへのフルパス または ファイル名のみ(WorkingDirectoryを指定する場合)>
                   # 例. /usr/bin/python3 main.py
Restart=always     # ※指定しなくてもよい

[Install]
WantedBy =         # multi-user.target または graphical.target等


以下の例では、Glancesという名前のサービスファイルを作成して、Linux向けの監視ツールであるglancesをバックグラウンドで動作させている。

sudo vi /usr/lib/systemd/system/glances.service


[Unit]
Description = Glances in Web Server Mode
After = network.target

[Service]
ExecStart = /usr/bin/glances -w -t 5

[Install]
WantedBy = multi-user.target


[Install]セクションでは、[WantedBy]キーにより、ユニットがいつ起動するかを指定する。
下表に、指定することができるキーの値を示す。

ターゲット 説明
multi-user.target グラフィカルログインの有無にかかわらず、マルチユーザシステム用(ランレベル3に対応)
graphical.target グラフィカルログインが必要なマルチユーザシステム用(ランレベル3 + グラフィカルログインに対応)
rescue.target 一般的に、シングルユーザモードはシステムのレスキュー時にのみ必要(ランレベル1に対応)
reboot.target システムの再起動時にのみユニットが実行する。
poweroff.target システムのシャットダウン開始時にのみ実行するユニットである。
default.target 別の既存ターゲットへのシンボリックリンクである。
例えば、Ubuntuデスクトップの初期設定では、default.targetはgraphical.targetである。


サービスファイルを読み込んで、新しいサービスを追加する。

sudo systemctl daemon-reload



手動で作成したシステムのサービスユニットを有効にする

サービスユニットの作成後は、サービスを有効にして起動する必要がある。

<サービスユニットのファイル名>において、
例えば、上記で作成したglancesサービスを有効にするには、sudo systemctl enable glances.serviceとなる。

以下のコマンドを実行して、新しいサービスユニットを読み込み・追加する。

sudo systemctl daemon-reload


サービスユニットを自動起動に設定する。

sudo systemctl enable <サービスユニットのファイル名>


サービスユニットを起動する。

sudo systemctl start <サービスユニットのファイル名>


サービスユニットの状態を確認する。
sudo systemctl status <サービスユニットのファイル名>