サマリ
親のunitがrestartやstop/startしたら、依存するunitも起動しておいてほしい。
子のunitに親へのRequires
と After
つけるだけだと、親のrestartで子もrestartしたけど、親のstop/startでは再起動しなかった。ググッても PartOf
使えなど諸説ありで腑に落ちない。
動かして確認→WantedBy
で解決できた。
検証
動作確認のため、parent, child, child-wanted-by-parent という3つのunitを作りました。
[Unit]
Description=parent
[Service]
ExecStart=/bin/bash -c 'trap "echo exited parent" EXIT; echo started parent; sleep infinity'
[Unit]
Description=child
Requires=parent.service
After=parent.service
[Service]
ExecStart=/bin/bash -c 'trap "echo exited child" EXIT; echo started child; sleep infinity'
[Unit]
Description=child wanted by parent.
Requires=parent.service
After=parent.service
[Service]
ExecStart=/bin/bash -c 'trap "echo exited child wanted by parent" EXIT; echo started child wanted by parent; sleep infinity'
[Install]
WantedBy=parent.service
以下に、親・子の状態が"親の状態", "子の状態"であるときに、systemctl で"親を操作"すると、
"WantedBy無しの子", "WantedByありの子"がどうなったかをまとめました。
※"-" は、変化なしを表す
親の状態 | 子の状態 | 親を操作 | WantedBy無しの子 | WantedByありの子 |
---|---|---|---|---|
stopped | stopped | start | - | started |
stopped | started | start | - | - |
started | stopped | stop | - | - |
started | stopped | restart | - | started |
started | started | stop | stopped | stopped |
started | started | restart | restarted | restarted |
環境
確認はdebian jessieで行いました。用いたスクリプト(vagrant/ansible)を下に配置しましたので、よろしければどうぞ。
https://github.com/sumomoneko/test-systemd-unit-dependency
動機など
dockerコンテナをsystemdで管理しようと考えた際、親のdockerデーモンがdebアップデートなどで再起動した場合の挙動がわからず、調査しました。
ただ、本家dockerの最近の考えとしては、systemdでコンテナを管理するのではなく、--restart
つかってねということだそうです。(s.a. docker run --restart=alwaysがどれくらいrestartしてくれるか調べた )
もっとも、 --restart
は コンテナを毎回破棄する -rm
とは相容れないので、「unit起動ごとにコンテナ作りなおすよ!」という場合は、本記事が役に立つのかなと思います。
終わりに
この方法がsystemd的に正しいのかどうか、いまいち確信がは持てていません。
「普通はこうだ」など指摘などありましたら、ソフトビニール製のモヒカンお願いいたします。