Docker コンテナのライフサイクル管理
docker run コマンドを使用してコンテナの作成と実行に成功した後、コンテナ化されたアプリケーションを管理するための次の重要なスキルは、それらのステータスをコントロールする方法をマスターすることです。コンテナは、他のプロセスやアプリケーションと同様に、独自のライフサイクルを持っています。それらはスタート (起動) され、ストップ (停止) され、時にはリスタート (再起動) され、まれに強制終了 (Kill) される必要があります。
これらのコマンドをマスターすることで、アプリケーションの信頼性の高い実行と効率的なリソース利用が保証され、予期せぬダウンタイムやデータロスのないスムーズなメンテナンスやアップデートが可能になります。本章では、コンテナの完全な実行ライフサイクルを管理するための基礎的なDockerコマンドを深く掘り下げ、コンテナの挙動と可用性に対するきめ細かなコントロール権限を提供します。
1. コンテナのステータスと docker ps の理解
コンテナを管理する前に、それらの現在のステータスを確認できる必要があります。docker ps コマンドは、コンテナをリストアップし、そのステータスを把握するための第一のツールです。
1.1 docker ps を使用した実行中のコンテナのリストアップ
docker ps(「process status」の略)コマンドは、デフォルトで現在実行中のコンテナのみを表示します。
docker ps例: 実行中の Nginx コンテナがある場合、出力は以下のようになります:
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
a1b2c3d4e5f6 nginx "/docker-entrypoint.…" 2 minutes ago Up 2 minutes 80/tcp my-nginx-containerカラムの意味の解説:
- CONTAINER ID (コンテナ ID): コンテナの一意の識別子。完全な ID を使用することも、最初の数文字(通常 3〜4 文字で一意性を確保できます)を使用することもできます。
- IMAGE (イメージ): このコンテナを作成するために使用された Docker イメージ(例:
nginx)。 - COMMAND (コマンド): コンテナ起動時に実行されるコマンド。
- CREATED (作成時間): コンテナがどれくらい前に作成されたか。
- STATUS (ステータス): コンテナの現在のステータス(例:
Up X minutesは X 分間実行中であることを示し、Exited (0) X minutes agoは X 分前に終了したことを示します)。 - PORTS (ポート): コンテナに設定されたすべてのポートマッピング(例:
80/tcp)。 - NAMES (名称): コンテナに割り当てられた人間が読める名称。
docker run時に--nameで指定しなかった場合、Docker はランダムな名称を自動生成します。
1.2 docker ps -a を使用したすべてのコンテナのリストアップ
すでに終了したコンテナなど、現在実行されていないコンテナを確認する必要がある場合があります。docker ps -a(または docker ps --all)コマンドは、現在のステータスに関係なく、すべてのコンテナを表示します。
docker ps -a例: 実行中の Nginx コンテナと、以前に停止した Ubuntu コンテナがある場合、出力は以下のようになります:
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
a1b2c3d4e5f6 nginx "/docker-entrypoint.…" 2 minutes ago Up 2 minutes 80/tcp my-nginx-container
g7h8i9j0k1l2 ubuntu "bash" 5 minutes ago Exited (0) 3 minutes ago my-ubuntu-boxmy-ubuntu-box コンテナの STATUS が Exited(終了)になっていることに注目してください。これは、リクエストの処理は行っていなくても、システム上にまだ存在しているコンテナを特定するために非常に重要です。
2. コンテナのスタートとストップ
コンテナの実行時間を管理することは、基本オペレーションです。docker start と docker stop は、コンテナをオンラインにし、グレースフル (Graceful) にオフラインにするための主要な手段を提供します。
2.1 docker start:停止したコンテナのウェイクアップ
コンテナが一度作成され(例:docker run を介して)、実行されなくなった(終了またはストップされた)場合、docker start を使用して再びオンラインにすることができます。このコマンドはコンテナのメインプロセスを再実行し、以前のステータスから効果的に実行を再開し、書き込み可能なレイヤー内のデータも保持されます(ボリュームが関与する場合を除き、これについては今後の章で説明します)。
構文:
docker start [オプション] コンテナ名称またはID [コンテナ名称またはID...]コンテナは CONTAINER ID または NAME で指定できます。
リアルなシナリオ例: my-api という名称のバックエンド API サービスがコンテナ内で実行されていると仮定します。このサービスがメンテナンスのためにストップされたか、クラッシュした場合、リスタートすることができます:
まず、すべてのコンテナをリストアップしてその ID または名称を見つけます:
docker ps -a
# (my-api のステータスが Exited と表示されていると仮定)該当のコンテナをスタートします:
docker start my-apiまたは ID を使用します:
docker start a1b2c3d4e5f6 # 実際の ID に置き換える再び実行されているか検証します:
docker psmy-api コンテナは現在 Up X seconds/minutes として表示されるはずです。
想定シナリオ: 夜間のバッチ処理タスクを実行する data-cruncher というデータ処理コンテナを考えてみましょう。タスクが完了すると、コンテナは終了します。翌日の夜、新しいコンテナを作成する必要はありません(それには docker run を再度実行する必要があります)。単に docker start data-cruncher を実行するだけで、次の処理サイクルを開始できます(起動時にタスクを実行するように設計されている場合)。
2.2 docker stop:グレースフルシャットダウン
docker stop コマンドは、実行中のコンテナをグレースフルにシャットダウンするために使用されます。docker stop を発行すると、Docker はコンテナのメインプロセスに SIGTERM シグナルを送信します。このシグナルは、コンテナ内で実行されているアプリケーションにグレースフルなシャットダウンを実行するように指示し、以下のことを許可します:
- 開いているファイルやメモリ内のデータを保存する。
- ネットワーク接続をクローズする。
- リソースをクリーンアップする。
- クリーンに終了 (Exit) する。
Docker はデフォルトで 10秒間、コンテナがグレースフルにストップするのを待ちます。アプリケーションがこのタイムアウト期間内に終了しない場合、Docker は次に SIGKILL シグナルを送信し、プロセスを即座に終了させます(つまり「強制 Kill」)。
構文:
docker stop [オプション] コンテナ名称またはID [コンテナ名称またはID...]オプション:
-t, --time int: コンテナを Kill する前にストップを待機する秒数(デフォルトは 10 秒)。
リアルなシナリオ例: 迅速なアップデートやトラブルシューティングのために一時的にオフラインにする必要がある Web アプリコンテナ web-app-production があるとします。
コンテナをストップする:
docker stop web-app-productionDocker は SIGTERM を送信します。web-app-production 内部のアプリケーションが適切に振る舞う場合、このシグナルをキャッチしてクリーンアップ処理を実行し、終了します。
ストップしたことを検証する:
docker psweb-app-production コンテナは、実行中のコンテナリストに表示されなくなっているはずです。
タイムアウト付きの高度な例: アプリケーションが膨大なメッセージキューを処理しているなどの理由で、グレースフルなシャットダウンにデフォルトの 10 秒以上かかる場合、タイムアウト時間を増やすことができます:
docker stop -t 30 my-message-processorこのコマンドは、Docker が SIGKILL で介入する前に、my-message-processor がグレースフルにシャットダウンするために最大 30 秒の猶予を与えます。
3. コンテナのリスタートと強制終了 (Kill)
単純なスタート/ストップ操作に加えて、docker restart と docker kill は、コンテナの管理に対してより具体的なコントロールを提供します。
3.1 docker restart:ストップしてからスタート
docker restart コマンドは、実行中のコンテナをストップし、直後に再度スタートさせるための便利な方法です。実質的に docker stop と docker start を単一の操作に組み合わせたものです。これは、適用にリスタートが必要な設定変更を行った場合や、単に不安定な状態にある可能性のあるコンテナを復旧させる場合に特に役立ちます。
構文:
docker restart [オプション] コンテナ名称またはID [コンテナ名称またはID...]オプション:
-t, --time int: コンテナを Kill する前にストップを待機する秒数(デフォルトは 10 秒)。docker stop と同様に、このタイムアウトはリスタート操作の「ストップ」フェーズに適用されます。
リアルなシナリオ例: my-nginx-container は実行中ですが、ホストマシン上の設定ファイルを更新したばかりです(このファイルはボリュームとしてコンテナにマウントされている可能性があります——この概念についてはモジュール 4 で探求します)。Nginx に新しい設定をロードさせるには、通常リスタートが必要です。
Nginx コンテナをリスタートする:
docker restart my-nginx-containerこのコマンドは Nginx をグレースフルにストップし(SIGTERM を送信)、終了するのを待ってから再びスタートさせ、新しい設定をロードさせます。
ステータスを検証する:
docker psmy-nginx-container は Up X seconds/minutes と表示されるはずです。
3.2 docker kill:強制終了
docker stop がグレースフルなシャットダウンを試みるのに対し、docker kill はコンテナに対して即時的かつ強制的な終了を実行します。コンテナのメインプロセスに SIGKILL シグナルを送信し、アプリケーションはこのシグナルをキャッチしたり無視したりすることはできません。これは物理マシンの電源プラグを引き抜くのと同じであり、保存されていないデータはすべて失われ、プロセスがクリーンアップを行う機会も与えられません。
docker kill は、docker stop が失敗した場合、または絶対的に即時終了が必要な場合(例えば、暴走したコンテナがリソースを過剰に消費し、SIGTERM に応答しない場合など)にのみ使用すべきです。
構文:
docker kill [オプション] コンテナ名称またはID [コンテナ名称またはID...]オプション:
--signal string: コンテナに送信するシグナル(デフォルトはKILL)。他のシグナルを送信することもできますが、KILL(SIGKILL) がこのコマンドの最も一般的なユースケースです。
リアルなシナリオ例: 開発コンテナ dev-env-container がフリーズして応答しなくなりました。長いタイムアウトを付けた docker stop を実行しても効果がありません。リソースを迅速に回収するために:
コンテナを強制 Kill する:
docker kill dev-env-containerこのコンテナは即座に実行を停止します。
ステータスを検証する:
docker ps -adev-env-container は現在 Exited (137) X seconds ago と表示されているはずです。終了コード 137 は通常、プロセスが SIGKILL シグナルによって Kill されたことを示します(128 + 9 は SIGKILL を表します)。
3.3 docker stop と docker kill の違い
| 特性 | docker stop | docker kill |
|---|---|---|
| 送信されるシグナル | SIGTERM (デフォルト)、タイムアウト後に SIGKILL 送信 | SIGKILL (デフォルト) |
| グレースフルシャットダウン | はい。アプリケーションのクリーンなシャットダウンを許可する | いいえ。即時終了 |
| データロスのリスク | 低い。アプリケーションがステータスを保存できる | 高い。未保存のデータが失われる可能性がある |
| ユースケース | 通常のシャットダウン、アップデート、計画的メンテナンス | 応答しないコンテナ、緊急終了 |
| タイムアウトメカニズム | Kill する前に設定可能なタイムアウト時間がある | タイムアウトなし、即時実行 |
ヒント: データの整合性と適切なリソース管理を確保するために、常に docker kill よりも docker stop の使用を優先してください。
4. 総合ハンズオンとデモンストレーション
シンプルな Nginx Web サーバーコンテナを使用して、完全なライフサイクルのデモンストレーションを実施してみましょう。
ステップ 1:Nginx コンテナを実行する
まず、バックグラウンドモード (-d) で Nginx コンテナを実行し、名称を与えます (my-webserver)。また、ホストマシンの 8080 ポートをコンテナ内の 80 ポートにマッピングします。
docker run -d --name my-webserver -p 8080:80 nginx-d: コンテナをバックグラウンドモードで実行します。--name my-webserver: コンテナにmy-webserverという名称を付けます。-p 8080:80: ホストマシンの 8080 ポートをコンテナの 80 ポートにマッピングします。nginx: 使用するイメージを指定します。
実行されていることを確認するコンテナ ID が出力されるはずです。
ステップ 2:コンテナが実行中であることを検証する
docker ps を使用して、実行中の my-webserver コンテナを確認します。
docker psまた、ブラウザで http://localhost:8080 にナビゲートしてチェックすることもできます。Nginx のウェルカムページが表示されるはずです。
ステップ 3:コンテナをストップする
それでは、my-webserver コンテナをグレースフルにストップさせましょう。
docker stop my-webserverストップコマンドが実行されたことを示す my-webserver が出力されるはずです。
ステップ 4:コンテナがストップしたことを検証する
docker ps をチェックします。my-webserver はリストに表示されなくなっているはずです。
docker psコンテナが削除されたわけではなく、単にストップしているだけであることを確認するために、docker ps -a を使用します。
docker ps -amy-webserver コンテナは現在 Exited (0) X seconds ago と表示されるはずです。ブラウザで http://localhost:8080 にアクセスしようとしても、アクセスできないはずです。
ステップ 5:コンテナをスタートする
my-webserver を再びオンラインに戻しましょう。
docker start my-webservermy-webserver が出力されるはずです。
ステップ 6:コンテナが再び実行されたことを検証する
docker ps をチェックし、ブラウザで http://localhost:8080 をリロードします。コンテナが実行されており、再びアクセス可能になっているはずです。
docker psステップ 7:コンテナをリスタートする
次に、docker restart を使用します。これにより、Web サーバーが一時的にシャットダウンされ、再び起動します。
docker restart my-webserverステップ 8:リスタート後のコンテナの実行ステータスを検証する
docker ps を使用し、ブラウザをリロードして確認します。
docker psステップ 9:docker kill を体験する
このために、シンプルな Ubuntu コンテナを使用して sleep 300(300 秒間のスリープ)のような長いタスクを実行させましょう。これにより、突然の終了をデモンストレーションできます。
まず、Ubuntu コンテナを実行します:
docker run -d --name my-sleeper ubuntu sleep 300実行を検証します:
docker psそれでは、強制 Kill します:
docker kill my-sleeperストップしたことを検証し、その終了ステータスをチェックします:
docker ps -amy-sleeper コンテナは Exited (137) X seconds ago と表示されるはずです。これは、コンテナが Kill されたことを裏付けています。
ステップ 10:クリーンアップ
不要になったコンテナは削除するのが良い習慣です(今後の章で docker rm について詳しく解説します):
docker rm my-webserver
docker rm my-sleeperこれらのコマンドは、ストップしたコンテナを削除します。-f (強制) フラグを追加しない限り、実行中のコンテナを削除することはできません。実行中のコンテナの削除は暗黙的に先にコンテナを Kill することになるため、通常は推奨されていません。