ROSAでEBSを利用する際のバックアップ・リストア戦略

# 概要
[前回記事](https://qiita.com/naras/items/c598c2187cb47602a2de)ではROSAでEFSを利用する際のバックアップ・リストアについてご紹介しましたが、本記事ではEBSを利用する際のバックアップ・リストアの選択肢とそれぞれの考慮点についてご紹介します。

# ROSAでのEBSの使われ方
## EBSはデフォルトのPVとして利用される
EBSを利用するために必要なEBS CSI DriverはROSAにデフォルトで導入されており、PVを作成するデフォルト設定はEBSが使うようになっています。そのため、EFSのように利用者自身がCSI Driver Operatorを導入する必要はありません。

> To create CSI-provisioned PVs that mount to AWS EBS storage assets, Red Hat OpenShift Service on AWS installs the AWS EBS CSI Driver Operator (a Red Hat operator) and the AWS EBS CSI driver by default in the openshift-cluster-csi-drivers namespace.

https://docs.openshift.com/rosa/storage/container_storage_interface/persistent-storage-csi-ebs.html

## EBSが存在するAvailability Zoneには注意が必要
ROSAは複数AZにそれぞれノードを作成し、AZ障害時には別AZのノードでPodを起動することでAZ障害に対して対応することが出来ます。
一方、EBSはAZ単位でリソースが作成され別のAZからそのリソースを利用することが出来ません。これによりEBSをPVとして利用するPodはEBSが存在するAZに縛られることになるため、AZ障害に対する耐性を失うことになります。


# バックアップ・リストア
## バックアップ・リストア方式の選択肢
ROSAクラスタとしてEBSのバックアップ・リストアを考えたとき、利用できる選択肢はOADPとAWS Backupの2種類が存在します。
以降の内容でそれぞれの詳細に触れていきますが、早見表としてそれぞれについて簡単に取りまとめます。

| 項目 | OADP | AWS Backup |
| --- | --- | --- |
| 導入 | Operatorを利用<br>ROSAクラスタ内にnamespaceや各種リソースの作成が必要 | ROSAクラスタの操作は不要<br>AWS側でバックアップボールトやバックアッププランの作成が必要 |
| バックアップ | Kubernetesリソースの作成により実行<br>namespace単位でバックアップされ、PVのデータ以外も取得 | AWS Backupより実行<br>EBSのスナップショットとして取得 |
| リストア | namespace単位でリストア<br>PV単位でのリストアは不可 | EBSとしてリストア<br>PV/PVCの再作成が必要 | 
| 実行状況監視 | CloudWatch Logsに出力されるログを監視が可能 | EventBridgeによるイベント監視が可能 |



### OADP(OpenShift API for Data Protection)
#### 概要
OADP(OpenShift API for Data Protection)はRed Hatから提供されているバックアップツール/サービスであり、Kubernetesクラスタのリソースのバックアップ・リストアに利用出来るOSSであるVeleroをベースとしています。  
OADPはEFSに対応していないことからEFSのBackupでは利用出来ませんでしたが、EBSには対応していることからバックアップツールの候補として利用出来ます。

#### 導入
OADPはOperatorの形で導入することが出来ます。  
詳細な手順はRed Hatのドキュメントをご確認ください。

https://docs.openshift.com/rosa/cloud_experts_tutorials/cloud-experts-deploy-api-data-protection.html

#### バックアップ方式の選択
OADPを利用してバックアップ(スナップショット)を取得する方法は2種類あります。  
どちらのパターンを利用する場合もyamlファイルの特定箇所を編集する必要がありますので注意してください。

##### ①EBSのスナップショット機能を利用してバックアップを取得する
バックアップの取得についてEBSのスナップショット機能を利用する場合、以下のように設定します。  
> If you use your cloud provider’s native snapshot API to back up persistent volumes, you must specify the cloud provider as the snapshot location.

→ cloud provider's native snapshot = EBSのスナップショット機能を利用する場合、`snapshot location`にcloud providet = awsを指定します。  

https://docs.openshift.com/container-platform/4.13/backup_and_restore/application_backup_and_restore/installing/installing-oadp-aws.html

具体的には以下の部分です。(yamlファイルは上記リンクの`DataProtectionApplication`のサンプルより引用)
```
apiVersion: oadp.openshift.io/v1alpha1
kind: DataProtectionApplication
metadata:
  name: <dpa_sample>
  namespace: openshift-adp
spec:
...
  backupLocations:
    - name: default
      velero:
        provider: aws
        default: true
        objectStorage:
          bucket: <bucket_name>
          prefix: <prefix>
        config:
          region: us-east-1
          profile: "backupStorage"
        credential:
          key: cloud
          name: cloud-credentials
  snapshotLocations:
    - velero:
        provider: aws　←←←　ココ！！
        config:
          region: us-west-2
          profile: "volumeSnapshot"
```
なお、veleroでバックアップされる範囲にはPV以外も含まれますので(Kubernetesとしてのマニフェストファイル等)、これらのデータは同yamlで指定するS3バケットに格納されます。


##### ②CSIスナップショットを利用してバックアップを取得する
CSIのスナップショットを利用してバックアップを取得する場合は、①の`snapshot location`の設定は不要です。その代わりとして、今度は`velero.defaultPlugins:`に`csi`を追加する必要があります。

```
apiVersion: oadp.openshift.io/v1alpha1
kind: DataProtectionApplication
...
spec:
  configuration:
    velero:
      defaultPlugins:
      - openshift
      - csi ←←← ココ！！
```
CSIスナップショットの場合はPV・PV以外のデータどちらも指定したS3バケットに格納されます。

#### バックアップ実行
バックアップを実行するには`Backup`もしくは`Schedule`というCRを作成します。
これはnative snapshot・CSI snapshotのどちらのバックアップ方式を利用する場合も同様です。  

**OADPでバックアップを取得する場合、namespace単位でバックアップを取得します。**

単発でバックアップを取得する場合は`Backup`というCRを作成します。
```
apiVersion: velero.io/v1
kind: Backup
metadata:
 name: hello-world
 namespace: openshift-adp
spec:
 includedNamespaces:
 - hello-world
 storageLocation: ${CLUSTER_NAME}-dpa-1
 ttl: 720h0m0s
```
スケジュールでバックアップを行いたい場合は、`Backup`ではなく`Schedule`というCRを作成する必要があります。

```
apiVersion: velero.io/v1
kind: Schedule
metadata:
  name: <schedule>
  namespace: openshift-adp
spec:
  schedule: 0 7 * * * 
  template:
    hooks: {}
    includedNamespaces:
    - <namespace> 
    storageLocation: <velero-sample-1> 
    defaultVolumesToFsBackup: true 
    ttl: 720h0m0s
```

https://docs.openshift.com/container-platform/4.14/backup_and_restore/application_backup_and_restore/backing_up_and_restoring/oadp-scheduling-backups-doc.html

`Backup`による単発でのバックアップ・`Schedule`によるスケジュールでのバックアップ、どちらとも作成されるリソースの情報を確認することでバックアップの実行状況を確認出来ます。  
```
oc get backup -n openshift-adp <backup> -o jsonpath='{.status.phase}'
oc get schedule -n openshift-adp <schedule> -o jsonpath='{.status.phase}'
```

#### リストア
リストアを行いたい場合は`Restore`というCRを作成します。  
そして、OADPのバックアップ・リストアに関して最も重要な点ですが、**リストアはnamespace単位で行われるので、事前にnamespaceを削除しておく必要があります*。**  
また、PVのみリストアするということも出来ないため、リストアを行いたい場合はnamespaceから全てを再作成することになります。
```
apiVersion: velero.io/v1
kind: Restore
metadata:
  name: <restore>
  namespace: openshift-adp
spec:
  backupName: <backup>
  restorePVs: true 
```

＊ 以下のVeleroのドキュメントに記載の通り、リストアするリソースが既に存在するリソースと同名の場合はskipする仕様となっています。ポリシーを変更する(`--existing-resource-policy=update`)ことで上書きすることも出来ますが、PV/PVCを上書きすることは出来ません。
> Update of a resource only applies to the Kubernetes resource data such as its spec. It may not work as expected for certain resource types such as PVCs and Pods. In case of PVCs for example, data in the PV is not restored or overwritten in any way.

https://velero.io/docs/main/restore-reference/

#### 実行状況監視
OADPのバックアップ実行ログはOpenShiftのインフラログとして記録されます。ROSAの場合、インフラログはCloudWatch Logsに転送されますので、このLog Groupを監視することでバックアップの実行状況/成否を監視することが出来ます。


### AWS Backup
#### 概要
AWS BackupはAWSにより提供されるバックアップ管理サービスです。様々なAWSサービスのバックアップに対応しており、当然EBSのバックアップもAWS Backupにより取得できます。  
AWS側でのバックアップであることから、リストア時はAWS側のリストア操作に加えてOpenShift(Kubernetes)側のリソースの再作成を別途行う必要があります。

#### 導入
AWS Backupを用いてEBSをバックアップする方法についてはAWS公式ドキュメントをご確認ください。
以下のドキュメントはEBS特有の手順ではありませんが、バックアップ対象のリソースタイプとしてEBSを選択することでEC2単位(AMI)ではなくEBS単位でのバックアップが可能です。

https://docs.aws.amazon.com/aws-backup/latest/devguide/create-on-demand-backup.html

#### バックアップ実行
単発のバックアップであればオンデマンドバックアップの作成から、定期的なバックアップであればバックアッププランでスケジュール設定を行うことで、バックアップを取得することが出来ます。  
**当然ながら、AWS Backupを利用する際のバックアップ単位はEBS毎です。**

#### リストア
EBS自体のリストアについてはAWS Backupの機能で行うことが出来ます。  
**バックアップ同様、リストアもEBSのリソース単位で行います。**
AWS側のリストアとは別に、OpenShift(Kubernetes)としてのリソースの再作成、具体的にはPV/PVCの再作成を行う必要がありますが、この設定はEFSの場合と基本的には同様であるため、[前回記事](https://qiita.com/naras/items/c598c2187cb47602a2de)をご参照ください。

ただし、EFSと異なりEBSはAZ単位のリソースであるため、NodeSelectorによるAZ指定が必要です。Depoyment(もしくはDeploymentConfig)の`spec.template.spec.containers`に以下のように`nodeSelector`の設定を追加するようにしてください。
```
      nodeSelector:                                         
        topology.ebs.csi.aws.com/zone: <ap-northeast-1x> 
```


#### 実行状況監視
AWS Backupの実行状況についてはEventBridgeで実行ステータスを取得することで監視を行うことが出来ます。"COMPLETED"・"FAILED"以外にも複数のステータスが存在するため、適切なステータスを監視するようにしましょう。

https://docs.aws.amazon.com/aws-backup/latest/devguide/eventbridge.html

# まとめ
本記事ではROSAでEBSをPVとして利用する際のバックアップ・リストアツールとしてOADP・AWS Backupをご紹介しました。OADPはKubernetesのマニフェストも含めてバックアップとして取得出来る点で優れていますが、リストア単位がnamespaceというのが通常運用では少し扱いづらいように感じます。
前回記事で紹介したEFSとEBSをPVとして両採用するような環境であれば、統一性という観点でもAWS Backupをバックアップ・リストアツールとして活用するのが望ましいのではないかと思います。
本記事が何らかの参考になりましたら幸いです。