EKS上のステートフルアプリケーションをまるごとバックアップ・リストアしてみた【④リストア&クローニング篇】

# はじめに
[前回の記事](https://qiita.com/yshimizu22/items/9e021dabc7db3c30a07b)ではEKS上にデプロイしたWordPressアプリケーションに対して、Astra Control Service(以下、ACS)の**スナップショット**ならびに**バックアップ**の機能をお試ししてみました。

今回はその際のバックアップデータを**リストア**していきます。
また、ACSにはバックアップを経由せずにアプリケーションを直接複製できる**クローニング**という機能もありますので併せて検証していきたいと思います。

- [Astra Control Service(ACS)の導入](https://qiita.com/yshimizu22/items/11967a351e3b1ddde00f)
- Astra Control Service(ACS)の使い方
    1. [アプリケーションの登録](https://qiita.com/yshimizu22/items/5b6a77a652b3a0b0ec22)
    1. [アプリケーションのスナップショット&バックアップ](https://qiita.com/yshimizu22/items/9e021dabc7db3c30a07b)
    1. **アプリケーションのリストア&クローニング ←イマココ**

# 前回までのおさらい
検証環境全体の構成図はこちら
![スクリーンショット 2022-10-14 11.04.25.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/436161/0771a474-5592-9398-5a01-82856bb5d04b.png)

バックアップしたアプリケーションはこんな感じのWordPressアプリケーション
![スクリーンショット 2022-10-13 13.14.01.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/436161/003a32e4-ae9e-64a5-c2e9-82b0bb9f1070.png)


# リストアしてみた
前回記事でACSにおけるスナップショットとバックアップの違いをお伝えしましたが、リストアにおいては各バックアップ方式で以下の機能差があります。

| 比較項目 | スナップショット | バックアップ |
|:----:|:-------------:|:-------------:|
| リストア先 | 同一k8sクラスタ内の別のnamespace | 同一k8sクラスタ内の別のnamespace<br>または<br>別のk8sクラスタ
| PV削除時の復旧可否 | 不可 | 可 |

## 下準備
リストアを行う前に、ACSでは**アプリケーションの構成**と**PVのデータ**の両方を一気通貫にバックアップできるという触れ込みなのでその辺りをきちんと確かめられる様に下準備を行なっていきます。

まずはPVのデータの復旧を確認できるように、あらかじめバックアップ元のブログ記事を削除しておきます。

頑張って書いたブログが消えて更地になってしまいました。
![スクリーンショット 2022-10-13 13.59.29.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/436161/3a5df6e9-0f6b-8241-fa75-d697a6ff81ae.png)

次にアプリケーションの構成をめちゃくちゃにします。
外部からのアクセスを受け付けるフロントエンドを担うpodをdeploymentごと削除します。

```sh
# 現在のリソース状況を確認
$ kubectl get all -n prod
NAME                                        READY   STATUS    RESTARTS      AGE
pod/my-release-mariadb-0                    1/1     Running   0             26h
pod/my-release-wordpress-6799967cb5-vgmng   1/1     Running   1 (26h ago)   26h

NAME                           TYPE           CLUSTER-IP       EXTERNAL-IP                                                                   PORT(S)                      AGE
service/my-release-mariadb     ClusterIP      10.100.47.177    <none>                                                                        3306/TCP                     26h
service/my-release-wordpress   LoadBalancer   10.100.128.152   a11be8760d14344e08c46c69949df1ce-743688330.ap-northeast-1.elb.amazonaws.com   80:32552/TCP,443:30615/TCP   26h

NAME                                   READY   UP-TO-DATE   AVAILABLE   AGE
deployment.apps/my-release-wordpress   1/1     1            1           26h

NAME                                              DESIRED   CURRENT   READY   AGE
replicaset.apps/my-release-wordpress-6799967cb5   1         1         1       26h

NAME                                  READY   AGE
statefulset.apps/my-release-mariadb   1/1     26h

# フロントエンドのdeployment削除
$ kubectl delete deployment.apps/my-release-wordpress -n prod
deployment.apps "my-release-wordpress" deleted
```

サイトへのアクセスすらできなくなりました。
![スクリーンショット 2022-10-13 14.08.21.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/436161/515f5e68-961a-b819-ceed-d101ee7bb0b3.png)

これでせっかくのブログサイトが完全崩壊です。

## スナップショットからのリストア
まずはスナップショットからの復旧を試してみます。
ACSにログイン後、**Applications** -> **対象のアプリケーション** -> **Actions** -> **Restore**と操作しウィザードを開きます。
![スクリーンショット 2022-10-13 16.06.52.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/436161/f401eab7-6d81-ca32-c89a-0de2841693e5.png)

ウィザード上でリストアするスナップショットを指定します。
- Destination cluster: リストア先のクラスタ(スナップショットの場合はバックアップ元のk8sクラスタのみ)
- Destination namespace: バックアップ元のnamespaceを指定 or リストア先として新規に作成するnamespaceの名前を入力
    - 今回はバックアップ元のnamespaceを指定しました
- Restore source: リストアするスナップショットを選択
![スクリーンショット 2022-10-13 15.11.27.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/436161/a90e0ef9-221d-007c-144d-77a9895149e8.png)

最終確認画面で"restore"と入力して、リストア処理を開始します。
ちなみに画面上部の警告に関しては「スナップショットをリストアすると、リストア対象のリソースはスナップショット取得時点のものに全て置き換えられるから、リストア前にスナップショットかバックアップを取得することをオススメするよ」という趣旨の事が書いてあります。今回は気にせず先に進みます。
![スクリーンショット 2022-10-13 15.15.12.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/436161/3adccf77-af57-8730-8125-39b44fa9f72d.png)

アプリの**State**が**Restoring**から**Helthy**に遷移したらリストア完了です。
![スクリーンショット 2022-10-13 15.30.58.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/436161/b15be4ee-df3a-133a-c2f3-1ae8f5a3f86e.png)

一応k8sのリソース状況も確認しておきます。

```sh
$ kubectl get all -n prod
NAME                                        READY   STATUS    RESTARTS   AGE
pod/my-release-mariadb-0                    1/1     Running   0          73s
pod/my-release-wordpress-6799967cb5-qskct   1/1     Running   0          80s

NAME                           TYPE           CLUSTER-IP      EXTERNAL-IP                                                                    PORT(S)                      AGE
service/my-release-mariadb     ClusterIP      10.100.78.146   <none>                                                                         3306/TCP                     79s
service/my-release-wordpress   LoadBalancer   10.100.61.201   acc1e4f5473d9455db80b94d5acb6500-1133067306.ap-northeast-1.elb.amazonaws.com   80:32083/TCP,443:31477/TCP   77s

NAME                                   READY   UP-TO-DATE   AVAILABLE   AGE
deployment.apps/my-release-wordpress   1/1     1            1           80s

NAME                                              DESIRED   CURRENT   READY   AGE
replicaset.apps/my-release-wordpress-6799967cb5   1         1         1       80s

NAME                                  READY   AGE
statefulset.apps/my-release-mariadb   1/1     78s

$ kubectl get pvc -n prod
NAME                        STATUS   VOLUME                                     CAPACITY   ACCESS MODES   STORAGECLASS   AGE
data-my-release-mariadb-0   Bound    pvc-4c2ea6b2-1f97-42fd-b342-3100db04907c   8Gi        RWO            fsx-nfs        11m
my-release-wordpress        Bound    pvc-2bc478fc-9bea-4374-bc18-506810c579aa   10Gi       RWO            fsx-nfs        11m
```
事前に削除したフロントエンドを担うDeploymentが復活しています。
また削除していないものも含め全てのリソースのAGEが若返ってることからも先ほど警告文に記載のあった仕様が伺えます。
全リソースの再作成となると**リストアにかかる時間は初期デプロイ時とほぼ同じになるはず**で、対象のアプリケーションに依存しそうですね（今回は10分程度かかりました）

では、リストアされたブログサイトにアクセスしてみます。
上記の通り、外部からのアクセスを受け付けるtypeがLoadBalancerのServiceも再作成されているため**URL(ServiceのFQDN)が変わっていることに注意。**

![スクリーンショット 2022-10-13 15.51.08.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/436161/c584255b-cebc-1a98-b8cc-4909d4084f11.png)

無事、ウチの猫に再開することができました。

## バックアップからのリストア
復旧したてで気の毒ではありますが、もう一度[下準備](#下準備)の項でやった様にブログサイトを崩壊させます。
またスナップショットとの差別化要素として、今度は**バックアップ元のPVも削除**してからリストアしてみたいと思います。
```sh
# Deployment削除
$ kubectl delete deployment.apps/my-release-wordpress -n prod
deployment.apps "my-release-wordpress" deleted

# PVC削除
$ kubectl get pvc -n prod -l app.kubernetes.io/instance=my-release
NAME                        STATUS   VOLUME                                     CAPACITY   ACCESS MODES   STORAGECLASS   AGE
data-my-release-mariadb-0   Bound    pvc-4c2ea6b2-1f97-42fd-b342-3100db04907c   8Gi        RWO            fsx-nfs        15m
my-release-wordpress        Bound    pvc-2bc478fc-9bea-4374-bc18-506810c579aa   10Gi       RWO            fsx-nfs        15m

$ kubectl delete pvc -n prod -l app.kubernetes.io/instance=my-release
persistentvolumeclaim "data-my-release-mariadb-0" deleted
persistentvolumeclaim "my-release-wordpress" deleted

$ kubectl get pvc -n prod
No resources found in prod namespace.
```

それではバックアップからのリストアを行います。
先ほど同様、**Applications** -> **対象のアプリケーション** -> **Actions** -> **Restore**と操作しウィザードを開きます。
![スクリーンショット 2022-10-13 16.06.52.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/436161/f401eab7-6d81-ca32-c89a-0de2841693e5.png)

**Restore source**のセクションで**Backups**のタブを選択する以外は、スナップショットからのリストア操作と全く同じです。
![スクリーンショット 2022-10-13 16.09.20.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/436161/fe7bafb6-908e-5abe-d7a0-0f51e3361b77.png)

今回もブログを復旧させることができました。
![スクリーンショット 2022-10-13 15.51.08.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/436161/c584255b-cebc-1a98-b8cc-4909d4084f11.png)

バックアップ機能に関しては別クラスタへのリストアもできるので、**k8sクラスタごと壊れちゃったという場合でもなんとかなりそう。**
そのほかにもアプリの開発段階で**ステージング用クラスタから本番クラスタにアプリを移行**するなんて使い方もできそうですね。

# クローニングしてみた
最後にアプリケーションの**クローニング機能**にも触れてみたいと思います。
クローニング機能では稼働中のアプリケーションを直接別のクラスタやnamespaceに複製します。
本番環境で稼働中のアプリに何か不具合が見つかったので検証環境にクローニングしてそこで調査してみる、みたいなユースケースで使えそう。

**Applications** -> **対象のアプリケーション** -> **Actions** -> **Clone**と操作しウィザードを開きます。
![スクリーンショット 2022-10-13 16.06.52.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/436161/f401eab7-6d81-ca32-c89a-0de2841693e5.png)

クローニング先の情報を入力します。
- Clone name: 複製したアプリケーションのACS上の管理名
    - 複製したアプリケーションは自動でACSの管理下に置かれます
- Clone namespace: クローン先として新規に作成するnamespaceの名前
- Destination cluster: クローン先のk8sクラスタ
- Clone from an existing snapshot or backup: 稼働中のアプリではなく過去に取得したスナップショットまたはバックアップをもとに複製を行うオプション
    - スナップショット/バックアップからの複製の方が処理時間が短いとのこと 

![スクリーンショット 2022-10-13 16.22.08.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/436161/65e6a60c-bd70-8ee9-3978-802747dd0a9b.png)

最終確認画面で**Clone**をクリックするとアプリの複製処理が開始します。
![スクリーンショット 2022-10-13 16.26.31.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/436161/feb63056-49d4-74eb-6d30-3b8095cd264b.png)

上がクローンされたアプリケーションで、下がオリジナルです。
保護ポリシーは引き継がれないので複製先のアプリもバックアップする必要がある場合は個別に設定が必要です。
![スクリーンショット 2022-10-13 16.29.57.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/436161/0e818885-1c00-e559-6009-1b62ff7c8652.png)


# まとめ
今回はACSのリストアならびにクローニングの機能を検証してみました。
これで**全4回に渡るACSの検証シリーズは一旦おわり**となります。
全体を通しての所感は、総じてACSがウリにしている部分はその通りだったかなと思います。
- UIの操作が簡単(ほぼドキュメント読まずに直感で操作できた)
- アプリの構成とPVのデータをまとめてバックアップ・リストアできるのはやっぱり助かる

一方で個人的に気になった部分としては、ACSオンプレのk8sも管理できるようにしてほしい(オンプレ版の**Astra Control Center**と連携や統合できるようにしてほしい)という点でしょうか。
上記の様な要望は実際既に開発元にフィードバックがあったらしく、エンハンスの検討は行われている様です。今後に期待。

今後に関してはマルチクラウドにおける検証(AWS + Azure等)、今回触れなかった機能(execution hook, Astra API, Python SDKなど)、オンプレ版の**Astra Control Center**などなど、機会があればそちらも同じ様に検証してシェアできればいいなと思っています。
ここまでお読みいただいてありがとうございました。