サービス管理の試験形式
systemctl enable を打っただけでサービスが動き出すと思っていると、そこで詰まります。enable と start は完全に独立した操作です。ここと mask の強さ、[Install] の意味が出題の中心です。
enable は今すぐ起動せず、start は次回に効かない
ターミナル
systemctl start nginx # 今動く。再起動したら止まったまま
systemctl enable nginx # 今は動かない。次回の起動から動く
systemctl enable --now nginx # 両方enable が実際にしているのは、ユニットファイルの [Install] セクションを読み、WantedBy で指定されたターゲットの .wants ディレクトリにシンボリックリンクを作ることです。disable はそのリンクを消すだけです。
残りは、restart が停止してから起動、reload がプロセスを落とさず設定だけ再読み込み、status が状態と直近のログです。判定を返すのが is-active と is-enabled、一覧が list-unit-files です。
mask は disable より強い
disable はリンクを消すだけなので、systemctl start を打てば普通に起動しますし、他のユニットが依存していればそちらの都合で勝手に起動してしまいます。mask は /etc/systemd/system/<ユニット名> を /dev/null へのシンボリックリンクにすることで、完全に起動不能にします。手動の start も拒否され、依存起動も封じられます。解除は unmask です。
| 状態 | 手動の start | 依存による起動 | 次回起動時 |
|---|---|---|---|
| enabled | 起動する | 起動する | 起動する |
| disabled | 起動する | 起動する | 起動しない |
| masked | 失敗する | 起動しない | 起動しない |
unit ファイルは3つのセクションでできている
プレーンテキスト
[Unit]
Description=My sample service
After=network.target
[Service]
Type=simple
ExecStart=/usr/local/bin/myservice
Restart=on-failure
[Install]
WantedBy=multi-user.target[Unit] は説明と他のユニットとの関係、[Service] は起動方法、[Install] は enable したときに何をするかです。[Install] が無いユニットは enable できません。
[Unit] では、After が指定したユニットの後に起動するという順序だけの指定で、Before がその逆です。Requires は強い依存で相手が起動できなければ自分も起動せず、Wants は弱い依存で相手が失敗しても自分は起動します。After は順序、Requires は依存、という区別が問われます。
[Service] の Type も頻出です。
| Type | 意味 |
|---|---|
simple | ExecStart のプロセスがそのまま本体。既定値 |
forking | プロセスがフォークして親が終了する従来型のデーモン |
oneshot | 1回実行して終了する。終わるまで次に進まない |
notify | 起動完了を systemd に自分で通知する |
oneshot は使い捨ての処理に使い、RemainAfterExit=yes を添えると実行後も active 扱いのままにできます。
置き場所には優先順位があり、変更には daemon-reload が要る
管理者が自分で置く /etc/systemd/system/ が最も優先され、パッケージが置く配布元の定義 /lib/systemd/system/ が最も低い優先度です。だからパッケージの定義を直接編集せず、/etc/systemd/system/ に置いて上書きするのが正しい作法です。一部だけ変えたいなら systemctl edit で drop-in を作ります。
ユニットファイルを追加・編集したら systemctl daemon-reload が必要です。忘れると変更が反映されません。定番の落とし穴です。
試験で狙われるところ
SysVinit との対応も出ます。chkconfig が enable と disable、service が start と stop に対応する、と覚えます。
そのほかは、enable は今すぐ起動せず start は次回に効かないこと、mask が依存起動まで封じること、ユニットを書き換えたら daemon-reload が要ること、[Install] の無いユニットは enable できないこと、そして restart は必ず一度停止するので無停止で設定だけ入れたいなら reload を使うことです。