ボリュームスナップショットのバックアップ
========================================

..  Important::
   CloudNativePGのボリュームスナップショットの現在の実装は、 :ref:`cold backup <バックアップ>` のみをサポートしています。 `PostgreSQL's low level API for base backups <https://www.postgresql.org/docs/current/continuous-archiving.html#BACKUP-LOWLEVEL-BASE-BACKUP>`_ の直接サポートを使用したホットバックアップ

バージョン1.22で追加される予定です。そうは言っても、現在の実装は、デフォルトで、プライマリに影響を与えることなく最も調整されたスタンバイで動作するため、運用HA環境に適しています。

..  Warning::
   :ref:`backup document <バックアップ>` で述べたように、プライマリをターゲットとするように明示的に設定されたコールドスナップショットは、バックアップ中にプライマリがフェンスされ、その間クラスターは読み取り専用になります。

..  Warning::
   ボリュームスナップショットバックアップには、ターゲットインスタンスのフェンシングが必要です。安全のため、フェンスされたインスタンスが既に含まれているクラスターでは、コールドスナップショットは拒否されます。

CloudNativePGは、完全に宣言的な方法で、バックアップとリカバリー操作の両方にKubernetesネイティブボリュームスナップショットAPIを直接利用するデータベースオペレーターの最初の既知のケースの1つです。

標準のボリュームスナップショットについて
----------------------------------------

ボリュームスナップショットは `Kubernetes 1.12 (2018) as alpha <https://kubernetes.io/blog/2018/10/09/introducing-volume-snapshot-alpha-for-kubernetes/>`_  で最初に導入され、
 `beta in 1.17 (2019) <https://kubernetes.io/blog/2019/12/09/kubernetes-1-17-feature-cis-volume-snapshot-beta/>`_  および `moved to GA in 1.20 (2020) <https://kubernetes.io/blog/2020/12/10/kubernetes-1.20-volume-snapshot-moves-to-ga/>`_ 
に昇格しました。安定して広く利用可能な標準になり、3つのカスタムリソース定義\ ``VolumeSnapshot``
、\ ``VolumeSnapshotContent`` 、\ ``VolumeSnapshotClass`` を提供します。

このKubernetes機能は、次の汎用インターフェイスを定義します。

-  PVCから始まる新しいボリュームスナップショットの作成

-  既存のスナップショットの削除

-  スナップショットからの新しいボリュームの作成

Kubernetesは、実際の実装を基になるCSIドライバーに委任しますそれらのすべてがボリュームスナップショットをサポートしているわけではありません。通常、ボリュームスナップショットを提供するストレージクラスは、
**アプリケーションの透過的な方法でのインクリメンタルおよび差分ブロックレベルのバックアップ**
をサポートします。これにより、スナップショットのクラスター間の可用性を含む、スタックの複雑さと独立した管理を委任できます。

要件
----

ボリュームスナップショットがCloudNativePGクラスターで動作するには、PostgreSQLボリュームつまり
``storage`` および\ ``walStorage``
セクションの動的プロビジョニングに使用される各ストレージクラスがボリュームスナップショットをサポートしていることを確認する必要があります。

手順はストレージクラスごとに異なるため、Kubernetesシステムに展開した特定のストレージクラスと関連するCSIドライバーのドキュメントを参照してください。

通常、それは :ref:`VolumeSnapshotClass <ストレージ>` です

特定のストレージクラスの永続ボリュームからスナップショットを取得し、\ ``VolumeSnapshot``
および\ ``VolumeSnapshotContent``
リソースとして管理できることを保証します。

..  Important::
   ボリュームスナップショットがサポートされていることをサードパーティベンダーに確認するのはあなたの責任です。 CloudNativePGは、この問題に関してKubernetes APIとのみ対話し、特定のCSIドライバーごとにストレージレベルでの問題をサポートすることはできません。

ボリュームスナップショットバックアップを構成する方法
----------------------------------------------------

CloudNativePGでは、 ``backup.volumeSnapshot``
スタンザを介したボリュームスナップショットバックアップ用に特定のPostgresクラスターを構成できます。

..  Note::
   :ref:`VolumeSnapshotConfiguration {postgresql-cnpg-io-v1- VolumeSnapshotConfiguration} <VolumeSnapshotConfiguration {postgresql-cnpg-io-v1- VolumeSnapshotConfiguration}>` を参照してください。

オプションの完全なリストについては、APIリファレンスを参照してください。

ボリュームスナップショットを使用した一般的な例PGDATAとWALが同じストレージクラスを共有すると仮定した場合、次のとおりです。

.. code:: yaml

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

     storage:
       storageClass: @STORAGE_CLASS@
       size: 10Gi
     walStorage:
       storageClass: @STORAGE_CLASS@
       size: 10Gi

     backup:
       # Volume snapshot backups
       volumeSnapshot:
          className: @VOLUME_SNAPSHOT_CLASS_NAME@
       # WAL archive
       barmanObjectStore:
          # ...

ご覧のとおり、 ``backup`` セクションには、 ``volumeSnapshot``
スタンザボリュームスナップショットの物理ベースバックアップの制御と
``barmanObjectStore`` スタンザ :ref:`WALアーカイブ <WALアーカイブ>` の制御
の両方が含まれています。

