Pod

このページでは、Kubernetes の Pod オブジェクトと Google Kubernetes Engine での Pod の使用方法について説明します。

Pod とは

Pod は、Kubernetes でデプロイできる最小かつ最も基本的なオブジェクトです。Pod は、クラスタ内で実行されるプロセスの単一インスタンスを表します。

Pod には、Docker コンテナなどのコンテナが 1 つ以上含まれています。Pod で複数のコンテナが実行される場合、コンテナは単一のエンティティとして管理され、Pod のリソースを共有します。一般に、単一の Pod で複数のコンテナを実行することは、高度な使用例です。

Pod には、Pod 内のコンテナが共有するネットワークとストレージのリソースも含まれています。

  • ネットワーク: Pod には一意の IP アドレスが自動的に割り当てられます。Pod コンテナは、IP アドレスとネットワーク ポートを含む同じネットワーク名前空間を共有します。Pod 内のコンテナは、Pod 内で localhost を使用して互いに通信します。
  • ストレージ: Pod では、コンテナ間で共有できる共有ストレージ ボリュームのセットを指定できます。

Pod は、ホストするアプリケーション向けのシステム上のニーズを組み込んだ自己完結型の独立した「論理ホスト」のようなものです。

各 Pod は、クラスタ上でアプリケーションの単一インスタンスを実行するためのものです。しかし、個々の Pod を直接作成することは推奨されません。代わりに、通常は、「レプリカ」と呼ばれる同一の Pod からなるセットを作成して、アプリケーションを実行します。このような複製 Pod のセットは、Deployment などの「コントローラ」によって作成され、管理されます。コントローラは、構成要素となる Pod のライフサイクルを管理するほか、「水平スケーリング」を実行して、必要に応じて Pod の数を変更することもできます。

Pod をデバッグ、トラブルシューティング、または検査するために Pod を直接操作することもありますが、コントローラを使用して Pod を管理することを強くおすすめします。

Pod は、クラスタ内のノードで実行されます。作成された Pod は、プロセスが完了するか、Pod が削除されるか、リソース不足のために Pod がノードから強制排除されるか、ノードに障害が発生するまで、ノードに存在し続けます。ノードに障害が発生すると、ノード上の Pod は自動的に削除するようにスケジュールされます。

Pod のライフサイクル

Pod は一時的なものです。Pod は永続的に動作するように設計されておらず、終了した Pod を元に戻すことはできません。一般に、ユーザーまたはコントローラによって削除されるまで、Pod がなくなることはありません。

Pod は自身を修復しません。たとえば、Pod がスケジュールされたノードでその後障害が発生した場合、Pod は削除されます。同様に、なんらかの理由で Pod がノードから強制排除された場合、Pod は自身を置き換えません。

各 Pod には 1 つの PodStatus API オブジェクトがあり、Pod の status フィールドでそれが表されます。Pod は status: phase フィールドに自身の「フェーズ」を公開します。Pod のフェーズは、Pod の現在の状態の概要です。

クラスタ上で実行されている Pod を検査するために kubectl get pod を実行すると、次のいずれかのフェーズが返されます。

  • Pending(保留中): Pod がすでに作成され、クラスタによって受け入れられましたが、Pod の 1 つ以上のコンテナがまだ実行されていません。このフェーズには、ノードでのスケジューリングとイメージのダウンロードにかかる時間が含まれます。
  • Running(実行中): Pod がノードにバインドされ、すべてのコンテナが作成されました。少なくとも 1 つのコンテナが実行中、起動中、または再起動中です。
  • Succeeded(成功): Pod 内のすべてのコンテナが正常に終了しました。終了した Pod は再起動しません。
  • Failed(失敗): Pod 内のすべてのコンテナが終了し、少なくとも 1 つのコンテナが失敗状態で終了しました。コンテナは、ゼロ以外のステータスで終了した場合に「失敗」となります。
  • Unknown(不明): Pod の状態を特定できません。

また、PodStatus には PodConditions という配列が含まれており、これは Pod のマニフェストで conditions として表されます。このフィールドには type および status フィールドが含まれています。conditions は、現在のステータスの原因となった Pod 内の状況をより具体的に示します。

type フィールドには、PodScheduledReadyInitializedUnschedulable が含まれる可能性があります。status フィールドは、type フィールドに対応しており、TrueFalse、または Unknown が含まれる可能性があります。

Pod を作成する

Pod は一時的なものですから、Pod を直接作成する必要はありません。同様に、Pod は自身を修理したり置き換えたりできないので、Pod を直接作成することは推奨されません。

代わりに、Deployment などのコントローラを使用して自動的に Pod を作成し、管理できます。コントローラは、更新プロセス全体を自動的に管理するため、更新をロールアウトする場合(コンテナ内で実行されるアプリケーションのバージョンを変更する場合など)にも役立ちます。

Pod リクエスト

Pod が実行を開始すると、CPU とメモリがリクエストされます。これにより、Kubernetes は適切なノードに Pod をスケジュールしてワークロードを実行できるようになります。Pod は、Pod のリクエストに対応できるリソースがないノードではスケジュールされません。リクエストされるのは、Kubernetes が Pod に対して保証する CPU またはメモリの最小量です。

