Backup on volume snapshots
==========================

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

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

要件
----

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

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

通常、それは :ref:`VolumeSnapshotClass <Storage>` です

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

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

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

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

..  Note::
   :ref:`VolumeSnapshotConfiguration <VolumeSnapshotConfiguration>` を参照してください。

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

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

.. code:: yaml

   apiVersion: postgresql.k8s.enterprisedb.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:`PostgreSQL WALアーカイブ <PostgreSQL WALアーカイブ>` の制御
の両方が含まれています。

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

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

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

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

ホットおよびコールドバックアップ
--------------------------------

デフォルトでは、EDB CloudNativePGクラスターは、
`PostgreSQL defaults of the low-level API for base backups <https://www.postgresql.org/docs/current/continuous-archiving.html#BACKUP-LOWLEVEL-BASE-BACKUP>`_ を使用して、ボリュームスナップショットのオンライン/ホットバックアップを要求します。

- バックアップ手順の開始時に、即時チェックポイントを要求しません

- バックアップ手順を終了するときに、WALアーカイバーがバックアップの最後のセグメントをアーカイブするのを待機します

..  Important::
   デフォルト値は、ほとんどの実稼働環境に適しています。ホットバックアップは一貫性があり、スナップショットリカバリーを実行するために使用できます。バックアップの開始から一時レプリケーションスロットを介してWALの保持を保証します。ただし、そのためにはコールドバックアップに依存することをお勧めします。

``Cluster`` リソースの\ ``.spec.backup.volumeSnapshot``
スタンザの次のオプションを使用して、デフォルトの動作を明示的に変更できます。

- ``online`` ``true`` デフォルトまたは\ ``false`` を値として受け入れます

- ``onlineConfiguration.immediateCheckpoint``
  バックアップ手順を開始する前に、即時チェックポイントを要求するかどうか。技術的には、PostgreSQLの\ ``pg_backup_start``
  /``pg_start_backup()`` ファンクションに渡す\ ``fast``
  引数に対応し、\ ``true`` デフォルトまたは\ ``false`` を受け入れます

- ``onlineConfiguration.waitForArchive``
  アーカイバーがバックアップの最後のセグメントを処理するまで待機するかどうか。技術的には、PostgreSQLの\ ``pg_backup_stop``
  /``pg_stop_backup()`` ファンクションに渡す\ ``wait_for_archive``
  引数に対応し、\ ``true`` デフォルトまたは\ ``false`` を受け入れます

デフォルトでコールドバックアップを取得するようにPostgresクラスターのデフォルト動作を変更する場合、次のようにマニフェストに\ ``online: false``
オプションを追加するだけです。

.. code:: yaml

     # ...
     backup:
       volumeSnapshot:
          online: false
          # ...

代わりに、デフォルトの動作として即時チェックポイントを要求する場合、このセクションを追加できます。

.. code:: yaml

     # ...
     backup:
       volumeSnapshot:
          online: true
          onlineConfiguration:
            immediateCheckpoint: true
          # ...

デフォルト動作のオーバーライド
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

``Backup`` または\ ``ScheduledBackup`` オブジェクトの\ ``online``
および必要に応じて\ ``onlineConfiguration``
に別の値を設定することにより、クラスターリソースで定義されたデフォルトの動作を変更できます。

たとえば、オンデマンドのコールドバックアップを発行する場合、\ ``.spec.online: false``
を使用して\ ``Backup`` オブジェクトを作成できます。

.. code:: yaml

   apiVersion: postgresql.k8s.enterprisedb.io/v1
   kind: Backup
   metadata:
     name: snapshot-cluster-cold-backup-example
   spec:
     cluster:
       name: snapshot-cluster
     method: volumeSnapshot
     online: false

同様に、 ScheduledBackupの場合

.. code:: yaml

   apiVersion: postgresql.k8s.enterprisedb.io/v1
   kind: ScheduledBackup
   metadata:
     name: snapshot-cluster-cold-backup-example
   spec:
     schedule: "0 0 0  **  *"
     backupOwnerReference: self
     cluster:
       name: snapshot-cluster
     method: volumeSnapshot
     online: false

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

デフォルトでは、 EDB
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 <Storage>` を参照してください。

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

例
--

次の例は、 ``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アーカイブを保存する\ ``Cluster``
を作成します :ref:`AWS S3 <AWS S3>` を参照してください。

.. code:: yaml

   apiVersion: postgresql.k8s.enterprisedb.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.k8s.enterprisedb.io/v1
   kind: ScheduledBackup
   metadata:
     name: hendrix-vs-backup
   spec:
     cluster:
       name: hendrix
     method: volumeSnapshot
     schedule: 0 0 0  **  *
     backupOwnerReference: cluster
     immediate: true

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