Edited at

なぜdocker stopは時間がかかるんですか?その理由と解決方法

More than 3 years have passed since last update.

docker stopってどうして時間がかかるのだろう??と疑問に思ったことはありませんか。

その理由は、Linuxではpid=1のプロセスはとても特別な扱いをうけるので簡単にkillできないという性質があるにもかかわらず、docker runでコンテナ上で実行されるコマンドはpidが1だからです。そういった問題を解決するのがdumb-initであったり、tiniであったりするわけです。

ということで、試しにdumb-initで本当に問題が解決されるか検証してみましょう。


テスト用のDockerマシンを準備する

すでにテスト用の環境がある方はスキップして次に進んで下さい。

$ docker-machine create --driver virtualbox node1

$ eval $(docker-machine env node1)


dumb-initをインストールするDockerfileを準備する

下記の通りapache2とdumb-initをインストールするDockerfileを準備します。

FROM ubuntu:14.04

RUN apt-get update && \
apt-get -y install apache2 python-pip && \
apt-get clean && \
pip install dumb-init

このDockerfileをdumb-initという名前でビルドします。

$ docker build -t dumb-init .

これで準備できました。それでは計ってみましょう。


dumb-initを使わない場合のdocker stopの時間を計ってみる

## dumb-initなしでapache2をスタートします

$ docker run -p 80:80 --name without-dumb-init -dt dumb-init /usr/sbin/apache2ctl -D FOREGROUND

## ストップしてみます
$ time docker stop without-dumb-init

real 0m10.130s
user 0m0.033s
sys 0m0.013s

10秒かかりました。仮にこのコンテナが6つあった場合はすべてストップするのに1分もかかることになります。


dumb-initを使った場合のdocker stopを計ってみる

## dumb-initありでapache2をスタートします

$ docker run -p 80:80 --name with-dumb-init -dt dumb-init /usr/local/bin/dumb-init /usr/sbin/apache2ctl -D FOREGROUND

## ストップしてみます
$ time docker stop with-dumb-init

real 0m0.127s
user 0m0.030s
sys 0m0.011s

一目瞭然ですね。コンテナは軽量で速いことが利点なので、今後はなるべくdump-initやtiniを使うようにしましょう。


NOTE: 一応参考までにですが、この問題はdockerのissueでも見かけるので、そのうち解決されるかもしれませんね。



片付ける

docker rm with-dumb-init without-dumb-init

docker-machine rm node1


もう少し詳しく知りたい人へ

dumb-initを開発したYelpのChris Kuehlさんのブログ"Introducing dumb-init, an init system for Docker containers"を読んでみることをお勧めします。とても勉強になります。