..  Note::
   `barmanObjectStore` を定義すると、ボリュームスナップショットとオブジェクトストアのバックアップ戦略の両方を同時に使用して物理的バックアップを取得することができます。

``volumeSnapshot.className``
オプションを使用すると、PostgreSQLクラスターで定義したすべてのストレージボリュームに使用されるデフォルトの\ ``VolumeSnapshotClass``
オブジェクトを参照できます。

..  Note::
   `PGDATA` およびWALファイルに別のストレージクラスを使用している場合、 `walClassName` オプションデフォルトで`className` と同じ値を介してそのボリュームに別個の`VolumeSnapshotClass` を指定できます。

ボリュームスナップショットバックアップ用にクラスターを定義したら、このようなバックアップを定期的に要求する\ ``ScheduledBackup``
リソースを定義する必要があります。

ボリュームスナップショットオブジェクトの永続化
----------------------------------------------

デフォルトでは、 CloudNativePGによって作成された\ ``VolumeSnapshot``
オブジェクトは、それらを生成した\ ``Backup``
オブジェクトまたはそれらが参照する\ ``Cluster``
を削除した後も保持されます。このような動作は、次の値を受け入れる\ ``.spec.backup.volumeSnapshot.snapshotOwnerReference``
オプションによって制御されます。

-  ``none`` 所有権が設定されていません。\ ``Backup``
   および/または\ ``Cluster``
   リソースが削除された後も\ ``VolumeSnapshot``
   オブジェクトが持続することを意味します

-  ``backup`` ``VolumeSnapshot``
   オブジェクトは、それを生成した\ ``Backup``
   リソースが所有しており、バックアップオブジェクトが削除されると、ボリュームスナップショットも削除されます

-  ``cluster`` ``VolumeSnapshot``
   オブジェクトは、バックアップされた\ ``Cluster``
   リソースが所有しており、Postgresクラスターが削除されると、ボリュームスナップショットも削除されます

``VolumeSnapshot`` が削除される場合、 ``VolumeSnapshotContent``
で指定された\ ``deletionPolicy`` が評価されます。

-  ``Retain`` に設定されている場合、\ ``VolumeSnapshotContent``
   オブジェクトは保持されます

-  ``Delete`` に設定されている場合、\ ``VolumeSnapshotContent``
   オブジェクトも削除されます

..  Warning::
   `VolumeSnapshotContent` オブジェクトは、バックアップと参照するクラスターに関するすべての情報を保持していません `VolumeSnapshot` オブジェクトに含まれる注釈やラベルなど。可能ですが、この種のオブジェクトのみからの復元は簡単ではない場合があります。このため、Kubernetesレベルのデータ保護ソリューションを使用する場合でも、常に`VolumeSnapshot` 定義をバックアップすることをお勧めします。

``VolumeSnapshotContent`` の値は、対応する\ ``VolumeSnapshotClass``
定義で設定された\ ``deletionPolicy`` によって決定されます。これは、
``.spec.backup.volumeSnapshot.className`` オプションで参照されます。

 :ref:`Kubernetes documentation on Volume Snapshot Classes <ストレージ>` を参照してください。

この標準の動作の詳細については、

例
--

次の例は、 ``ebs-sc`` ストレージクラスと\ ``csi-aws-vsc``
ボリュームスナップショットクラスを使用して、AWSのEKSクラスターでボリュームスナップショットベースバックアップを構成する方法を示しています。

..  Important::
   例のテストに興味がある場合は、ストレージクラスとスナップショットクラスのインストールプロセスの詳細な手順については `Volume Snapshots <https://github.com/kubernetes-sigs/aws-ebs-csi-driver/tree/master/examples/kubernetes/snapshot>`_ を読んでください。

次のマニフェストは、ボリュームスナップショットに使用する準備ができ、サービスアカウントIRSAのIAMロールを介してS3バケットにWALアーカイブを保存するを作成します
 :ref:`AWS S3 <AWS S3>` を参照してください。

.. code:: yaml

   apiVersion: postgresql.cnpg.io/v1
   kind: Cluster
   metadata:
     name: hendrix
   spec:
     instances: 3

     storage:
       storageClass: ebs-sc
       size: 10Gi
     walStorage:
       storageClass: ebs-sc
       size: 10Gi

     backup:
       volumeSnapshot:
          className: csi-aws-vsc
       barmanObjectStore:
         destinationPath: s3://@BUCKET_NAME@/
         s3Credentials:
           inheritFromIAMRole: true
         wal:
           compression: gzip
           maxParallel: 2

     serviceAccountTemplate:
       metadata:
         annotations:
           eks.amazonaws.com/role-arn: "@ARN@"
   - --
   apiVersion: postgresql.cnpg.io/v1
   kind: ScheduledBackup
   metadata:
     name: hendrix-vs-backup
   spec:
     cluster:
       name: hendrix
     method: volumeSnapshot
     schedule: 0 0 0  **  *
     backupOwnerReference: cluster
     immediate: true

最後のリソースは、深夜に毎日のボリュームスナップショットバックアップを定義し、クラスターが作成された直後に1つを要求します。