アプリケーションに必要なリソースに基づいて、Pod の CPU とメモリのリクエストを構成できます。Pod 内で実行される個々のコンテナに対して、リクエストを指定することもできます。以下の点にご注意ください。

  • CPU に関するデフォルトのリクエストは、100m です。これは、ほとんどのアプリケーションにとっては少なく、ノードで使用可能な CPU の数値よりもはるかに小さい値です。
  • メモリに関しては、デフォルトのリクエストはありません。デフォルトのメモリ リクエストがない Pod は、Pod のワークロードを実行できる十分なメモリがないノード上でもスケジュール可能です。
  • CPU リクエストやメモリ リクエストの値が小さすぎると、多すぎる Pod や、不十分な組み合わせの Pod が特定のノード上でスケジュールされ、パフォーマンスが低下する可能性があります。
  • CPU リクエストやメモリ リクエストの値が大きすぎると、Pod がスケジューリング不能になり、クラスタのリソースのコストが増加する可能性があります。
  • Pod にリソースを設定せずに(もしくは Pod のリソース設定に加えて)、Pod 内で実行される個々のコンテナにリソースを指定することもできます。コンテナにのみリソースを指定する場合、Pod のリクエストは、各コンテナに指定されたリクエストの合計になります。両方を指定する場合は、すべてのコンテナのリクエストの合計が、Pod リクエストを超えないようにする必要があります。

実際のワークロードの要件に基づいて、Pod リクエストの構成を行うことを強くおすすめします。詳細については、Google Cloud ブログの Kubernetes のベスト プラクティス: リソース リクエストと制限をご覧ください。

Pod の制限

デフォルトでは、ノードで使用できる CPU またはメモリの最大値に上限はありませんが、Pod がノードで使用できる CPU またはメモリの量に制限をかけることができます。制限とは、Kubernetes が Pod に対して保証する CPU またはメモリの最大量を意味します。

また、Pod の制限を設定せずに(もしくは Pod の制限に加えて)、Pod 内で実行される個々のコンテナに制限をかけることもできます。コンテナにのみ制限をかける場合、Pod の制限は、各コンテナにかけられた制限の合計になります。ただし、各コンテナはその制限の最大値までしかリソースにアクセスできないので、コンテナだけに制限をかける場合は、各コンテナの制限を指定する必要があります。両方を指定した場合は、すべてのコンテナの上限の合計が Pod 制限を超えないようにする必要があります。

Pod のスケジューリングの際には制限が考慮されませんが、制限をかけることで、同じノード上の Pod 間でのリソース競合を防ぐことができます。また、リソースの基盤となるオペレーティング システムを Pod が枯渇させてノードのシステムが不安定になることを防げます。

実際のワークロードの要件に基づいて、Pod の制限を構成することを強くおすすめします。詳細については、Google Cloud ブログの Kubernetes のベスト プラクティス: リソース リクエストと制限をご覧ください。

Pod テンプレート

Deployment や StatefulSet などのコントローラ オブジェクトには、Pod テンプレート フィールドが含まれています。Pod テンプレートには、Pod 内でどのコンテナを実行するか、Pod でどのボリュームをマウントするかなど、各 Pod の実行方法を決定する Pod 仕様が含まれます。

コントローラ オブジェクトは、Pod テンプレートを使用して Pod を作成し、クラスタ内の「目的の状態」を管理します。Pod テンプレートが変更されると、新しいテンプレートはその後のすべての Pod に反映されますが、既存の Pod には反映されません。

詳しくは、Kubernetes ドキュメントの Deployment の作成をご覧ください。

Pod がどのノードで実行されるかを制御する

デフォルトでは、Pod はクラスタのデフォルト ノードプール内のノードで実行されます。次のようにして、Pod が選択するノードプールを明示的または暗黙的に構成できます。

  • Pod マニフェストで nodeSelector を設定すると、その Pod を特定のノードプールにデプロイするよう明示的に指定できます。こうすることで、Pod はそのノードプール内のノードでのみ実行されるようになります。

  • 実行するコンテナに関するリソース リクエストを指定できます。Pod は、リソース リクエストを満たすノードでのみ実行されます。たとえば、Pod 定義に 4 つの CPU を必要とするコンテナが含まれている場合、サービスは 2 つの CPU を持つノード上で動作する Pod を選択しません。

Pod の使用パターン

Pod には、主に次の 2 つの使用方法があります。

  • 単一コンテナを実行する Pod。最も簡単かつ一般的な Pod パターンである「Pod ごとに 1 コンテナ」は、1 つのコンテナがアプリケーション全体を表します。この場合は、Pod をラッパーと考えることができます。
  • 連携して動作する必要がある複数のコンテナを実行する Pod。複数のコンテナを含む Pod の主な使用目的は、リソースを共有する必要があり、同じ場所に配置され、共同で管理されるプログラムをサポートすることです。このように同じ場所に配置されたコンテナは 1 つのまとまったサービス単位を形成できます。たとえば、あるコンテナが共有ボリュームからファイルを提供し、別のコンテナがそれらのファイルを更新できます。Pod は、これらのコンテナとストレージ リソースを 1 つの管理可能なエンティティにまとめます。

個々の Pod は、特定のアプリケーションの単一インスタンスを実行するためのものです。複数のインスタンスを実行する場合は、アプリケーションのインスタンスごとに 1 つの Pod を使用する必要があります。これを一般に「複製」と呼びます。複製 Pod は、Deployment などのコントローラによって 1 つのグループとして作成され、管理されます。

Pod の終了

Pod は、自身のプロセスが完了すると正常に終了します。Kubernetes のデフォルトでは、正常に終了するための時間として、30 秒が指定されています。Pod を削除するときには、Pod が強制終了されるまでの待機期間(秒数)を --grace-period フラグで設定することで、この正常終了時間をオーバーライドできます。

次のステップ