2022年11月14日月曜日

Linuxでデーモンを定義して動かす


背景

Linuxのデーモン(daemon 守護者)とは、システムの裏側で動いてくれるプログラムです。
systemdなどプログラムの最後の文字がdになっている場合はデーモンを意味する場合があります。
参考:
Linux リテラシ - 第4回 デーモン
デーモン (ソフトウェア)

サーバーからsshのログアウトをした後も動き続けて欲しいプロセスがあったので、書き方を調べて適用してみました。
備忘録を兼ねて取り組んだ内容を記事にします。

使った物

  • EC2 インスタンス(OS: amazon linux2)
  • sshログインするPC

javaのプログラムを動かすservice

linux環境で既にデーモンとして動いているsystemdに設定ファイルを読み込ませることでデーモンの管理ができます。
場所は/etc/systemd/systemです。

下記のserviceファイルは、関連するプログラムを要求し、bash_profileを読み込み(行儀は良くない)、自動起動設定可能にしたjavaのプログラム起動用のデーモンです。
/etc/systemd/system/server-raw-device-log.service
ExecStart=/bin/bash -c "source /home/ec2-user/.bash_profile && /usr/bin/java -jar /home/ec2-user/deploy/back/back.jar"

上記のserviceは下記のようにファイル名をサービス名として、サービス開始や起動時の自動開始の設定が可能です。
# 開始
sudo systemctl start server-raw-device-log.service
# 起動時自動開始有効化
sudo systemctl enable server-raw-device-log.service
# 起動時自動開始有効化確認
sudo systemctl is-enabled server-raw-device-log.service

要所を解説します。

便利情報: ログは/var/log/messagesで見れる

実行時やエラーの出力は/var/log/messagesに出力されます。
端末を複数実行して下記のコマンドを実行しておくと、ログを見れて作業が捗ると思います。
sudo tail /var/log/messages -f
上記コマンドをターミナルで実行しつつ、別のターミナルでサービスの起動コマンドを実行すると、実行時のエラーの内容を確認できます。

注意: service編集後は再読込が必要

serivceファイルを変更後にserviceを実行しようとすると、再読込要求のエラーが出ます。
sudo systemctl start server-raw-device-log.service
Warning: server-raw-device-log.service changed on disk. Run 'systemctl daemon-reload' to reload units.
要求通り読み直せば実行できます。
sudo systemctl daemon-reload
sudo systemctl start server-raw-device-log.service

Afterで起動時の順序を指定でき、Requiresで一緒に起動させられる

UnitではAfter, Wants, Requiresなどで関連するデーモンを指定できます。
/etc/systemd/system/server-raw-device-log.service
[Unit]
After=syslog.target
After=network.target
After=mariadb.service
Requires=mariadb.service
Afterで指定すると起動時の順序を決めれてよいのですが、それが動いてない状態でサービスを動かすと、動いてないまま動作を開始します。
今回の場合mariadbが必須のプログラムだったのでRequiresで指定して動作時にmariadbが動いてなければ動かす設定にしました。

bash_profileを読み込んでくれないが、bashとsourceを組み合わせれば同等の環境を作れる

serviceが実行するプログラムは標準ではbash_profileを読み込んでくれません。
service化するプログラムなら.envなどを利用して変数設定可能にするのが混乱が少なくなる設計方針だとは思いますが、今回はひとまず動かしたいので読み込ませました。
/etc/systemd/system/server-raw-device-log.service
ExecStart=/bin/bash -c "source /home/ec2-user/.bash_profile && /usr/bin/java -jar /home/ec2-user/deploy/back/back.jar"ExecStart=/bin/bash -c "source /home/ec2-user/.bash_profile && /usr/bin/java -jar /home/ec2-user/deploy/back/back.jar"
上記のようにbash -cの引数にsourceでbash_profileを読ませた上でjavaを実行すれば、bash_profileに定義した環境変数を参照して実行できました。

起動時自動実行にはInstall設定が必要

Install設定が無い状態で自動実行を有効化すると、エラーは何も出ませんが状態がstaticから変わらず、OSを再起動しても自動で動いてくれません。
sudo systemctl enable server-raw-device-log.service
sudo systemctl is-enabled server-raw-device-log.service
static

下記の設定をserviceに記述すると自動実行の有効化が可能になります。
/etc/systemd/system/server-raw-device-log.service
[Install]
WantedBy=multi-user.target

sudo systemctl enable server-raw-device-log.service
sudo systemctl is-enabled server-raw-device-log.service
enabled

終わり

関連サービスの状況を見つつ、bash_profileを読み込んだ上でjavaのプログラムをOS起動時に自動で実行するデーモンを書けました。

参考

Linux リテラシ - 第4回 デーモン
デーモン (ソフトウェア)
systemd
How to check syslog in Bash on Linux?
【新旧対応】Linuxでの自動起動の設定方法を解説

0 件のコメント :