Dockerコンテナの停止と終了方法
この記事では、Dockerコンテナの停止と終了に関する7つのポイントを説明します。
pause
コマンドとstop
コマンド、完全に停止してシャットダウンする方法、
停止とシャットダウンを強制する方法、停止したコンテナを一括削除する方法、 signal
と timeout
オプション、そして `permission denied' の解決方法です。
1. Dockerコンテナ停止コマンド
実行中のDockerコンテナを停止または終了させるコマンドの基本形は以下の通りである。
docker container stop [OPTIONS] CONTAINER [CONTAINER...].
DockerコンテナはUnixプロセスベースなので、このコマンドは対応するDockerコンテナにSIGTERM
シグナルを送ることで、コンテナの実行を停止する時間を与えます。
. そして SIGKILL
シグナルを送ることで、そのプロセスを終了させる。
SIGTERM
シグナルはプロセスが安全に終了するのを待ってから kill することを伝えます。
SIGKILL は他のオペレーティングシステムでいう強制シャットダウンに相当します。
ここで、CONTAINER
は停止したいコンテナの名前または ID である。
このコマンドでは、1つまたは複数のコンテナを一らせるができる。
[OPTIONS]
には、--time` オプションなど、好きなオプションを追らせるる。
よく使うオプションは以下のセクションで説明する。
stop
コマンドで停止したコンテナは、start
コマンドで再起動することができる。
コマンドは以下のとおりで、-a
や -i
など、Docker Containers の実行の投稿で見たオプションを追加することができる。
$ docker container start [OPTIONS] CONTAINER [CONTAINER...].
実行中の `nginx' コンテナをシャットダウンして再起動する簡単な例を見てみよう。
まず、(1) このコンテナの名前または ID を調べて、(2) stop
コマンドを実行する。
(3) 停止したコンテナは、--all
オプションを指定しないと ls
クエリで検索されないことに注意する。
次に、(4) start
コマンドでコンテナを再起動し、(5) 検証する。
$ docker container ls # (1)
container id image command
6f3e40d12122 nginx "/docker-entrypoint...."
$ docker container stop 6f3e # (2)
6f3e
$ docker container ls # (3)
$ docker container start 6f3e # (4)
6f3e
$ docker container ls # (5)
container id image command
6f3e40d12122 nginx "/docker-entrypoint...."
2. Dockerコンテナの一時停止コマンド
時には、実行中のコンテナを一時停止する必要があるかもしれない。 これは通常、システムリソースが限られており、リソースが不足している場合に行われる。 Dockerコンテナを一時停止すると、そのコンテナに割り当てられていたリソースを一時的に返します。
コンテナを一時停止するコマンドは以下の通り:
docker container pause [OPTIONS] CONTAINER [CONTAINER...]
これは Section 1 で見た stop
コマンドに似ています。
上記のコマンドを実行すると、Docker デーモンは対応するコンテナに `SIGSTOP' シグナルを送信し、コンテナのプロセスを一時的に停止します。
一時停止したコンテナを再開するには、以下のコマンドを実行する。
docker container unpause CONTAINER [CONTAINER...] $ docker container unpause CONTAINER [CONTAINER...
このコマンドは一時停止しているDockerコンテナにSIGCONT
シグナルを送り、作業を再開させる。
以下はその例である。
$ docker container ls # check container ID
container id image ... status
6f3e40d12122 nginx ... Up 11 seconds
$ docker container pause 6f32 # Pause the container
6f3e
$ docker container ls # Verify container pause
container id image ... status
6f3e40d12122 nginx ... Up 26 seconds (Paused)
$ docker container unpause 6f3e # Restart the container
6f3e
$ docker container ls # Confirm container redo
6f3eCONTAINER ID IMAGE ... STATUS
6f3e40d12122 nginx ... Up 44 seconds
Paused
状態のコンテナは docker container ls
コマンドで問い合わせることができる、
STATUS
エントリには (Paused)
と表示される。
この状態で unpause
コマンドを実行すると、再びコンテナが実行されます。
3. 全てのDockerコンテナの停止と終了
Dockerには、全てのコンテナを一括で停止・強制終了するオプションは用意されていない。 しかし、以下のように2つのdockerコマンドを一緒に使うことで、すべてのコンテナを停止することができます。
$ docker container stop $(docker container ls -aq)
ここで使用した docker container ls
コマンドの -a
オプションは --all
オプションで、すべての状態のコンテナを尋ねる、
-q
オプションは --quiet
オプションで、コンテナの ID だけを表示する。
この ID のリストは、シェルスクリプトの構文 $()
を使って stop
コマンドの引数として渡される。
実際には次のようになる。
$ docker container ls -aq # check target container IDs
6f3e40d12122
7d392cc25008
$ docker container stop $(docker container ls -aq) # Stop the entire container
6f3e40d12122
7d392cc25008
$ docker container ls # Confirm full container stop
container id image command
これはすべてのコンテナを停止する簡単な方法だが、実行すべきでないコンテナを予期せず停止してしまうことがある。 そのため、注意して使用すること。
4. コンテナ停止後のコマンド削除
Dockerがコマンド構造を再編成した際、コンテナのkillと削除を同時に行う機能が削除された。 そのため、以下の2つのコマンドを背中合わせに使うのがベストだ。
$ docker container stop [container-id]
$ docker container rm [container-id]
停止したDockerコンテナを削除するには、`docker container rm' コマンドを使用する、 詳細はコンテナ削除の投稿を参照。
ただし、どうしても1つのコマンドだけで行いたい場合は
Dockerのレガシーコマンドであるdocker rm
コマンドの--force
オプションを使うことができる。
$ docker rm -f [container-id]
このコマンドは、即座にそのコンテナに SIGKILL
シグナルを送り、強制的にシャットダウンさせる。
コンテナを削除すると、そのコンテナ内のすべてのデータも削除されることを忘れないように。
5. killコマンドと-signalオプションを使ってコンテナを強制終了する
コンテナを停止して終了させる場合、docker container stop
コマンドは常に最初の選択肢となる。
しかし、コンテナが応答しない状態であったり、不正なイメージで作成されて操作が困難であったりする場合は、強制シャットダウンが必要になる。
Dockerはコンテナを強制終了するコマンドを別に用意している。
これが kill
コマンドである。
$ docker container kill [OPTIONS] CONTAINER [CONTAINER...]
このコマンドは1つ以上のコンテナに SIGKILL
シグナルを送り、即座にコンテナを kill する。
SIGKILL
以外のシグナルを送りたい場合は、--signal
オプションで指定することができる。
しかし、kill
の場合、プロセスは既に他のシグナルを無視しているので、異なるレスポンスを期待するのは妥当ではないと思う。
もし kill
コマンドを使用すると、即座にシャットダウンせざるを得なくなり、予期せぬデータ損失などが発生する可能性があります。
従って、バックアップを取るか、その準備をしておくべきです。
6. コンテナ停止タイムアウトの設定
セクション1で、docker container stop
コマンドを実行すると、コンテナが SIGTERM'
シグナルを送るのを待ち、プロセスを安全に停止させることができると述べました。
dockerが待機する時間のデフォルト値は10秒に設定されています。
10秒はそれほど長い時間ではないが、コンテナをシャットダウンするプロセスが10秒以上かかるほど複雑な場合、Dockerは SIGKILL
シグナルでコンテナを強制終了する。
これは予期せぬデータ損失などにつながる可能性がある。
そのため、もう少し時間をかけてもいい場合もあるはずだ。
stop
コマンドの --time
オプションはまさにそれを行う。
$ docker container stop -t 30 my_container
上記のようなコマンドを実行した場合、コンテナにはシャットダウン処理を完了する30秒間の猶予があり、その後強制的にシャットダウンされる。
7. パーミッションが拒否された場合の対処法
コンテナのシャットダウン中に permission denied
というエラーメッセージに遭遇することがある。
メッセージにあるように、これは現在のユーザーがDockerコンテナを操作するのに十分なパーミッションを持っていないために起こります。
Dockerはデフォルトでroot
または管理者権限を必要とする。
ホームユーザーであれば自由に権限を設定できますが、企業環境や共同作業をしている場合は、権限が高く設定されていない可能性があります。
これは、docker コマンドを root
として実行するか、ホストユーザー以外でも docker を使用できるようにする docker
グループに参加することで解決できます。
7.1. sudo キーワードの使用
root
権限を使うのは簡単です。以下のように sudo
キーワードを併用する。
ホストアカウントのパスワードを知っておく必要がある。
$ sudo docker container stop [container-id]
7.2. docker ユーザーグループへの追加
すべてのコマンドで sudo
キーワードを使うことなく、現在のユーザーに docker 権限を付与する方法を紹介します。
以下のコマンドを実行してログアウトし、現在のユーザーでログインすると、グループ設定が適用されます。
$ sudo usermod -aG docker $USER
上記のコマンドは、現在ログインしているユーザー($USER
)を docker
というグループに追加する(-aG
: append Group)、
(usermod
:ユーザーを変更する)。
また、この方法では sudo
コマンドのパスワードが必要になる。
以上がDockerのパーミッションを取得し、permission denied
の問題を解決する2つの方法です。
8. 最後に
この投稿では、Dockerコンテナを停止、一時停止、強制終了、停止、削除する方法、強制終了、timeout
の設定、パーミッションの問題のトラブルシューティングについて説明した、
と権限問題のトラブルシューティングについて説明した。
これが実際の開発プロセスに役立つことを願っています。
