unitファイル入門

自分の書いたスクリプトも systemd に載せられる

ここまで nginx を systemctl で扱ってきました。あの nginx という名前は、どこかに書いてあるから通じています。実体は次のファイルです。

systemctl cat nginx | head -5

これが unit ファイルです。systemd に対して「このサービスは、どんな名前で、何を実行して、どういう性質のものか」を説明する設定ファイルにすぎません。自分で書けば、自作のスクリプトも同じように systemctl で扱えるようになります。

最小の unit ファイルは3行

[Unit] Description=サイトの死活を記録する [Service] Type=oneshot ExecStart=/usr/local/bin/hello-service.sh

角かっこの行がセクションの見出しです。[Unit] にはサービスそのものの説明や、他のサービスとの前後関係を書きます。[Service] には、実際に何をどう動かすかを書きます。

ExecStart が実行するコマンドです。ここは必ず絶対パスで書きます。systemd は受講者のシェルとは別の環境で動くので、PATH に頼った書き方は通りません。ここは初学者が最も詰まる場所です。

Type で性質を伝える

Type=oneshot は「走って、終わって、それで完了」という性質です。バックアップや集計のように、一度実行すれば役目を終える処理はこちらになります。

対して Type=simple は「起動したらずっと居続ける」という性質です。nginx のようなデーモンはこちらです。simple にしたのに実際のプログラムがすぐ終わってしまうと、systemd は落ちたとみなします。逆に oneshot にしたのにプログラムが終わらないと、起動待ちのまま止まります。書き分けを間違えると、動くはずのものが failed になります。

置き場所と、書いたあとの一手

自作の unit ファイルは /etc/systemd/system/ に置きます。ファイル名がそのままサービス名になるので、hello-service.service と保存すれば systemctl start hello-service で呼べます。

systemctl daemon-reload systemctl start hello-service

daemon-reload を忘れないでください。systemd は unit ファイルを読み込んで覚えているので、ファイルを置いたり書き換えたりしただけでは気づきません。「変更したのに反映されない」の原因は、ほとんどがこれです。

動いたかは status とログで確かめる

systemctl status hello-service --no-pager journalctl -u hello-service --no-pager

oneshot は走り終えると inactive (dead) に戻ります。止まっているように見えても、これは正常な姿です。本当に実行されたかどうかは、ログか、スクリプトが残したファイルで判断します。

手を動かす

実行するスクリプトを1本置き、それを呼ぶ unit ファイルを書いて、systemctl から動かします。

ヒント

  • 1. /usr/local/bin/hello-service.sh を作り、date の結果を /var/log/hello-service.log に追記する内容にする
  • 2. chmod +x /usr/local/bin/hello-service.sh で実行できるようにする
  • 3. /etc/systemd/system/hello-service.service を書く。Type=oneshot と ExecStart を含める
  • 4. systemctl daemon-reload のあと systemctl start hello-service で動かす

6 項目で採点します