私のような古くからのLinux管理者は、initスクリプトを書いてサービスを登録することが多かったと思います。
しかし、Ubuntu15.04以降はsystemdが使われています。その中で、旧来のSystv initやUpstartは後方互換性のために利用可能だったため、新しいシステム管理デーモンは何となく利用していました。
・・・が、サービスを自分で登録する段になって困ることがあったので、改めてSysV initやUpstartとの関係と、大まかな使い方について整理しました。
- 【非推奨/後方互換でサポート】SysV init
- 【非推奨/後方互換でサポート】Upstart
- 【推奨/最新】systemd
SysV initやUpstartとsystemdの違い
Linux上の各サービスの起動~停止までの一連をsystemdが管理する。systemdを用いたLinux上でのサービスの起動停止や登録は、更にはOSの再起動、状態(以前のrunlevel)は下表のとおり代替される。
サービスの起動・停止・再起動等
service(非推奨) | systemd(推奨) | 備考 |
service name start | systemctl start name.service | 起動 |
service name stop | systemctl stop name.service | 停止 |
service name restart | systemctl restart name.service | 再起動 |
service name condrestart | systemctl try-restart name.service | 実行中の場合のみ再起動 |
service name reload | systemctl reload name.service | 設定の再読み込み |
service name status | systemctl status name.service systemctl is-active name.service | サービス状態のチェック |
service –status-all | systemctl list-unit-files –type service | 全サービスを一覧表示 |
サービスの有効・無効
chkconfig | systemctl | 備考 |
chkconfig name on | systemctl enable name.service | 有効 |
chkconfig name off | systemctl disable name.service | 無効 |
chkconfig –list name | systemctl status name.service | 確認 |
chkconfig –list | systemctl list-unit-files –type service | 確認 |
systemctl list-dependencies –after | 前後関係確認 | |
systemctl list-dependencies –before | 前後関係確認 |
OSの停止・再起動・サスペンド等
今回、systemdを調べていて一番驚いた点です。実はrebootコマンドがsystemctl rebootに変わっていました。rebootコマンドは残っていますが、かなりショックを受けました。
古いコマンド | systemctl | 備考 |
halt | systemctl halt | 停止 |
poweroff | systemctl poweroff | 電源OFF |
shutdown | systemctl poweroff | 電源OFF |
reboot | systemctl reboot | 再起動 |
rebootコマンドとか、いつも使っているので念のために確認してみたところ、確かにsystemctlを読んでいました。
lrwxrwxrwx /sbin/halt -> /bin/systemctl
lrwxrwxrwx /sbin/poweroff -> /bin/systemctl
lrwxrwxrwx /sbin/reboot -> /bin/systemctl
lrwxrwxrwx /sbin/shutdown -> /bin/systemctl
再起動の度にsystemctl rebootとは打たないと思うので、上記を確認したうえでもrebootコマンド等は使い続けると思います。
新規サービスの登録方法
ずっと昔は/etc/init.d/の下に起動スクリプトを書いて、rc3.d等の設定をしていました。しかし、systemdになってからは、シェルスクリプトで起動停止することはしません。起動コマンド、停止コマンド等をパラメータ形式で書いた*.serviceファイルを/etc/systemd/system/配下に格納して、systemdに登録します。
/usr/lib/systemd/system/ | OS側のデフォルトのサービスが格納されている |
/etc/systemd/system/ | 追加インストールしたサービスの設定ファイルを格納。自分で用意した設定ファイルはこちらに格納 |
新規サービスの登録方法(zabbix-serverの例)
zabbix4.4.8をインストールした後に、サービスファイルとして登録する例を記します。「結局何をすればいいの?」という方向けにシェルコードから行きます。完成系の/etc/systemd/system/zabbix-server.serviceはこちらを参照。
参考:Ubuntu20.04へZabbix4.4.xをインストールする
# サービスの作成
sudo touch /etc/systemd/system/zabbix-server.service
sudo chmod 664 /etc/systemd/system/zabbix-server.service
# サービスの中身を書く・・・のですが、以下手順でwgetするファイルで代替します。
sudo vi /etc/systemd/system/zabbix-server.service
# wget
wget https://eco.senritu.net/wp-content/uploads/zabbix-server.zip
unzip zabbix-server.zip
sudo mv zabbix-server.service /etc/systemd/system/zabbix-server.service
# 追加したサービスをロード
sudo systemctl daemon-reload
# 動作確認
sudo systemctl start zabbix-agent.service
sudo systemctl status zabbix-agent.service
sudo systemctl stop zabbix-agent.service
/etc/systemd/system/zabbix-server.serviceの中身は以下の通りです。コメントを適宜入れているので、コメントなし版はこちらからダウンロードしてもらえるといいかと。
# Unitは基本情報を書く。
# Wants、Afterは、ネットワークが起動している事とかが多いはず。
# sudo systemctl list-units --type targetでターゲットは確認できる。
[Unit]
Description=Zabbix Server
Documentation=man:zabbix(8)
Wants=network-online.target
After=network.target network-online.target
# Serviceの中で、特に気にするのはPIDFileと、ExecStart。
# PIDと、起動スクリプトを記載するだけ。
[Service]
Type=simple
NotifyAccess=all
PIDFile=/tmp/zabbix_server.pid
EnvironmentFile=-/usr/local/etc
ExecStart=/usr/local/sbin/zabbix_server -c /usr/local/etc/zabbix_server.conf
ExecReload=/bin/kill -HUP $MAINPID
LimitCORE=infinity
Restart=no
# Installは、サービスの自動起動設定時に利用される。
# Installが無くても動くが、systemctl enableしたい場合には作成すること
[Install]
WantedBy=multi-user.target
登録した新規サービスが動かない場合のデバッグ方法(zabbix-serverの例)
systemdのserviceファイルを作成しているときに動かなくて確認していた場所は主に以下観点です。
- /etc/systemd/system/以下に格納したserviceファイル記載の各種パスがあっているか?
- serviceファイルに記載したExecStartが動くか?
- 少しでも修正した場合はsudo systemctl daemon-reloadをしたか?
- /var/log以下に出力されるログを確認
- PIDファイルが出来たか?
- 対象サービスが実行する実行ファイル(ここではzabbix-server)を直接rootで実行して動くか?
- いったん再起動だ!(笑)
また、対象サービスを中途半端に実行してsystemdが認識していない場合(つまりsystemdから起動しなかったプログラム)は、以下のような感じでkillできます。
sudo kill -TERM `cat /tmp/zabbix_server.pid`
最後に
普段、aptでインストールしているためsystemdもaptが面倒を見てくれることが殆どです。しかし、ソースコードから最新のソフトウェアをインストールする際には、systemdに登録してOSの起動・停止時にサービスが連動する仕組みを提供する必要があります。
今までは「systemdって意味わからないんだけど動くからいいか」と言う状況でしたが、一度でも実績を作ってしまえば、次回はそれを横展開・改善すれば良いだけなので、良い勉強になったと思います。
参考リンク
Ubuntu向けのマニュアルではありませんが、RHELのマニュアルは読みやすくてお勧めです。