技術備忘記

日々調べたこととかとりとめなく

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)

というわけで今回は以上です。