ストレージ ========== ストレージは、データベースワークロードで最も重要なコンポーネントです。ストレージは常に利用でき、スケーリング、パフォーマンスが良く、一貫性と耐久性を保証する必要があります。仮想マシンやベアメタルなどの従来の環境に適用されるのと同じ期待と要件は、Kubernetesによって管理されるコンテナコンテキストでも有効です。 .. Important:: 動的にプロビジョニングされるストレージに関しては、Kubernetesに独自の詳細があります。これらには、_ストレージクラス_、_永続ボリューム_、および_永続ボリューム要求PVCs_が含まれます。 VMおよび物理サーバー上のデータベースワークロードのストレージの観点から、長年構築してきた貴重な知識に加えて、これらの概念を所有する必要があります。 ストレージへのアクセスには、主に2つの方法があります。 - **ネットワーク** – 直接または間接的に。 (Kubernetesを実行しているホストにローカルにマウントされたNFSボリュームを考えます。) - **ローカル** – ポッドが実行されているノードに直接接続されます。これには、Kubernetesのベアメタルインストールに直接接続されたディスクも含まれます。 Kubernetesで最も一般的な使用パターンであるネットワークストレージは、従来の環境で経験する可能性のあるスループットとレイテンシと同じ問題を示します。これらの問題は、複数のアプリケーションとのI/O競合によりパフォーマンス結果のばらつきが増加する共有環境では強調される可能性があります。 ローカルストレージは、シェアードナッシングアーキテクチャを有効にします。これは、より高く予測可能なパフォーマンスを保証するため、高トランザクションで非常に大規模なデータベースVLDBワークロードに適しています。 .. Warning:: CloudNativePGでPostgreSQLクラスターを展開する前に、使用しているストレージがデータベースワークロードに推奨されていることを確認してください。 `fio `_ などのツールを使用してストレージをベンチマークし、パフォーマンスの期待値を明確に設定することをお勧めします 次に、 `pgbench `_ を使用したデータベース。 .. NOTE:: CloudNativePGは、データの永続性の管理に`StatefulSet` を使用しません。むしろ、PVCを直接管理します。詳細については、 :ref:`カスタムポッドコントローラ <カスタムポッドコントローラ>` を参照してください。 バックアップ リカバリー ----------------------- CloudNativePGは、バックアップとリカバリーの両方のボリュームスナップショットをサポートしているため、ストレージソリューションを選択するときに、特に非常に大規模なデータベースを管理する場合、この側面も考慮することをお勧めします。 .. Important:: サポートされているすべてのサービスのリストについては、Kubernetesドキュメントを参照してください `container storage interface (CSI) drivers `_ スナップショット機能を提供します。 CloudNativePGのベンチマーク --------------------------- データベースを実稼働環境に展開する前に、制御されたKubernetes環境でCloudNativePGのベンチマークを行うことをお勧めします。 :ref:`ベンチマーク <ベンチマーク>` のガイドラインに従ってください。 手短に言うと、2つのレベルで動作することをお勧めします。 - シークエンシャル読み取り、シークエンシャル書き込み、ランダム読み取り、ランダム書き込みのスループットなど、データベースワークロードの関連メトリックを使用して、fioを使用して基になるストレージのパフォーマンスを測定する - PostgreSQLで配布されるデフォルトのベンチマークツール、pgbenchを使用してデータベースのパフォーマンスを測定する .. Important:: データベースを本番環境に配置する前に、ストレージとデータベースのパフォーマンスの両方を測定する必要があります。これらの結果は、計画段階たとえば、キャパシティプランニングなどにおいてだけでなく、非常に価値があります。また、実稼働ライフサイクル、特にこの種のテストを実行する時間がない緊急事態においても貴重です。データベースは時間の経過とともに変更および進化し、データの分散も同様に、パフォーマンスに影響を与える可能性があります。シークエンシャルな読み取りまたは書き込みの理論的な最大スループットを知ることは、これらの状況において非常に役立ちます。これは、外部ワークロードの影響によって結果が変化しないシェアードナッシングコンテキストに特に当てはまります。 自分のシステムを知り、ベンチマークします。 保存時の暗号化 -------------- CloudNativePGでは、保存時の暗号化が可能です。オペレーターは、それを基になるストレージクラスに委任します。この重要なセキュリティ機能の詳細については、ストレージクラスを参照してください。 Persistent Volume Claim Claim PVC --------------------------------- オペレーターは、\ ``PGDATA`` を保存することを目的に、各PostgreSQLインスタンスのPVCを作成します。次に、それを各ポッドにマウントします。 さらに、次のクラスターの作成をサポートしています。 - :ref:`WALのボリューム ` で説明しているように、PostgreSQL WALを保存する別のPVC - :ref:`TablespaceState {postgresql-cnpg-io-v1-TablespaceState} ` で説明しているように、PostgreSQLテーブルスペース用に予約された追加の個別ボリューム CloudNativePGでは、単一のPostgreSQLインスタンスに接続されたボリュームは_PVC group_として定義されます。 ストレージクラスを介した構成 ---------------------------- .. Important:: CloudNativePGは、すべてのストレージクラスと互換的に動作するように設計されました。いつものように、運用に展開する前に、制御された環境でストレージクラスを適切にベンチマークすることをお勧めします。 PostgreSQLクラスのストレージを構成する最も簡単な方法は、次の例のように、特定のサイズのストレージを要求することです。 .. code:: yaml apiVersion: postgresql.cnpg.io/v1 kind: Cluster metadata: name: postgresql-storage-class spec: instances: 3 storage: size: 1Gi 前の構成を使用すると、生成されたPVCはデフォルトのストレージクラスで満たされます。ターゲットKubernetesクラスターにデフォルトのストレージクラスがない場合、または既知のストレージクラスでPVCを満たす必要がある場合でも、カスタムリソースに設定できます。 .. code:: yaml apiVersion: postgresql.cnpg.io/v1 kind: Cluster metadata: name: postgresql-storage-class spec: instances: 3 storage: storageClass: standard size: 1Gi PVCテンプレートを介した構成 --------------------------- 生成されたPVCをさらにカスタマイズするには、次の例のように、カスタムリソース内にPVCテンプレートを提供できます。 .. code:: yaml apiVersion: postgresql.cnpg.io/v1 kind: Cluster metadata: name: postgresql-pvc-template spec: instances: 3 storage: pvcTemplate: accessModes: - ReadWriteOnce resources: requests: storage: 1Gi storageClassName: standard volumeMode: Filesystem WALのボリューム --------------- デフォルトでは、PostgreSQLはすべてのデータをいわゆる\ ``PGDATA`` ディレクトリに保存します。 ``PGDATA`` 内のコアディレクトリの1つが\ ``pg_wal`` で、これには、データベースで発生したトランザクション変更のログがセグメントファイルの形式で含まれています。 ``pg_wal`` は、PostgreSQLでは歴史的に\ ``pg_xlog`` として知られています。 .. NOTE:: 通常、各セグメントのサイズは16MBですが、 `walSegmentSize` オプションを使用してサイズを構成できます。 :ref:`空のクラスターをブートストラップする `initdb` <空のクラスターをブートストラップする `initdb`>` で説明しているように、このオプションはクラスターの初期化時に適用されます。 ほとんどの場合、\ ``PGDATA`` が存在するのと同じボリュームに\ ``pg_wal`` があっても問題ありません。ただし、WALを別のボリュームに保存すると、いくつかの利点があります。 - **I/Oパフォーマンス** – WALファイルを\ ``PGDATA`` とは別のストレージに保存することにより、PostgreSQLはWAL操作通常はシークエンシャル書き込みとデータファイルテーブルやインデックスなどの並列I/Oを利用でき、したがって、垂直方向を向上させることができますスケーラビリティ。 - **信頼性の向上** – WALファイルに専用のディスク領域を予約することにより、\ ``PGDATA`` ボリュームの領域を使い果たしてもWALの書き込みが妨げられることはありません。この動作により、PostgreSQLプライマリが正しくシャットダウンされます。 - **より細かい制御** – ``PGDATA`` と\ ``pg_wal`` の両方専用の領域の量を定義でき、 `WAL configuration `_ を微調整できます。 とチェックポイント、さらにはコスト最適化のために別のストレージクラスを使用します。 - **I/Oモニタリングの向上** – ``PGDATA`` と\ ``pg_wal`` の両方で負荷とディスク使用量を常にモニタできます。たとえば、\ ``PGDATA`` のサイズ変更が必要な場合に通知するアラートを設定することもできます。 .. Seealso:: `Reliability and the Write-Ahead Log `_ を参照 詳細については、PostgreSQLドキュメントを参照してください。 ``.spec.walStorage`` オプションを使用して、WALの別のボリュームを追加できます。 ``storage`` フィールドで説明したものと同じルールに従い、専用のPVCをプロビジョニングします。例 .. code:: yaml apiVersion: postgresql.cnpg.io/v1 kind: Cluster metadata: name: separate-pgwal-volume spec: instances: 3 storage: size: 1Gi walStorage: size: 1Gi .. Important:: `walStorage` の削除はサポートされていません。 WALの別のボリュームを追加すると、既存のPostgresクラスターから削除することはできません。 テーブルスペースのボリューム ---------------------------- CloudNativePGは、宣言的テーブルスペースをサポートしています。それぞれが単一のPostgreSQLテーブルスペース専用の1つ以上のボリュームを追加できます。詳細は、 :ref:`TablespaceState {postgresql-cnpg-io-v1-TablespaceState} ` を参照してください。 ボリュームの拡張 ---------------- Kubernetesが :ref:`expanding PVCs <ストレージ>` を許可するAPIを公開 それはデフォルトで有効になっています。ただし、基になる\ ``StorageClass`` でサポートされている必要があります。 特定の\ ``StorageClass`` がボリューム拡張をサポートしているかどうかを確認するには、ストレージクラスの\ ``allowVolumeExpansion`` フィールドを読み取ることができます。 :: $ kubectl get storageclass -o jsonpath={$.allowVolumeExpansion} premium-storage true ボリューム拡張Kubernetes機能の使用 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ストレージクラスがボリューム拡張をサポートしている場合、 ``Cluster`` のサイズ要件を変更できます。オペレーターはすべてのPVCに変更を適用します。 ``StorageClass`` が :ref:`online volume resizing <ストレージ>` をサポートしている場合、変更はすぐにポッドに適用されます。基になるストレージクラスがそれをサポートしていない場合、ポッドを削除してサイズ変更をトリガーする必要があります。 続行する最良の方法は、一度に1つのポッドを削除し、レプリカから始めて、各ポッドがバックアップされるまで待機することです。 AKSでのPVCボリュームの拡張 ^^^^^^^^^^^^^^^^^^^^^^^^^^ 現在、 `Azure can resize the PVC's volume without restarting the pod only on specific regions `_ . CloudNativePGは、 :ref:`オペレーター設定 <オペレーター設定>` の\ ``ENABLE_AZURE_PVC_UPDATES`` 環境変数を介してこの制限を克服しました。 ``true`` に設定すると、CloudNativePGはPostgresクラスターのローリング更新をトリガーします。 または、次の回避策を使用して、AKSのボリュームのサイズを手動で変更できます。 AKSのボリューム拡張の回避策 ^^^^^^^^^^^^^^^^^^^^^^^^^^^ AKSでPVCのサイズを手動で変更できます。例として、3つのレプリカを持つクラスターがあるとします。 :: $ kubectl get pods NAME READY STATUS RESTARTS AGE cluster-example-1 1/1 Running 0 2m37s cluster-example-2 1/1 Running 0 2m22s cluster-example-3 1/1 Running 0 2m10s `Kubernetes documentation `_ で説明しているように、Azureディスクは「未接続」状態にあるときにのみ拡張できます。 これは、PostgreSQLクラスターが使用するディスクのサイズを変更するには、手動ロールアウトを実行し、最初にディスクにバインドされたPVCを使用してポッドをホストするノードを遮断する必要があることを意味します。これにより、バックグラウンドでのディスクのサイズ変更が完了する前に、オペレーターがポッドを再作成し、すぐにPVCに再接続することを防ぎます。 最初に、クラスター定義を編集し、新しいサイズを適用します。この例では、新しいサイズは\ ``2Gi`` です。 :: apiVersion: postgresql.cnpg.io/v1 kind: Cluster metadata: name: cluster-example spec: instances: 3 storage: storageClass: default size: 2Gi ``cluster-example-1`` ポッドがクラスターのプライマリであると仮定すると、最初にレプリカの使用を続行できます。たとえば、 ``cluster-example-3`` ポッドをホストするKubernetesノードを遮断することから始めます。 :: kubectl cordon 次に、 ``cluster-example-3`` ポッドを削除します。 :: $ kubectl delete pod/cluster-example-3 次のコマンドを実行します。 :: kubectl get pvc -w -o=jsonpath={.status.conditions[].message} cluster-example-3 次の出力が表示されるまで待ちます。 :: Waiting for user to (re-)start a Pod to finish file system resize of volume on node. 次に、ノードの遮断を解除できます。 :: kubectl uncordon ポッドが正しく再作成され、「Running and Ready」状態になるのを待ちます。 :: kubectl get pods -w cluster-example-3 cluster-example-3 0/1 Init:0/1 0 12m cluster-example-3 1/1 Running 0 12m 次のコマンドを実行して、PVC拡張を確認します。これは、構成どおりに\ ``2Gi`` を結果ます。 :: kubectl get pvc cluster-example-3 -o=jsonpath={.status.capacity.storage} 残りのポッドに対してこれらの手順を繰り返すことができます。 .. Important:: `kubectl cnpg promote` を使用して、新しいサイズ変更されたポッドをスイッチオーバーでプロモートした後、プライマリインスタンスに関連付けられているディスクのサイズ変更を最後のディスクとして残します。たとえば、 `kubectl cnpg promote cluster-example 3` を使用して`cluster-example-3` をプライマリに昇格させます。 ストレージの再作成 ^^^^^^^^^^^^^^^^^^ ストレージクラスがボリューム拡張をサポートしていない場合でも、別のPVCでクラスターを再生成できます。増加したストレージに新しいPVCを割り当て、データベースをそこに移動します。この操作は、クラスターに複数のノードが含まれる場合にのみ実行可能です。 その際、次の例のように、\ ``resizeInUseVolumes`` フラグを無効にすることにより、オペレーターが既存のPVCを変更しないようにする必要があります。 .. code:: yaml apiVersion: postgresql.cnpg.io/v1 kind: Cluster metadata: name: postgresql-pvc-template spec: instances: 3 storage: storageClass: standard size: 1Gi resizeInUseVolumes: False クラスター全体を別の記憶領域に移動するには、すべてのPVCとすべてのポッドを再作成する必要があります。次の例のように、3つのレプリカを含むクラスターがあるとします。 :: $ kubectl get pods NAME READY STATUS RESTARTS AGE cluster-example-1 1/1 Running 0 2m37s cluster-example-2 1/1 Running 0 2m22s cluster-example-3 1/1 Running 0 2m10s 別のPVCを使用してクラスターを再作成するには、クラスター定義を編集して\ ``resizeInUseVolumes`` を無効にできます。次に、すべてのインスタンスを別のPVCで再作成します。 たとえば、 ``cluster-example-3`` のストレージを再作成します。 :: $ kubectl delete pvc/cluster-example-3 pod/cluster-example-3 .. Important:: 専用のWALボリュームを作成した場合、このプロセス中に両方のPVCを削除する必要があります。 WALボリュームPVCを再生成する場合にも、同じ手順が適用されます。これは、 `.spec.walStorage` セクションの`resizeInUseVolumes` も無効にすることにより実行できます。 たとえば、WALストレージ専用のPVCが存在する場合 :: $ kubectl delete pvc/cluster-example-3 pvc/cluster-example-3-wal pod/cluster-example-3 それが完了したら、オペレーターは、サイズ変更したPVCを使用して別のレプリカの作成を調整します。 :: $ kubectl get pods NAME READY STATUS RESTARTS AGE cluster-example-1 1/1 Running 0 5m58s cluster-example-2 1/1 Running 0 5m43s cluster-example-4-join-v2 0/1 Completed 0 17s cluster-example-4 1/1 Running 0 10s 永続ボリュームの静的プロビジョニング ------------------------------------ CloudNativePGは、動的ボリュームプロビジョニングで動作するように設計されました。この機能により、ストレージクラスとPVCテンプレートを介してユーザーが要求したときに、ストレージボリュームをオンデマンドで作成できます。 :ref:`ストレージの再作成 <ストレージの再作成>` を参照してください。 ただし、場合によっては、Kubernetes管理者がストレージボリュームを手動で作成し、Kubernetesクラスター内での表現形式に関連する\ ``PersistentVolume`` オブジェクトを作成することを優先する場合があります。これは、ボリュームの_pre-provisioning_としても知られています。 .. Important:: ボリュームの事前プロビジョニングは、オペレーターの高可用性と自己修復機能に影響を与えるため、回避することをお勧めします。これは、CloudNativePGが構築された完全な宣言型モデルを中断します。 CloudNativePGで事前プロビジョニングされたボリュームを使用するには 1. Kubernetesの外部でボリュームを手動で作成します。 2. 実際のCSIドライバーつまり ``volumeHandle`` 、\ ``fsType`` 、\ ``storageClassName`` などに必要な正しいパラメーターを使用して、このボリュームと一致するように\ ``PersistentVolume`` オブジェクトを作成します。 3. ストレージセクションごとに、コヒーレントな :ref:`pvcTemplate <ストレージ>` を使用してPostgres ``Cluster`` を作成します このセクションは、Kubernetesが\ ``PersistentVolume`` と一致し、CloudNativePGが必要な\ ``PersistentVolumeClaim`` を作成できるようにします。 .. Warning:: 静的プロビジョニングでは、事前プロビジョニングされたボリュームが存在するKubernetesによってPostgresポッドを正しくスケジュールできることを確認するのはあなたの責任です。スケジューリング構成は、クラスターのアフィニティルールにもとづいています。クラスターを展開した後、`Pending` にスタックしているポッドがないかを確認してください。状態が続く場合は、それが発生した理由を調査します。 ブロックストレージの考慮事項Ceph/Longhorn ----------------------------------------- LonghornやCephなど、Kubernetesのほとんどのブロックストレージソリューションでは、復元力を強化するためにボリュームの複数のレプリカを持つことをお勧めします。このアプローチは、組み込みの復元力が不足しているワークロードに適しています。 ただし、 CloudNativePGは、 :ref:`状態の同期 <状態の同期>` で説明しているように、インスタンスの数とそれらにアタッチされている永続ボリュームを介して、この復元力をPostgres ``Cluster`` に直接統合します。 その結果、ストレージレベルで追加のレプリカを定義すると、書き込み増幅が発生し、ディスクI/Oと領域の使用量が不必要に増加する可能性があります。 CloudNativePGを使用する場合、ブロックストレージレベルのレプリカの数を1つに減らしながら、 ``Cluster`` リソース全体のストレージレベルで単一障害点SPoFが存在しないことを確認することを検討します。これは通常、単一のストレージホスト、そして最終的には物理ディスクが、より広範な_shared-nothingアーキテクチャ_原則に沿って、同じ\ ``Cluster`` の異なるインスタンスからのブロックをホストしないことを意味します。 Longhornでは、カスタムストレージクラスを作成するときに厳密なローカルデータの局所性を有効にすることにより、このリスクを軽減できます。厳密なローカルデータの局所性を使用してボリュームを作成するための詳細な手順は、 `here `_ を参照してください。この設定により、ポッドのデータボリュームがポッド自分自身と同じノードに存在します。 さらに、Postgres ``Cluster`` には :ref:`pod anti-affinity rules <スケジューリング>` が必要です オペレーターがさまざまなノードにポッドを展開できるように、Longhornは対応するホストにデータボリュームを配置できます。必要に応じて、ボリュームレプリカ数を一時的に2に設定し、後で減らして、古いレプリカを削除することにより、Longhornのボリュームを手動で再配置できます。ホストが破損した場合は、 :ref:`Backup {postgresql-cnpg-io-v1-Backup} ` 影響を受けるインスタンス。 CloudNativePGは別のホストでインスタンスを再作成し、データを複製します。 Cephでは、これはCRUSHルールを介して構成できます。 CRUSHルールの構成に関するドキュメントは `here `_ で入手できます。これらのルールは、ノードごとにポッドごとに1つのボリュームを保証することを目的としています。ボリュームを別のプールにインポートすることにより、再配置することもできます。