Kubernetes での状態管理について

完了

アプリケーションについて一般的な話をするとき、"アプリケーションの状態" についてよく耳にします。 このユニットでは、状態の定義と、さまざまな種類の状態を確認して、それらを処理するためのアプリケーションをより適切に準備できるようにします。

状態

アプリケーションの状態とは、アプリケーションが実行されるときまでにメモリ内に格納されるすべてのものです。 状態にはさまざまなことが関係する可能性がありますが、ここでは主にユーザー データに焦点を当てます。

アプリケーション状態の例としては、音楽プレーヤーを開いている場合を想像してください。 このアプリケーションには状態があります。 聴いているのは誰か、何を聴くのが好きか、どのような曲をダウンロードしたか、といったことを知っています。 このような情報はすべて、アプリケーション状態の一部です。

メモリ内の状態は、アプリケーションで他の場所を検索する必要がない情報です。 ディスク状態には、アプリケーションがすぐに使用できない情報が含まれているので、別のデータ ソースから取得する必要があります。

状態の種類

アプリケーション状態には、2 つの種類があります。 1 つ目の種類は、"一時的状態" です。これは、永続的ではなく、アプリケーションが閉じられるとすぐに消えます。

コンテナーには一時的な状態があります。 コンテナーが削除されると、その中の格納データはすぐにすべて失われます。 一部のアプリケーションは、他のソースから状態を再生成でき、ローカルに格納しておく必要がないため、それだけで動作できます。 そのようなアプリケーションは "stateless アプリケーション" と呼ばれます。

これに対して、一時的ではない残りのすべての状態は、"永続的状態" と呼ばれます。 永続的状態は、コンテナーのライフサイクルが終わった後も存在し続けます。 使用するほとんどのコンテナー テクノロジには、"ボリューム" という概念があります。これは、状態が存在しているディスク内の場所です。 コンテナーを削除してから元に戻した場合でも、状態は安全な場所に格納されていて、再び使用できます。

外部状態の取得に依存するアプリケーションは、"stateful アプリケーション" と呼ばれます。

状態と Kubernetes

Kubernetes では、ステートレスとステートフルの両方のアプリケーションを処理できます。 ステートレス アプリは、アプリケーション自体だけに注目し、状態は (存在しないため) 気にしなくてよいので、より簡単に処理することができます。

ほとんどのステートレス アプリケーションでは、システムを完全に機能させ、クラスターを最大限に活用するのに、ポッドを使用した単純なデプロイ ワークロードで十分です。

ステートフル アプリケーションの処理はその逆です。 これらの場合は、アプリケーションとその状態 (状態がどこに格納されるか、どうすれば安全で確実に状態を格納できるか) について考慮する必要があります。

このため、Kubernetes には PersistentVolumes (PV) および PersistentVolumeClaims (PVC) という概念もあります。

ヒント

このモジュールではストレージの概念については詳しく説明しませんが、「まとめ」にある Azure Kubernetes Service リソースを参照して詳細を確認できます。

PersistentVolumes は、ポッドのコンテナーから状態を格納するためにノードに割り当てられているディスクです。 Kubernetes は分散アプリに最適なので、作成されたすべてのボリュームは "使用可能なボリューム" のプールに格納されます。 その後、コンテナーはそれ自体のための領域を要求します。 PersistentVolumeClaims を使用して PersistentVolume をポッドとバインドし、その領域を使用して必要なデータを格納することができます。

すべてのデータベース プロバイダーは、ステートフル アプリケーションです。 データベース プロバイダーをクラスターにデプロイする場合は、データベースのデータを安全な場所に格納し、そのコンテナーが削除された場合でもプロバイダーでデータを取得できるようにするために、PV と PVC が必要になります。

状態の処理に関するベスト プラクティス

状態は、ほとんどのアプリケーションに存在します。 ただし、状態の処理に関するベスト プラクティスは、それをまったく処理しないことです。

効率的なアプリケーションを設計するときの目標は、高可用性と拡張性を実現することです。 状態はそれと正反対のものです。 ストレージ プロバイダーによって提供されるオプションと、デプロイと使用の容易さにもかかわらず、状態は簡単には拡張できません。 高可用性もありません。

高可用性の状態

高可用性にするには、常にアプリケーションをオンラインにする必要があります。 これは、ゾーンとリージョンのレプリケーションによって行われます。 Kubernetes は、ほとんどのワークロードでゾーンに対応しています。 つまり、アプリケーションの複数のインスタンスを異なるゾーンにデプロイできます。 ただし、ディスクはゾーンに対応していません。

Kubernetes に新しい PersistentVolume オブジェクトをデプロイすると、ノード上のディスクにバインドされます。 また、そのディスクは特定のリージョン内の特定のゾーンにもバインドされます。 PV でゾーンまたはリージョンのレプリケーションを使用するのは複雑であり、データのレプリケートと同期の両方のために多くのメンテナンスが必要になります。

高スケーラブルの状態

アプリケーションが高度にスケーラブルであるためには、それに接続しているユーザーの数と共にスループットを増やす必要があります。 基本的に外部状態はディスクであり、ディスクは入出力のレートが限られているため、状態管理が複雑になります。 この問題の解決にはスループット管理が役立ちます。

データベース ソリューションには、ReplicaSets の考え方が採用されています。これは、データベース全体を複数のインスタンスにレプリケートするというものです。 レプリケーションによってディスクの数が増え、"したがって" 状態の I/O が増加します。

データベースのすべての変更について、すべてのディスクに同じデータが含まれるように状態を同期する必要があります。 この同期も複雑です。

状態の外部化

Azure には、Azure Cosmos DB のように、可用性と拡張性が高く、状態管理の問題のほとんどを解決するサービスとしてのプラットフォーム (PaaS) ソリューションが用意されています。

状態を外部に格納し、メンテナンスを不要にすることで、ユーザーはアプリケーションに集中でき、インフラストラクチャ内のデータの整合性を処理するオーバーヘッドを軽減することができます。

自分の知識をチェックする

1.

アプリケーションの永続的状態とはどのようなことですか?

2.

状態は Kubernetes によってどのように処理されますか?

3.

Kubernetes アプリケーションで状態を処理するためのベスト プラクティスは何ですか?