ストレージ

ストレージは、データベースのワークロードで最も重要なコンポーネントです 。ストレージは常に利用可能であり、拡張性があり、パフォーマンスが高く、一貫性と耐久性が保証されている必要があります。仮想マシンやベアメタルなどの従来の環境に適用されるのと同じ期待と要件は、Kubernetesによって管理されるコンテナのコンテキストでも有効です。

重要

動的にプロビジョニングされるストレージに関しては、Kubernetesには独自の特性があります。これらには、ストレージクラス、永続ボリューム、および*永続ボリューム要求*が含まれます。 VMと物理サーバー上のデータベースワークロードのストレージに関して長年にわたって構築した貴重な知識に加えて、これらの概念を所有する必要があります。

ストレージにアクセスするには、主に2つの方法があります。

  • ネットワーク :直接的または間接的(Kubernetesを実行しているホストにローカルにマウントされたNFSボリュームを考えてください)

  • ローカル :ポッドが実行されているノードに直接接続されています(これには、Kubernetesのベアメタルインストールに直接接続されたディスクも含まれます)

Kubernetesで最も一般的な使用パターンであるネットワークストレージには、従来の環境で発生するのと同じ問題が発生します。これらは、複数のアプリケーションとのI / O競合がパフォーマンス結果の変動性を高める共有環境で強調される可能性があります。

ローカルストレージは、より高い予測可能なパフォーマンスを保証するため、高トランザクションおよびVery Large Database (VLDB)のワークロードにより適したシェアードナッシングアーキテクチャを有効にします。

警告

CloudNativePGでPostgreSQLクラスターをデプロイする前に、使用しているストレージがデータベースワークロードに推奨されていることを確認してください。私たちのアドバイスは、最初に fio などのツールを使用してストレージをベンチマークし、次に pgbench を使用してデータベースをベンチマークすることにより、パフォーマンスの期待値を明確に設定することです。

CloudNativePGのベンチマーク

EDBは、データベースを本番環境にデプロイする前に、制御されたKubernetes環境でCloudNativePGをベンチマークするためのオープンソースのガイドラインとHelmチャートのセットである

cnp-bench を維持します。

簡単に言えば、 cnp-bench は2つのレベルで動作するように設計されています。

  • fio を使用して、基になるストレージのパフォーマンスを測定し、シーケンシャル読み取り、シーケンシャル書き込み、ランダム読み取り、ランダム書き込みなどのデータベースワークロードに関連するメトリック

  • PostgreSQLとともに配布されるデフォルトのベンチマークツールを使用してデータベースのパフォーマンスを測定する:pgbench

重要

ストレージとデータベースの両方のパフォーマンスを測定することは、データベースが実稼働する前に**行う必要があるアクティビティです。ただし、このような結果は、計画段階(容量計画など)だけでなく、生産ライフサイクル、特に緊急事態(この種のテストを実行する余裕がなくなった場合)でも非常に貴重です。データベースは実際に時間の経過とともに変化および進化し、データの分散も同様にパフォーマンスに影響を与える可能性があります。シーケンシャルの読み取りまたは書き込みの理論上の最大スループットを知ることは、これらの状況で非常に役立ちます。特に、外部ワークロードの影響によって結果が変わらないシェアードナッシングのコンテキストでは。 システムを知り、ベンチマークします。

永続ボリュームの要求

オペレーターは、 PGDATA を保存することを目的として、各PostgreSQLインスタンスの永続的ボリュームクレーム(PVC)を作成し、各Podにマウントします。

ストレージクラスを介した設定

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

重要

CloudNativePGは、ストレージクラスに依存しないように設計されています。いつものように、本稼働に移す前に、制御された環境でストレージクラスを適切にベンチマークすることをお勧めします。

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

ボリューム拡張

Kubernetesは、デフォルトで有効になっている expanding PVCs を許可するAPIを公開しますが、基になる StorageClass でサポートする必要があります。

特定のStorageClass がボリューム拡張をサポートしているかどうかを確認するには、ストレージクラスのallowVolumeExpansion フィールドを読み取ります。

$ kubectl get storageclass -o jsonpath={$.allowVolumeExpansion} premium-storage
true

ボリューム拡張Kubernetes機能の使用

ストレージクラスがボリューム拡張をサポートしている場合、 Cluster のサイズ要件を変更できます。オペレーターは変更をすべてのPVCに適用します。

StorageClass が online volume resizing をサポートしている場合、変更はすぐにPodに適用されます。基になるストレージクラスがそれをサポートしていない場合は、ポッドを削除してサイズ変更をトリガーする必要があります。

続行するための最善の方法は、レプリカから始めて、各ポッドがバックアップされるのを待って、一度に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を使用してPodをホストするノードを遮断します。これにより、オペレーターはバックグラウンドのディスクサイズ変更が完了する前にPodを再作成し、すぐにPVCに再接続できません。

最初のステップは、次のように新しいサイズ、たとえば「2Gi」を適用するクラスター定義を編集することです。

apiVersion: postgresql.cnpg.io/v1
kind: Cluster
metadata:
  name: cluster-example
spec:
  instances: 3

  storage:
    storageClass: default
    size: 2Gi

cluster-example-1 Podがクラスターのプライマリであると仮定すると、最初にレプリカを続行できます。たとえば、 cluster-example-3 Podをホストするkubernetesノードの暗号化から始めます。

kubectl cordon <node of cluster-example-3>

次に、 cluster-example-3 Podを削除します。

$ 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>

Podが正しく再作成され、 Running および 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 を使用して、新しいサイズ変更されたPodをスイッチオーバーしてプロモートした後、プライマリインスタンスに関連付けられたディスクのサイズ変更を最後のディスクのままにしてください(例、 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

それが終わったら、オペレーターはサイズを変更した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-v2bfg   0/1     Completed   0          17s
cluster-example-4              1/1     Running     0          10s