Docker Compose restart の挙動
Docker (Compose) の 自動再起動について
ホストOSを起動したタイミングであるアプリケーションを自動で立ち上げたい、 あるいは何らかの問題で落ちた時に、自動で再起動して欲しい、というニーズは何処にでもあるかと思います。
今回は Docker Compose (以下単純にComposeと記します)に関して、コンテナの再起動や、他コンテナとの依存関係が設定されている場合に どのような挙動をとるのかを調べてみました。
なお、今回検証に使用した Compose バージョンは 1.6.0
です。
restart policy
Docker 及び Compose では、 run/upの restart policy
の設定することにより、
コンテナが停止した際の再起動にまつわる設置を行うことができます。
オプション | 意味 |
---|---|
no | 再起動しない (デフォルト) |
on-failure[:max-retries] | プロセスが 0 以外のステータスで終了した場合、 最大:max_retries の分だけ再起動を行う |
always | 明示的に stop がされない限り、終了ステータスに関係なく常に再起動が行われる |
unless-stopped | 最後にdocker daemon が起動していた際に ステータスが終了状態だった場合は再起動しない。それ以外はalwaysと同じ。 |
ちなみに、起動したもののすぐに(10秒。今の所固定っぽいです)終了してしまう場合は
起動回数に応じて遅延処理(100ms => 200 => 400..)が入るようになっています。
fluentd
のリトライでも使われている、いわゆる Exponential Backoff アルゴリズムですね。
Compose の 「依存関係、起動順」 と 「再起動」の関係
依存関係、コンテナの起動順
Compose内のコンテナの依存関係、起動順を決定する要因には以下があります。
- depends_on
- links
- volumes_from
- network_mode
再起動との関連は?
「依存関係、起動順」 と 「再起動」にまつわる設定を両方行った場合、 どういった挙動になるのか気になったので試してみました。
version: "2" services: elasticsearch: image: elasticsearch ports: - 9200:9200 restart: always kibana: image: kibana ports: - 5601:5601 depends_on: - "elasticsearch"
$ docker-compose up -d Starting composerestarttest_elasticsearch_1 Starting composerestarttest_kibana_1 $ docker ps CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES d9b3f1c7796b kibana "/docker-entrypoint.s" 2 minutes ago Up 3 seconds 0.0.0.0:5601->5601/tcp composerestarttest_kibana_1 3e493eaf0fb7 elasticsearch "/docker-entrypoint.s" 2 minutes ago Up 3 seconds 0.0.0.0:9200->9200/tcp, 9300/tcp composerestarttest_elasticsearch_1
上記の設定では kibana サービスが elasticsearch サービスに依存しています。 この状態で elasticsearch が停止/再起動した場合、従属するkibnaコンテナはどのような動きになるでしょうか。
docker exec -i -t composerestarttest_elasticsearch_1 kill 1
具体的に確認したかった内容とその結果を以下に示します。
Q. 従属 コンテナのプロセスはそのまま? それとも再起動される?
従属コンテナであるkibanaはそのままでした。
docker ps CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES d9b3f1c7796b kibana "/docker-entrypoint.s" 3 minutes ago Up About a minute 0.0.0.0:5601->5601/tcp composerestarttest_kibana_1 3e493eaf0fb7 elasticsearch "/docker-entrypoint.s" 3 minutes ago Up 28 seconds 0.0.0.0:9200->9200/tcp, 9300/tcp composerestarttest_elasticsearch_1
restartのオプションを幾つか試してみましたが挙動は同じでした。 依存関係の設定と再起動のそれに相関はなさそうです。
Q. コンテナ間の接続は再開される?
docker exec -i -t composerestarttest_kibana_1 ping elasticsearch PING elasticsearch (172.18.0.2): 56 data bytes 64 bytes from 172.18.0.2: icmp_seq=0 ttl=64 time=0.073 ms 64 bytes from 172.18.0.2: icmp_seq=1 ttl=64 time=0.092 ms 64 bytes from 172.18.0.2: icmp_seq=2 ttl=64 time=0.089 ms 64 bytes from 172.18.0.2: icmp_seq=3 ttl=64 time=0.107 ms 64 bytes from 172.18.0.2: icmp_seq=4 ttl=64 time=0.111 ms
再起動後も接続は問題なさそうです。
まとめ
上記以外にも docker inspectの内容など見てみましたが、
バージョン 1.6.0
時点では、 Compose の restart の挙動は Docker単体と特に変わりはなく、
その他依存関係や起動順などの設定とは無関係に動作するようでした。
個人的な予想ですが、おそらくバージョンUPを重ねてもこの動作に変更はないように思えます。 そもそもDocker、あるいはコンテナというものが以下の思想で作られているからです。
- 状態や複雑な依存関係は極力持たず、各サービス間が疎結合であるべき (Microservices)
- アプリケーションは壊れるものであり、修復・維持を考えるより新しく作り直す方が良い (Imuutable Infrastracture)
- 依存関係を管理せざるをえないのであれば別途Consulなど専用のサービスを使う(Service Discovery)
というわけで今回は以上です。