ストレージ
*ストレージは、データベースワークロードで最も重要なコンポーネントです** 。ストレージは、常に利用でき、スケーリング、パフォーマンスが良く、一貫性と耐久性を保証する必要があります。仮想マシンやベアメタルなどの従来の環境に適用されるのと同じ期待と要件は、Kubernetesによって管理されるコンテナコンテキストでも有効です。
重要
動的にプロビジョニングされるストレージに関して、Kubernetesには独自の特性があります。これらには、ストレージクラス、永続ボリューム、および*永続ボリューム要求*が含まれます。 VMおよび物理サーバー上のデータベースワークロードのストレージの観点から、長年構築してきた貴重な知識に加えて、これらの概念を所有する必要があります。
ストレージへのアクセスには、主に2つの方法があります。
ネットワーク 直接または間接的にKubernetesを実行しているホストにローカルにマウントされたNFSボリュームを考えます。
ローカル ポッドが実行されているノードに直接接続されていますこれには、Kubernetesのベアメタルインストールに直接接続されたディスクも含まれます
Kubernetesで最も一般的な使用パターンであるネットワークストレージは、従来の環境で経験する可能性のあるスループットとレイテンシと同じ問題を示します。これらは、複数のアプリケーションとのI/O競合によりパフォーマンス結果のばらつきが増加する共有環境では強調される可能性があります。
ローカルストレージは、シェアードナッシングアーキテクチャを有効にします。これは、より高く予測可能なパフォーマンスを保証するため、高トランザクションの超大規模データベースVLDBワークロードに適しています。
警告
CloudNativePGでPostgreSQLクラスターを展開する前に、使用しているストレージがデータベースワークロードに推奨されていることを確認してください。私たちのアドバイスは、最初に fio などのツールを使用してストレージをベンチマークし、次に pgbench を使用してデータベースをベンチマークすることにより、パフォーマンスの期待値を明確に設定することです。
注釈
CloudNativePGは、データの永続性の管理に`StatefulSet` sを使用しません。代わりに、永続ボリューム要求PVCを直接管理します。詳細については、 カスタムポッドコントローラ ドキュメントをご覧ください。
バックアップ リカバリー
CloudNativePGは、バックアップとリカバリーの両方のボリュームスナップショットをサポートしているため、ストレージソリューションを選択するときに、特に非常に大規模なデータベースを管理する場合、この側面も考慮することをお勧めします。
重要
サポートされているすべてのサービスのリストについては、Kubernetesの公式ドキュメントを参照してください Container Storage Interface (CSI) drivers
スナップショット機能を提供します。
CloudNativePGのベンチマーク
guidelines in the "Benchmarking" section に従って、運用環境にデータベースを展開する前に、制御されたKubernetes環境でCloudNativePGのベンチマークを行うことをお勧めします。
手短に言うと、私たちのアドバイスは2つのレベルで動作することです。
fioを使用して、基になるストレージのパフォーマンスを測定する。シークエンシャル読み取り、シークエンシャル書き込み、ランダム読み取り、ランダム書き込みのスループットなど、データベースワークロードの関連メトリックPostgreSQLとともに配布されるデフォルトのベンチマークツール
pgbenchを使用してデータベースのパフォーマンスを測定する
重要
ストレージとデータベースのパフォーマンスの両方の測定は、データベースが運用開始する前に**行う必要があるアクティビティです。ただし、このような結果は、計画段階キャパシティプランニングなどでだけでなく、生産ライフサイクル、特に緊急事態この種のテストを実行する余裕がない場合でも非常に価値があります。データベースは実際に時間の経過とともに変更および進化し、データの分散も変化し、パフォーマンスに影響を与える可能性があります。シークエンシャルな読み取りまたは書き込みの理論的な最大スループットを知ることは、これらの状況で非常に役立つことがわかります。特に、外部ワークロードの影響によって結果が変化しないシェアードナッシングコンテキストでは。 **システムを知り、ベンチマークします。
保存時の暗号化
CloudNativePGでは、保存時の暗号化が可能です。オペレーターは、それを基になるストレージクラスに委任します。この重要なセキュリティ機能については、ストレージクラスを参照してください。
Persistent Volume Claim
オペレーターは、PGDATA
を保存することを目的として、各PostgreSQLインスタンスの永続ボリューム要求PVCを作成し、各ポッドにマウントします。
さらに、次のクラスターの作成をサポートします。
以下の WALのボリューム で説明しているように、PostgreSQL書き込み先行ログWALを保存する別のPVC
TablespaceState {postgresql-cnpg-io-v1-TablespaceState} で説明しているように、PostgreSQLテーブルスペース用に予約された追加の個別ボリューム
CloudNativePGでは、単一のPostgreSQLインスタンスに接続されたボリュームは PVCグループ として定義されます。
ストレージクラスを介した構成
重要
CloudNativePGは、ストレージクラスに依存しないように設計されています。いつものように、運用に展開する前に、制御された環境でストレージクラスを適切にベンチマークすることをお勧めします。
PostgreSQLクラスのストレージを構成するより簡単な方法は、次の例のように、特定のサイズのストレージを要求するだけです。
apiVersion: postgresql.cnpg.io/v1
kind: Cluster
metadata:
name: postgresql-storage-class
spec:
instances: 3
storage:
size: 1Gi
前の構成を使用すると、生成されたPVCはデフォルトのストレージクラスで満たされます。ターゲットKubernetesクラスターにデフォルトのストレージクラスがない場合、または既知のストレージクラスでPVCを満たす必要がある場合でも、カスタムリソースに設定できます。
apiVersion: postgresql.cnpg.io/v1
kind: Cluster
metadata:
name: postgresql-storage-class
spec:
instances: 3
storage:
storageClass: standard
size: 1Gi
PVCテンプレートを介した構成
生成されたPVCをさらにカスタマイズするには、次の例のように、カスタムリソース内にPVCテンプレートを提供できます。
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 PostgreSQLではpg_xlog
として知られています。これには、データベースで発生したトランザクション変更のログがセグメントファイルの形式で含まれています。
注釈
通常、各セグメントのサイズは16MBですが、サイズは 空のクラスターをブートストラップする `initdb <空のクラスターをブートストラップする initdb>` で説明しているように、クラスターの初期化時に適用される`walSegmentSize` オプションを介して構成できます。
ほとんどの場合、 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のサイズ変更が必要な場合に通知する適切なアラートを設定できます。
参考
Reliability and the Write-Ahead Log を参照してください。
詳細については、 PostgreSQLの公式ドキュメントから 。
.spec.walStorage
オプションを介してWALの個別のボリュームを追加できます。これは、
storage
フィールドで説明したものと同じルールに従い、専用PVCをプロビジョニングします。例
apiVersion: postgresql.cnpg.io/v1
kind: Cluster
metadata:
name: separate-pgwal-volume
spec:
instances: 3
storage:
size: 1Gi
walStorage:
size: 1Gi
重要
walStorage の削除はサポートされていません。追加されると、WALの別のボリュームは既存のPostgresクラスターから削除できません。
テーブルスペースのボリューム
- CloudNativePGは、宣言的テーブルスペースをサポートしています。それぞれが単一のPostgreSQLテーブルスペース専用の1つ以上のボリュームを追加できます。詳細は、
TablespaceState {postgresql-cnpg-io-v1-TablespaceState} を参照してください。
ボリュームの拡張
Kubernetesが expanding PVCs を許可するAPIを公開
これはデフォルトで有効ですが、基になるStorageClass
でサポートする必要があります。
特定のStorageClass
がボリューム拡張をサポートしているかどうかを確認するには、ストレージクラスのallowVolumeExpansion
フィールドを読み取ることができます。
$ kubectl get storageclass -o jsonpath={$.allowVolumeExpansion} premium-storage
true
ボリューム拡張Kubernetes機能の使用
ストレージクラスがボリューム拡張をサポートしている場合、 Cluster
のサイズ要件を変更できます。オペレーターはすべてのPVCに変更を適用します。
StorageClass が online volume resizing をサポートしている場合
変更はすぐにポッドに適用されます。基になるストレージクラスがそれをサポートしていない場合、ポッドを削除してサイズ変更をトリガーする必要があります。
続行する最良の方法は、一度に1つのポッドを削除し、レプリカから始めて、各ポッドがバックアップされるまで待機することです。
AKSでのPVCボリュームの拡張
- 現時点では、 Azure is not able to resize the PVC's volume without restarting the pod 。 CloudNativePGは、
オペレーター設定 の
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
`docs <https://github.com/kubernetes-sigs/azuredisk-csi-driver/blob/master/docs/known-issues/sizegrow.md>`_ で説明しているように、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 <node of cluster-example-3>
次に、 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 <node of cluster-example-3>
ポッドが正しく再作成され、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}
したがって、残りのポッドに対してこれらの手順を繰り返すことができます。
重要
kubectl cnpg promote たとえば、cluster-example-3 をプライマリに昇格させるための`kubectl cnpg promote cluster-example 3` を使用して、新しいサイズ変更したポッドをスイッチオーバーで昇格させた後、プライマリインスタンスに関連付けられたディスクのサイズ変更を最後のディスクとして残してください。
ストレージの再作成
ストレージクラスがボリューム拡張をサポートしていない場合でも、増加したストレージで新しいPVCを割り当て、そこにデータベースを移動することにより、別のPVCでクラスターを再生成できます。この操作は、クラスターに複数のノードが含まれる場合にのみ実行可能です。
その際、次の例のように、resizeInUseVolumes
フラグを無効にすることにより、オペレーターが既存のPVCを変更しないようにする必要があります。
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
重要
専用の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は、動的ボリュームプロビジョニングと連携するように設計されており、ユーザーが要求したときに、上記のストレージクラスと永続ボリューム要求テンプレートを介して、オンデマンドでストレージボリュームを自動的に作成できます。
ただし、場合によっては、Kubernetes管理者は、新しいストレージボリュームを
手動
作成し、Kubernetesクラスター内での表現に関連するPersistentVolume
オブジェクトを作成することを優先します。これはとしても知られています
ボリュームの *事前プロビジョニング** 。
重要
私たちの推奨は、オペレーターの高可用性と自己修復機能に影響を与え、CloudNativePGが構築されている完全な宣言型モデルを壊すため、ボリュームの事前プロビジョニングを回避することです。
次の手順を実行して、CloudNativePGで事前プロビジョニングされたボリュームを使用できます。
Kubernetesの外部でボリュームを手動で作成する
実際のCSIドライバーつまり
volumeHandle、fsType、storageClassNameなどに必要な正しいパラメーターを使用して、上記のボリュームと一致するようにPersistentVolumeオブジェクトを作成しますストレージセクションごとに、コヒーレントな pvcTemplate を使用してPostgres
Clusterを作成します
Kubernetesが上記のPersistentVolume
と一致し、CloudNativePGが必要なPersistentVolumeClaim
を作成できるようにするセクション
警告
静的プロビジョニングでは、クラスターのアフィニティルールに基づいて、事前プロビジョニングされたボリュームが存在するKubernetesによってPostgresポッドを正しくスケジュールできることを確認するのはあなたの責任です。クラスターを展開した後、Pending でスタックしているポッドがないかを確認し、状態が持続する場合は、これが発生した理由を調査します。
ブロックストレージの考慮事項Ceph/Longhorn
Kubernetesのブロックストレージソリューションのほとんどは、復元性を向上させるためにボリュームの複数の「レプリカ」を持つことを提案しています。これは、アプリケーションに復元力が組み込まれていないワークロードに適しています。ただし、CloudNativePGは、インスタンスの数とそれらに接続されている永続ボリュームを介してPostgres
Cluster に直接組み込まれているこの復元力を備えています。