長時間実行される Docker コンテナを適切にシャットダウンする方法

DockerDockerBeginner
今すぐ練習

💡 このチュートリアルは英語版からAIによって翻訳されています。原文を確認するには、 ここをクリックしてください

はじめに

Dockerコンテナは、様々なアプリケーションやサービスを実行するために広く使用されていますが、長時間実行されるコンテナのライフサイクルを管理することは難しい場合があります。このチュートリアルでは、長時間実行されるDockerコンテナを適切にシャットダウンするプロセスを案内し、スムーズな移行を確保し、潜在的なデータ損失やアプリケーションの問題を防ぎます。


Skills Graph

%%%%{init: {'theme':'neutral'}}%%%% flowchart RL docker(("Docker")) -.-> docker/ContainerOperationsGroup(["Container Operations"]) docker/ContainerOperationsGroup -.-> docker/start("Start Container") docker/ContainerOperationsGroup -.-> docker/stop("Stop Container") docker/ContainerOperationsGroup -.-> docker/restart("Restart Container") docker/ContainerOperationsGroup -.-> docker/logs("View Container Logs") docker/ContainerOperationsGroup -.-> docker/inspect("Inspect Container") subgraph Lab Skills docker/start -.-> lab-417742{{"長時間実行される Docker コンテナを適切にシャットダウンする方法"}} docker/stop -.-> lab-417742{{"長時間実行される Docker コンテナを適切にシャットダウンする方法"}} docker/restart -.-> lab-417742{{"長時間実行される Docker コンテナを適切にシャットダウンする方法"}} docker/logs -.-> lab-417742{{"長時間実行される Docker コンテナを適切にシャットダウンする方法"}} docker/inspect -.-> lab-417742{{"長時間実行される Docker コンテナを適切にシャットダウンする方法"}} end

Dockerコンテナのライフサイクルの理解

開発者がアプリケーションを効果的に管理するためには、Dockerコンテナの明確に定義されたライフサイクルを理解する必要があります。このセクションでは、Dockerコンテナのライフサイクルの概要を説明します。これには、コンテナが遷移するさまざまな状態と、このライフサイクルの基礎となる主要な概念が含まれます。

Dockerコンテナの状態

Dockerコンテナは、そのライフタイム中にいくつかの異なる状態で存在することができます。

  1. Created(作成済み): コンテナが作成されたが、まだ起動されていない状態です。
  2. Running(実行中): コンテナが現在、メインプロセスを実行している状態です。
  3. Paused(一時停止中): コンテナのメインプロセスが一時停止されているが、コンテナはまだ実行中です。
  4. Stopped(停止済み): コンテナのメインプロセスが停止されている状態です。
  5. Restarting(再起動中): コンテナが現在、再起動中です。
  6. Exited(終了済み): コンテナが停止し、メインプロセスが終了している状態です。

これらの状態を理解することは重要です。なぜなら、これらの状態によって、コンテナに対して実行できるアクションと期待できる動作が決まるからです。

graph LR Created --> Running Running --> Paused Paused --> Running Running --> Stopped Stopped --> Running Stopped --> Exited

Dockerコンテナのライフサイクルイベント

コンテナの状態に加えて、Dockerコンテナのライフサイクル中にいくつかの重要なイベントが発生します。

  1. Create(作成): 新しいコンテナが作成されます。
  2. Start(起動): コンテナのメインプロセスが起動されます。
  3. Stop(停止): コンテナのメインプロセスが停止されます。
  4. Restart(再起動): コンテナが手動または自動で再起動されます。
  5. Pause/Unpause(一時停止/再開): コンテナのメインプロセスが一時停止または再開されます。
  6. Kill(強制終了): コンテナのメインプロセスが強制的に終了されます。
  7. Delete(削除): コンテナがシステムから削除されます。

これらのライフサイクルイベントを理解することは、Dockerコンテナの動作を管理および自動化するために不可欠です。

Docker CLIを使用したコンテナのライフサイクルの管理

Docker CLIは、コンテナのライフサイクルとやり取りするためのいくつかのコマンドを提供しています。

  • docker create: 新しいコンテナを作成します。
  • docker start: 停止しているコンテナを起動します。
  • docker stop: 実行中のコンテナを停止します。
  • docker restart: コンテナを再起動します。
  • docker pause: 実行中のコンテナを一時停止します。
  • docker unpause: 一時停止しているコンテナを再開します。
  • docker kill: 実行中のコンテナを強制的に停止します。
  • docker rm: コンテナを削除します。

これらのコマンドを使用すると、Dockerコンテナのライフサイクルをプログラムで管理し、コンテナ管理に関連するさまざまなタスクを自動化することができます。

長時間実行されるコンテナを適切に停止する

長時間実行されるDockerコンテナを扱う際には、コンテナが適切に停止されるようにすることが重要です。つまり、コンテナが終了する前に、コンテナのメインプロセスが必要なクリーンアップやシャットダウンタスクを実行できるようにする必要があります。このセクションでは、長時間実行されるDockerコンテナを適切に停止するための戦略を探ります。

SIGTERMシグナルの理解

Dockerコンテナを適切に停止するための主なメカニズムは、コンテナのメインプロセスにSIGTERMシグナルを送信することです。このシグナルは、プロセスにシャットダウンプロセスを開始し、必要なクリーンアップタスクを実行するよう通知します。

デフォルトでは、docker stopコマンドを実行すると、DockerはコンテナのメインプロセスにSIGTERMシグナルを送信し、プロセスが終了するまでデフォルトのタイムアウト期間(通常は10秒)待機します。タイムアウト期間内にプロセスが終了しない場合、DockerはSIGKILLシグナルを送信し、プロセスを強制的に終了させます。

シャットダウン動作のカスタマイズ

長時間実行されるDockerコンテナのシャットダウン動作をカスタマイズするには、以下のオプションを使用できます。

  1. --stop-signal: docker stopコマンド実行時に、コンテナのメインプロセスに送信する代替シグナルを指定します。例えば、--stop-signal=SIGINTとすると、デフォルトのSIGTERMではなくSIGINTシグナルが送信されます。

  2. --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開発者や管理者にとって重要なスキルです。