ポッド

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

ポッドとは

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

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

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

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

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

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

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

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

ポッドのライフサイクル

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

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

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

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

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

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

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

ポッドを作成する

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

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

ポッド リクエスト

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

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

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

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

ポッドの制限

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

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

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

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

ポッド テンプレート

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

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

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

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

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

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

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

ポッドの使用パターン

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

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

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

ポッドの終了

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

次のステップ