systemd のサービスを定期的に再起動する
systemd で作ったサービスを定期的に再起動したい。
定期的に再起動する必要があるのか。と問われれば、私自身も答えに窮するのだけれど。
今回は pip install しているpython パッケージや npm run で起動している元になっている npm/node_moduleを、定期的更新して再起動をしたいなと思ったんですよ。
systemd の書き方
[Service] Restart=always RuntimeMaxSec=864000
unit ファイルに上記のように書くと定期的に再起動がかかる。
仕組みの説明
RuntimeMaxSec による実行時間の制限
RuntimeMaxSec=60
RuntimeMaxSec をつけることで、サービスのプロセスの継続実行時間を秒単位で指定できる。今回は 60*60*24*10 = 864,000
を指定した。
Restart による再起動の設定
Restart=always
Restart の設定を alwaysにしておくと、サービスに定義したプロセスが異常終了など、終了したときに自動再実行によりプロセスが起動している状態を維持してくれる。
組合わたら、定期的に再起動
これらを組合わたら、定期的に再起動のコマンドが実現する
[Service] Restart=always RuntimeMaxSec=864000
組み合わせてしまうと、指定時間経過後にプロセスが終了して、always により再度サーバーが実行される。
検討したその他の手法との比較など
systemctl restart を自動的に実行するのもなんか違う。
timer を作ると管理が複数に分かれてしまう。
crontab に書いてしまうと、管理がsystemd と分かれてしまうのであまり好ましくないし。
サーバーが自分を自分で再起動するように sleep を使った定期的に再起動が仕込まれた起動用python スクリプトを書くのは煩雑すぎるし。
systemd の timer を使っても、設定が2つに別れてしまって面倒だ。
今回採用した方法だと、設定ファイルが1つにまとまるので書き捨てて仕様書を残さなくても気付けるメリットが有る。
systemd の設計者は、こういう利用は想定外なんだろうと思うんだけど、1箇所に必要な設定が集まるのは嬉しい
nginx を自動的に再起動する
例えば、nginx を再起動する場合。
既存のUnitsを編集する
sudo systemctl edit nginx
すると、conf.d 方式で Service ユニットの追記上書きファイルの記入を催促される
### Editing /etc/systemd/system/nginx.service.d/override.conf ### Anything between here and the comment below will become the new contents of the file [Service] Restart=always RuntimeMaxSec=864000 ### Lines below this comment will be discarded
保存する。保存すると/etc/systemd/system/nginx.service.d/override.conf
が作成されて上書きされる
編集(上書き)結果を確認する。
sudo systemctl edit nginx
上記コマンドで上書きが反映されているのがわかる。
# /etc/systemd/system/nginx.service.d/override.conf [Service] Restart=always RuntimeMaxSec=864000
systemd のユニットをリロードして
systemctl daemon-reload
該当のサービス・ユニットを再起動する。
systemctl restart nginx
これで、定期的・自動的に再起動するnginx の出来上がりである。
pip や npm の更新が辛い
npm でパッケージをいれて、npm run で動かせるサーバーアプリケーションが多いけど、パッケージはlock されて基本的には更新を考慮してない。
debian の apt などは セキュリティ・パッチが含まれた deb などをaptの設定自動的にダウンロードして再実行してくれる。ほんとうにこの差は大きいと思う。
gitlab とは自動的に自分で自分を更新してくれるし、そういう意味で node のnpm で作られたサーバーって今後危ういなぁなどと思う。
もちろん、むやみにライブラリの更新はしないほうがいい。がセキュリティ・フィックスも気になるし。
service と timer を分けて書くとき
再起動するサービスと、タイマー、この2つのユニットを分けて書くときは、ネットにいっぱいサンプルが転がってる。
うちのサイトでの作成サンプルは、この記事でtimer/serviceのunits を使ってsystemdのユニットを定期的に起動している。
分ける場合のサンプル → https://takuya-1st.hatenablog.jp/entry/2020/04/09/051239
分ける場合のtimer の書式 → https://takuya-1st.hatenablog.jp/entry/2020/04/24/032822
再起動スクリプト+Service+Timer+タイマ書式の4つが必要になる。こういうことを考えるのが面倒なので再起動がすぐ終わるServiceなら今回紹介しているMaxTimeによる再起動が楽だと思うの。
関連資料
参考資料
2024-09-01
やっぱりこの書き方に戻ってきたので、検索キーワードを増やしておく。