はじめに
Dockerコンテナは、様々なアプリケーションやサービスを実行するために広く使用されていますが、長時間実行されるコンテナのライフサイクルを管理することは難しい場合があります。このチュートリアルでは、長時間実行されるDockerコンテナを適切にシャットダウンするプロセスを案内し、スムーズな移行を確保し、潜在的なデータ損失やアプリケーションの問題を防ぎます。
💡 このチュートリアルは英語版からAIによって翻訳されています。原文を確認するには、 ここをクリックしてください
Dockerコンテナは、様々なアプリケーションやサービスを実行するために広く使用されていますが、長時間実行されるコンテナのライフサイクルを管理することは難しい場合があります。このチュートリアルでは、長時間実行されるDockerコンテナを適切にシャットダウンするプロセスを案内し、スムーズな移行を確保し、潜在的なデータ損失やアプリケーションの問題を防ぎます。
開発者がアプリケーションを効果的に管理するためには、Dockerコンテナの明確に定義されたライフサイクルを理解する必要があります。このセクションでは、Dockerコンテナのライフサイクルの概要を説明します。これには、コンテナが遷移するさまざまな状態と、このライフサイクルの基礎となる主要な概念が含まれます。
Dockerコンテナは、そのライフタイム中にいくつかの異なる状態で存在することができます。
これらの状態を理解することは重要です。なぜなら、これらの状態によって、コンテナに対して実行できるアクションと期待できる動作が決まるからです。
コンテナの状態に加えて、Dockerコンテナのライフサイクル中にいくつかの重要なイベントが発生します。
これらのライフサイクルイベントを理解することは、Dockerコンテナの動作を管理および自動化するために不可欠です。
Docker CLIは、コンテナのライフサイクルとやり取りするためのいくつかのコマンドを提供しています。
docker create
: 新しいコンテナを作成します。docker start
: 停止しているコンテナを起動します。docker stop
: 実行中のコンテナを停止します。docker restart
: コンテナを再起動します。docker pause
: 実行中のコンテナを一時停止します。docker unpause
: 一時停止しているコンテナを再開します。docker kill
: 実行中のコンテナを強制的に停止します。docker rm
: コンテナを削除します。これらのコマンドを使用すると、Dockerコンテナのライフサイクルをプログラムで管理し、コンテナ管理に関連するさまざまなタスクを自動化することができます。
長時間実行されるDockerコンテナを扱う際には、コンテナが適切に停止されるようにすることが重要です。つまり、コンテナが終了する前に、コンテナのメインプロセスが必要なクリーンアップやシャットダウンタスクを実行できるようにする必要があります。このセクションでは、長時間実行されるDockerコンテナを適切に停止するための戦略を探ります。
Dockerコンテナを適切に停止するための主なメカニズムは、コンテナのメインプロセスにSIGTERM
シグナルを送信することです。このシグナルは、プロセスにシャットダウンプロセスを開始し、必要なクリーンアップタスクを実行するよう通知します。
デフォルトでは、docker stop
コマンドを実行すると、DockerはコンテナのメインプロセスにSIGTERM
シグナルを送信し、プロセスが終了するまでデフォルトのタイムアウト期間(通常は10秒)待機します。タイムアウト期間内にプロセスが終了しない場合、DockerはSIGKILL
シグナルを送信し、プロセスを強制的に終了させます。
長時間実行されるDockerコンテナのシャットダウン動作をカスタマイズするには、以下のオプションを使用できます。
--stop-signal
: docker stop
コマンド実行時に、コンテナのメインプロセスに送信する代替シグナルを指定します。例えば、--stop-signal=SIGINT
とすると、デフォルトのSIGTERM
ではなくSIGINT
シグナルが送信されます。
--stop-timeout
: SIGKILL
シグナルを送信する前に、コンテナのメインプロセスが終了するのを待つ秒数を指定します。例えば、--stop-timeout=30
とすると、プロセスが強制終了される前に30秒間終了するのを待ちます。
以下は、長時間実行されるコンテナを起動する際にこれらのオプションを使用する例です。
docker run -d --name my-app --stop-signal=SIGINT --stop-timeout=60 my-app:latest
このコマンドは、my-app
という名前の長時間実行されるコンテナを起動します。docker stop
コマンドが発行されると、コンテナのメインプロセスにSIGINT
シグナルが送信され、SIGKILL
シグナルを送信する前に最大60秒間終了するのを待ちます。
長時間実行されるDockerコンテナが適切に停止されるようにするには、アプリケーションを設計してSIGTERM
(または代替)シグナルを処理し、終了する前に必要なクリーンアップタスクを実行するようにすることが重要です。これには以下のようなタスクが含まれる場合があります。
アプリケーションでこのシグナルハンドリングを実装することで、コンテナを制御された予測可能な方法で停止させ、データ損失やその他の問題のリスクを最小限に抑えることができます。
長時間実行されるDockerコンテナを適切にシャットダウンするには、スムーズで制御可能なシャットダウンプロセスを確保するためのいくつかの戦略を採用できます。このセクションでは、適切なシャットダウンのための主要な戦略とベストプラクティスのいくつかを探ります。
適切なシャットダウンのための最も重要な戦略の1つは、アプリケーションでシグナルハンドリングを実装することです。これには、SIGTERM
(または代替)シグナルを待ち受け、アプリケーションが終了する前に必要なクリーンアップタスクを実行するコードを記述することが含まれます。
以下は、Node.jsアプリケーションでシグナルハンドリングを実装する方法の例です。
process.on("SIGTERM", () => {
console.log("Received SIGTERM signal, starting graceful shutdown...");
// Perform cleanup tasks, such as:
// - Saving in-memory data to persistent storage
// - Closing network connections or database connections
// - Flushing logs or other output
// - Performing any other application-specific cleanup tasks
console.log("Graceful shutdown complete, exiting process.");
process.exit(0);
});
このシグナルハンドリングを実装することで、アプリケーションは制御されたシャットダウンを実行し、データ損失やその他の問題のリスクを最小限に抑えることができます。
適切なシャットダウンのもう1つの戦略は、Dockerの組み込みのヘルスチェックと生存プローブ機能を使用することです。これらの機能を使用すると、Dockerがコンテナの健全性と準備状態を判断するために使用できるチェックを定義できます。
シャットダウンプロセス中に、これらのプローブを使用して、コンテナがシャットダウン中であることをDockerに通知し、コンテナを削除する前にシャットダウンが完了するのを待機させることができます。
以下は、Dockerコンテナでヘルスチェックと生存プローブを構成する方法の例です。
## Dockerfile
FROM node:14-alpine
COPY. /app
WORKDIR /app
CMD ["node", "server.js"]
HEALTHCHECK --interval=5s --timeout=3s \
CMD curl -f http://localhost:3000/healthz || exit 1
LABEL com.labex.shutdown.signal=SIGINT
LABEL com.labex.shutdown.timeout=60
この例では、HEALTHCHECK
命令は、コンテナのWebサーバーの/healthz
エンドポイントをチェックするヘルスチェックを定義しています。LABEL
命令は、適切なシャットダウンに使用するシグナル (SIGINT
) とタイムアウト期間 (60秒) を定義しています。
シャットダウンプロセス中に、アプリケーションはヘルスチェックエンドポイントを更新して、シャットダウンが進行中であることを通知し、コンテナを削除する前にシャットダウンが完了するのをDockerに待機させることができます。
KubernetesやDocker SwarmなどのオーケストレーションフレームワークでDockerコンテナを実行している場合、これらのフレームワークの組み込み機能を活用して適切なシャットダウンを支援できます。
たとえば、Kubernetesでは、preStop
フックを使用して、コンテナが終了する前にクリーンアップタスクを実行するコマンドまたはスクリプトを実行できます。また、terminationGracePeriodSeconds
フィールドを使用して、コンテナが適切にシャットダウンするために与えられる時間を指定できます。
以下は、preStop
フックと適切な終了期間を設定したKubernetesデプロイメントを構成する方法の例です。
## kubernetes-deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: my-app
spec:
replicas: 3
selector:
matchLabels:
app: my-app
template:
metadata:
labels:
app: my-app
spec:
containers:
- name: my-app
image: my-app:latest
ports:
- containerPort: 3000
lifecycle:
preStop:
exec:
command: ["/app/shutdown.sh"]
terminationGracePeriodSeconds: 60
この例では、preStop
フックは、コンテナが終了する前に必要なクリーンアップタスクを実行するスクリプト (/app/shutdown.sh
) を実行します。terminationGracePeriodSeconds
フィールドは、コンテナが強制終了される前に60秒間適切にシャットダウンする時間を与えます。
これらのオーケストレーションフレームワークの機能を活用することで、コンテナのシャットダウンプロセスの信頼性と予測可能性をさらに向上させることができます。
このチュートリアルでは、Dockerコンテナのライフサイクルを理解することの重要性と、長時間実行されるコンテナを適切にシャットダウンするための戦略を学びました。概説されたベストプラクティスに従うことで、スムーズで信頼性の高いシャットダウンプロセスを確保し、データ損失やアプリケーションの中断のリスクを最小限に抑えることができます。適切なコンテナのシャットダウンの技術を習得することは、すべてのDocker開発者や管理者にとって重要なスキルです。